root/trunk/fcode-utils-devel/localvalues/LocalValuesSupport.fth

Revision 102, 5.0 KB (checked in by stepan, 3 years ago)

localvalues support, contributed by David Paktor <dlpaktor@…>

Line 
1\       (C) Copyright 2005 IBM Corporation.  All Rights Reserved.
2\       Licensed under the Common Public License (CPL) version 1.0
3\       for full details see:
4\            http://www.opensource.org/licenses/cpl1.0.php
5\
6\       Module Author:  David L. Paktor    dlpaktor@us.ibm.com
7
8\  The support routines for Local Values in FCode.
9
10\  Function imported
11\       _local-storage-size_    \  Size, in cells, of backing store for locals
12\       \  A constant.  If not supplied, default value of d# 64 will be used.
13\
14\  Functions exported:
15\       {push-locals}  ( #ilocals #ulocals -- )
16\       {pop-locals}   ( #locals -- )
17\       _{local}       ( local-var# -- addr )
18\
19\  Additional overloaded function:
20\      catch            \  Restore Locals after a  throw
21
22\  The user is responsible for declaring the maximum depth of the
23\      run-time Locals stack, in storage units, by defining the
24\      constant  _local-storage-size_  before floading this file.
25\  The definition may be created either by defining it as a constant
26\      in the startup-file that FLOADs this and other files in the
27\      source program, or via a command-line user-symbol definition
28\      of a form resembling:   -d '_local-storage-size_=d# 42'
29\      (be sure to enclose it within quotes so that the shell treats
30\      it as a single string, and, of course, replace the "42" with
31\      the actual number you need...)
32\  If both forms are present, the command-line user-symbol value will
33\      be used to create a duplicate definition of the named constant,
34\      which will prevail over the earlier definition, and will remain
35\      available for examination during development and testing.  The
36\      duplicate-name warning, which will not be suppressed, will also
37\      act to alert the developer of this condition.
38\  To measure the actual usage (in a test run), use the separate tool
39\      found in the file  LocalValuesDevelSupport.fth .
40\  If the user omits defining  _local-storage-size_  the following
41\      ten-line sequence will supply a default:
42
43[ifdef] _local-storage-size_
44    f[  [defined] _local-storage-size_   true  ]f
45[else]
46    [ifexist] _local-storage-size_
47        f[  false  ]f
48    [else]
49        f[  d# 64   true  ]f
50    [then]
51[then]          ( Compile-time:  size true | false )
52[if]   fliteral  constant  _local-storage-size_    [then]
53
54_local-storage-size_    \  The number of storage units to allocate
55  cells                 \    Convert to address units
56  dup                   \    Keep a copy around...
57 ( n )  instance buffer: locals-storage     \  Use one of the copies
58
59\  The Locals Pointer, added to the base address of  locals-storage
60\      points to the base-address of the currently active set of Locals.
61\      Locals will be accessed as a positive offset from there.
62\  Start the Locals Pointer at end of the buffer.
63\  A copy of ( N ), the number of address units that were allocated
64\      for the buffer, is still on the stack.  Use it here.
65 ( n )  instance value locals-pointer
66   
67\  Support for  {push-locals}
68
69\  Error-check.
70: not-enough-locals? ( #ilocals #ulocals -- error? )
71   + cells locals-pointer swap - 0<
72;
73
74\  Error message.
75: .not-enough-locals ( -- )
76    cr ." FATAL ERROR:  Local Values Usage exceeds allocation." cr
77;
78
79\  Detect, announce and handle error.
80: check-enough-locals ( #ilocals #ulocals -- | <ABORT> )
81    not-enough-locals? if
82        .not-enough-locals
83        abort
84    then
85;
86
87\  The uninitialized locals can be allocated in a single batch
88: push-uninitted-locals ( #ulocals -- )
89    cells locals-pointer swap - to locals-pointer
90;
91
92\  The Initialized locals are initted from the items on top of the stack
93\      at the start of the routine.  If we allocate them one at a time,
94\      we get them into the right order.  I.e., the last-one named gets
95\      the top item, the earlier ones get successively lower items.
96: push-one-initted-local ( pstack-item -- )
97    locals-pointer 1 cells -
98    dup to locals-pointer
99    locals-storage  + !
100;
101
102\  Push all the Initialized locals.
103: push-initted-locals ( N_#ilocals-1 ... N_0 #ilocals -- )
104    0 ?do push-one-initted-local loop
105;
106
107: {push-locals}  ( N_#ilocals ... N_1 #ilocals #ulocals -- )
108    2dup check-enough-locals
109    push-uninitted-locals               ( ..... #i )
110    push-initted-locals                 (  )
111;
112
113\  Pop all the locals.
114\  The param is the number to pop.
115: {pop-locals} ( total#locals -- )
116    cells locals-pointer + to locals-pointer
117;
118
119\  The address from/to which values will be moved, given the local-var#
120: _{local} ( local-var# -- addr )
121    cells locals-pointer + locals-storage  +
122;
123
124\  We need to overload  catch  such that the state of the Locals Pointer
125\  will be preserved and restored after a  throw .
126overload  : catch ( ??? xt -- ???' false | ???'' throw-code )
127    locals-pointer >r   ( ???  xt )                       ( R: old-locals-ptr )
128    catch               ( ???' false | ???'' throw-code ) ( R: old-locals-ptr )
129    \  No need to inspect the throw-code.
130    \  If  catch  returned a zero, the Locals Pointer
131    \  is valid anyway, so restoring it is harmless.
132    r>  to locals-pointer
133;
Note: See TracBrowser for help on using the browser.