|
|
1.1 root 1: #include "../h/config.h"
2:
3: /*
4: * efail - handles the failure of an expression. efail is used
5: * by a number of routines. Its task to resume the newest
6: * inactive generator in the current expression frame. If
7: * no such generator exists, the expression frame is exited
8: * and execution continues at the point indicated in the
9: * expression marker. If the marker has a 0 address for
10: * the point to continue at, efail is called to fail again.
11: */
12:
13: Global(_interp) /* interpreter loop */
14: Global(_atrace) /* trace generator reactivations */
15: Global(_boundary) /* Icon/C boundary address */
16: Global(_line) /* current line number */
17: Global(_file) /* current file name */
18: Global(_k_level) /* value of &level */
19: Global(_k_trace) /* value of &trace */
20:
21: Global(_efail)
22: /*
23: * Note that efail is jumped to.
24: */
25: #ifdef VAX
26: _efail:
27: tstl gfp # gfp points to the most recent generator
28: # frame. If it's 0, there is no inactive
29: jeql nogen # generator in this expression frame and
30: # the frame is exited.
31:
32: /*
33: * There is an inactive generator in this expression frame. It
34: * must be reactivated.
35: */
36: movl (gfp),_boundary # Restore boundary address from that
37: # stored in the generator frame.
38: movl fp,r0 # Save fp value for testing later.
39: # The fp must be restored. gfp points
40: movl gfp,fp # at the word before the former top
41: tstl (fp)+ # of stack. The fp is loaded from
42: # gfp and then incremented by 4.
43: /*
44: * Trace resumption if &trace is set and if generator is an Icon procedure.
45: */
46: tstl _k_trace # If &trace is 0,
47: jeql tracedone # no tracing.
48: cmpl _boundary,fp # If the boundary is not the same as the
49: jneq tracedone # fp, the generator is not an Icon procedure.
50: movl 12(fp),efp # Point efp at saved fp in generator frame.
51: # If efp is the same as the fp was upon
52: cmpl efp,r0 # entry to efail, then generator is
53: jeql tracedone # control regime
54: #
55: # Otherwise, an Icon procedure is to be
56: # resumed. atrace handles the tracing,
57: # and takes the address of the procedure
58: # block as it's only argument. arg0 is
59: # is the descriptor for the block. It is
60: # located using:
61: # &arg0 = (ap + 8 + 8*nargs)
62: movl 8(fp),r4 # r4 = old ap
63: ashl $3,4(r4),r2 # r2 = nargs * 8
64: addl2 r4,r2 # ... + old ap
65: addl2 $8,r2 # ... + 8
66: pushl 4(r2) # r2 points to descriptor, push address
67: # residing in second word.
68: calls $1,_atrace # atrace(&arg0)
69: /*
70: * Resume the generator.
71: */
72: tracedone:
73: movl -(gfp),_k_level # Restore &level
74: movl -(gfp),_line # Restore _line and
75: movl -(gfp),_file # _file from the generator frame.
76:
77: cmpl _boundary,fp # If the boundary is the same as the
78: bneq f3 # fp, the return if from Icon to C
79: clrl _boundary # and the boundary is cleared.
80: f3:
81: ret # All set, return. This return
82: # will sweep off the generator frame
83: # on the top of the stack and resume
84: # execution after point where the
85: # suspension that created this generator
86: # was performed.
87:
88: /*
89: * There are no inactive generators in the expression frame, thus
90: * the expression fails. If the failure label in the expression
91: * frame marker is not 0, execution resumes at the indicated address.
92: * Otherwise, failure in the surrounding expression is signaled by
93: * looping back to efail.
94: */
95: nogen:
96: movl -8(efp),ipc # Point ipc at failure label from expression
97: # frame. Note that this is always a
98: # ucode address.
99: movl -4(efp),gfp # Restore old generator frame pointer from
100: # expression frame marker.
101: movl efp,sp # Move sp back to point at expression frame
102: # marker.
103: movl (sp)+,efp # Restore old expression frame pointer and
104: # move sp up to previous word. Moving
105: # the sp up effectively removes the
106: # expression marker from the stack.
107: tstl ipc # If the failure label in the expression
108: # frame is 0, this expression fails
109: jeql _efail # by branching back to efail.
110: jmp _interp # Otherwise, execution continues. (at
111: # address in ipc)
112:
113: #endif VAX
114:
115: #ifdef PORT
116: DummyFcn(_efail)
117: #endif PORT
118:
119: #ifdef PDP11
120: / efail - reactivate newest inactive generator within current
121: / expression frame. If there are none, exit the expression
122: / frame and take the failure branch (stored in the expression
123: / frame marker).
124: Global(cret)
125: _efail:
126: tst r3 / test for inactive generators,
127: beq 1f / branch if none
128:
129: / Reactivate newest inactive generator.
130:
131: mov (r3),_boundary / restore Icon/C boundary address
132: mov r5,r0 / save procedure frame pointer
133: mov r3,r5 / restore procedure frame pointer
134: add $8.,r5
135:
136: / Trace reactivation if &trace is set and if generator is an Icon procedure.
137:
138: tst _k_trace
139: beq 2f
140: cmp _boundary,r5 / if boundary == r5, then
141: bne 2f / generator is an Icon procedure
142: mov (r5),r4 / r4 <- address of procedure frame
143: cmp r4,r0 / if hidden procedure frame is same as current,
144: beq 2f / then generator is control regime
145: mov 4(r4),r2 / r2 <- nargs * 4
146: asl r2
147: asl r2
148: add r4,r2 / push address of procedure block,
149: mov 8.(r2),-(sp) / which is pointer field of arg0
150: jsr pc,_atrace
151:
152: / Restore &level, line number, and file name, and return to generator.
153:
154: 2:
155: mov -(r3),_k_level
156: mov -(r3),_line
157: mov -(r3),_file
158: jmp cret
159:
160: / Exit expression frame and signal failure again.
161:
162: 1:
163: mov -4(r4),r2 / get failure label
164: mov -2(r4),r3 / exit current expression frame
165: mov r4,sp
166: mov (sp)+,r4
167: tst r2 / is failure label zero?
168: beq _efail / yes, pass failure to outer expression
169: jmp _interp / no, resume interpreting at failure label
170:
171: #endif PDP11
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.