1
2
3
4
5
6 attempt_thunk:
7 procedure (P_encoded_value, P_blockp, P_stackp, P_refp, P_code) returns (fixed bin (35));
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 declare P_encoded_value fixed bin (35) parameter;
36 declare P_blockp pointer parameter;
37 declare P_stackp pointer parameter;
38 declare P_refp pointer parameter;
39 declare P_code fixed bin (35) parameter;
40
41 declare refp pointer;
42 declare blockp pointer;
43 declare value fixed bin (35);
44
45 declare 1 ev aligned like encoded_value;
46
47 declare thunk_entry variable entry (pointer, fixed bin (35));
48 declare 1 entry_template aligned,
49 2 location pointer,
50 2 stack_frame pointer;
51
52 declare thunk_ptr pointer;
53 declare thunk_lth fixed bin;
54 declare thunk (thunk_lth) bit (36) aligned based (thunk_ptr);
55
56 declare (addr, binary, hbound, null, pointer) builtin;
57
58
59
60 refp = P_refp;
61 sp = P_stackp;
62 blockp = P_blockp;
63 unspec (ev) = unspec (P_encoded_value);
64
65
66
67
68 if (binary (ev.code, 4) ^= 8) then call punt (1);
69
70
71
72
73 if (sp ^= null ()) then do;
74 thunk_ptr = pointer (sp -> stack_frame.entry_ptr, ev.n3);
75 entry_template.location = thunk_ptr;
76 entry_template.stack_frame = sp;
77 unspec (thunk_entry) = unspec (entry_template);
78
79 call thunk_entry (refp, value);
80
81 P_code = 0;
82 return (value);
83 end;
84
85
86
87
88
89 if (blockp = null ()) then call punt (2);
90
91 thunk_ptr = pointer (blockp, ev.n3);
92 entry_template.location = thunk_ptr;
93 entry_template.stack_frame = baseptr (""b);
94 unspec (thunk_entry) = unspec (entry_template);
95
96 call find_thunk_bounds ();
97
98 call check_thunk_code ();
99
100 call thunk_entry (refp, value);
101
102 P_code = 0;
103 return (value);
104
105
106
107 find_thunk_bounds:
108 procedure ();
109
110 declare idx fixed bin;
111
112
113
114
115
116
117
118
119
120
121
122
123 thunk_lth = 5;
124 if (substr (thunk (1), 19, 18) ^= "727007"b3) then call punt (3);
125 if (thunk (2) ^= "700034352120"b3) then call punt (3);
126 if (thunk (3) ^= "201047272100"b3) then call punt (3);
127 if (thunk (4) ^= "000002000000"b3) then call punt (3);
128 if (thunk (5) ^= "000000000000"b3) then call punt (3);
129
130 thunk_ptr = addrel (thunk_ptr, 5);
131 thunk_lth = 200;
132
133
134
135
136
137
138 do idx = 1 to hbound (thunk, 1);
139 if (thunk (idx) = "000631710100"b3) then do;
140 thunk_lth = idx - 1;
141 return;
142 end;
143 end;
144
145 call punt (4);
146
147 end find_thunk_bounds;
148
149
150
151 check_thunk_code:
152 procedure ();
153
154 declare idx fixed bin;
155 declare jdx fixed bin;
156 declare opcode bit (12) aligned;
157 declare TRANSFERS (24) bit (12) aligned internal static options (constant) init
158 ("7100"b3 ,
159 "6050"b3 ,
160 "6040"b3 ,
161 "6054"b3 ,
162 "6000"b3 ,
163 "6010"b3 ,
164 "6070"b3 ,
165 "6064"b3 ,
166 "7000"b3 ,
167 "7010"b3 ,
168 "7020"b3 ,
169 "7030"b3 ,
170 "7040"b3 ,
171 "7050"b3 ,
172 "7060"b3 ,
173 "7070"b3 ,
174 "2700"b3 ,
175 "2710"b3 ,
176 "2720"b3 ,
177 "2730"b3 ,
178 "6700"b3 ,
179 "6710"b3 ,
180 "6720"b3 ,
181 "6730"b3 );
182
183 declare 1 inst aligned,
184 2 offset fixed bin (18) unsigned unaligned,
185 2 opcode bit (10) unaligned,
186 2 pad bit (2) unaligned,
187 2 pr_flag bit (1) unaligned,
188 2 tag bit (6) unaligned;
189 declare 1 pr_inst aligned,
190 2 pr_no fixed bin (3) unsigned unaligned,
191 2 offset fixed bin (14) unaligned,
192 2 opcode bit (10) unaligned,
193 2 pad bit (2) unaligned,
194 2 pr_flag bit (1) unaligned,
195 2 tag bit (6) unaligned;
196
197
198
199
200
201
202
203 do idx = 1 to thunk_lth;
204 unspec (inst) = thunk (idx);
205 unspec (pr_inst) = thunk (idx);
206
207
208
209 Note
210
211
212 if inst.pr_flag then
213 if (pr_inst.pr_no = 6) then
214 if (pr_inst.offset < 64) then
215 if (pr_inst.offset ^= 26) then
216 call punt (5);
217
218
219
220 opcode = inst.opcode || "00"b;
221 do jdx = 1 to hbound (TRANSFERS, 1);
222 if (opcode = TRANSFERS (jdx)) then call punt (6);
223 end;
224 end;
225
226 return;
227 end check_thunk_code;
228
229
230
231 PUNT:
232 return (0);
233
234
235
236 punt:
237 procedure (why);
238
239 declare why fixed bin (35) parameter;
240
241 P_code = why;
242 goto PUNT;
243
244 end punt;
245
246 %page; %include runtime_symbol;
247 %page; %include stack_frame;
248
249 end attempt_thunk;