|
|
1.1 root 1: #include "../h/config.h"
2:
3: /*
4: * esusp - suspends a value from an expression. A generator frame
5: * hiding the current expression frame is created. The surrounding
6: * expression frame is duplicated and the value being suspended
7: * is copied to the top of the stack. The generator frame that
8: * is created uses efail as a return point, thus if an alternative
9: * is needed, efail will return to itself via the generator frame
10: * and then resume execution at the failure label specified in
11: * the expression marker.
12: *
13: * The value being suspended appears as an argument.
14: */
15:
16: Global(_efail) /* signal failure in an expression */
17: Global(_boundary) /* Icon/C boundary address */
18: Global(_line) /* current line number */
19: Global(_file) /* current file name */
20: Global(_k_level) /* value of &level */
21:
22: Global(_esusp)
23:
24: #ifdef VAX
25: _esusp:
26: /*
27: * Construct the generator frame.
28: */
29: Mask STDSV # Partially create new generator frame
30: movl fp,_boundary # Set the boundary
31: pushl fp # Push boundary as part of generator frame
32: movl sp,gfp # The generator frame pointer points at
33: # the word containing the boundary.
34: pushl _k_level # Save &level,
35: pushl _line # line number,
36: pushl _file # and file name in generator frame,
37: # completing the frame.
38: /*
39: * Determine region to be copied.
40: */
41: addl3 $4,efp,r0 # Point r0 at first word above the
42: # expression frame marker. This
43: # word is the lower end of the region
44: # that will be copied.
45:
46: # If the saved gfp is non-zero, the
47: # generator frame marker serves as the
48: # upper bound of the expression frame.
49: # If it is zero, the expression frame
50: # marker pointed at by the saved
51: # efp is the upper bound of the frame
52: # to be copied.
53: # Note that the marker itself is not
54: # copied, the region only extends to
55: # the marker and not through it.
56: movl -4(efp),r2 # Get gfp from expression marker.
57: jneq f1 # If it is zero,
58: subl3 $8,(efp),r2 # use saved efp - 8.
59: jmp f2
60: f1: # gfp is not zero,
61: subl2 $12,r2 # use gfp - 12.
62: /*
63: * Copy surrounding expression frame.
64: */
65: # r0 points to the lowest word to be copied
66: # and r2 points to high end of the region.
67: # The word that r2 points at is part of
68: # a generator or expression frame marker
69: # is not copied.
70: f2: subl2 r0,r2 # Calculate length in bytes of region and
71: # put it in r2.
72: subl2 r2,sp # Move stack pointer down to accommodate
73: # copied region.
74: movc3 r2,(r0),(sp) # Copy the region by moving r2 bytes from
75: # the address pointed at by r2 to the
76: # address pointed at by the stack pointer.
77:
78: movq 8(ap),-(sp) # Copy the value being suspended to
79: # the top of the stack.
80: /*
81: * Fix things up for return.
82: */
83: movl 16(fp),r1 # Get the saved pc (the return point for
84: # esusp) out of the frame and save it in r1.
85: movl $_efail,16(fp) # Replace saved pc with efail so that when
86: # a return using the generator frame is
87: # performed, it will go to efail.
88: movl 8(fp),ap # Restore ap
89: movl 12(fp),fp # and fp.
90: clrl _boundary # Clear the boundary since control is
91: # going back into Icon code.
92: movl (efp),efp # Point efp at bounding expression frame
93: # marker.
94: jmp (r1) # Return by branching back to desired
95: # return point. The suspended value is
96: # on the top of the stack, gfp points
97: # at the newly constructed generator
98: # frame.
99: #endif VAX
100:
101: #ifdef PORT
102: DummyFcn(_esusp)
103: #endif PORT
104:
105: #ifdef PDP11
106: / esusp - Suspend from an expression.
107: / Duplicates the most recent generator frame outside the
108: / current expression frame. Esusp does not return directly.
109: / The expression is reactivated when an alternative is needed;
110: / the return actually comes from efail.
111:
112: / Register usage:
113: / r0: pointer to top of stack region to be copied,
114: / which is just above the procedure descriptor (arg0) of the
115: / suspending procedure
116: / r2: old generator frame pointer, indexed down to r0 during copy
117: / r3: new generator frame pointer
118: / r4: suspending expression frame pointer
119: / r5: current procedure frame pointer
120: _esusp:
121: mov r5,-(sp) / create new procedure frame
122: mov sp,r5
123: mov r4,-(sp) / save registers
124: mov r3,-(sp)
125: mov r2,-(sp)
126: mov r5,-(sp) / create Icon/C boundary
127: mov r5,_boundary
128:
129: / Calculate addresses of new generator frame.
130:
131: mov sp,r3 / r3 <- pointer to new generator frame
132: mov _k_level,-(sp) / save &level
133: mov _line,-(sp) / save current line number
134: mov _file,-(sp) / and file name
135: mov r4,r0 / r0 <- pointer to top of region to be copied
136: tst (r0)+ / (= r4 + 2)
137: mov -2(r4),r2 / r2 <- generator frame pointer from caller
138: bne 1f / use saved gfp - 6 if non-zero,
139: mov (r4),r2 / else use saved efp - 4
140: cmp -(r2),-(r2)
141: br 2f
142: 1:
143: sub $6,r2
144: br 2f
145:
146: / Copy surrounding expression frame.
147:
148: 1:
149: mov -(r2),-(sp)
150: 2:
151: cmp r2,r0 / stop at end of frame
152: bhi 1b
153:
154: / Copy value of suspending expression.
155:
156: mov 8.(r5),-(sp) / push return value
157: mov 6(r5),-(sp)
158:
159: / Return to code; reactivation will go directly to efail.
160:
161: mov 2(r5),r1 / r1 <- return pc
162: mov $_efail,2(r5) / fix reactivation pc to propagate failure
163: mov -6(r5),r2
164: mov (r5),r5 / restore old registers,
165: mov (r4),r4 / and exit suspending expression frame
166: clr _boundary / returning to Icon code
167: jmp (r1) / this really suspends
168: #endif PDP11
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.