2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "PyrKernel.h"
22 #include "PyrParseNode.h"
23 #include "PyrSymbol.h"
26 void numBlockTemps(PyrBlock
*block
, long level
, long *numArgNames
, long *numVarNames
);
27 void numBlockTemps(PyrBlock
*block
, long level
, long *numArgNames
, long *numVarNames
)
30 for (i
=0; i
<level
; ++i
) {
31 block
= slotRawBlock(&block
->contextDef
);
33 *numArgNames
= slotRawSymbolArray(&block
->argNames
) ? slotRawSymbolArray(&block
->argNames
)->size
: 0;
34 *numVarNames
= slotRawSymbolArray(&block
->varNames
) ? slotRawSymbolArray(&block
->varNames
)->size
: 0;
37 unsigned char* dumpOneByteCode(PyrBlock
*theBlock
, PyrClass
* theClass
, unsigned char *ip
);
38 unsigned char* dumpOneByteCode(PyrBlock
*theBlock
, PyrClass
* theClass
, unsigned char *ip
)
45 long op1
, op2
, op3
, op4
, op5
;
46 long i
, n
, ival
, jmplen
;
47 long numArgNames
, numVarNames
, numTemps
;
50 if (theClass
== NULL
) {
54 //dumpObject((PyrObject*)block);
55 //post("block->classptr %d class_method %d %d\n",
56 // block->classptr, class_method, isKindOf((PyrObject*)block, class_method));
57 //if (block->classptr == class_method) {
58 if (isKindOf((PyrObject
*)block
, class_method
)) {
59 theClass
= slotRawClass(&((PyrMethod
*)block
)->ownerclass
);
62 block
= slotRawBlock(&block
->contextDef
);
64 if (theClass
== NULL
) {
65 theClass
= s_interpreter
->u
.classobj
;
66 //error("dumpByteCodes: no Class found.\n");
70 ipbeg
= slotRawInt8Array(&theBlock
->code
)->b
;
73 post("%3d %02X", n
, op1
);
75 case 0 : // push class
76 op2
= *ip
++; // get literal index
77 post(" %02X PushClassX '%s'\n", op2
,
78 slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
])->name
);
80 case 1 : // Extended, PushInstVar
81 op2
= *ip
++; // get inst var index
82 post(" %02X PushInstVarX '%s'\n", op2
,
83 slotRawSymbolArray(&theClass
->instVarNames
)->symbols
[op2
]->name
);
85 case 2 : // Extended, PushTempVar
86 op2
= *ip
++; // get temp var level
89 for (i
=op2
; i
--; block
= slotRawBlock(&block
->contextDef
)) { /* noop */ }
90 numArgNames
= slotRawSymbolArray(&block
->argNames
) ? slotRawSymbolArray(&block
->argNames
)->size
: 0;
91 numVarNames
= slotRawSymbolArray(&block
->varNames
) ? slotRawSymbolArray(&block
->varNames
)->size
: 0;
92 numTemps
= numArgNames
+ numVarNames
;
94 op3
= numTemps
- *ip
++ - 1; // get temp var index
95 if (op3
< numArgNames
) {
96 post(" %02X %02X PushTempVarX '%s'\n", op2
, op3
,
97 slotRawSymbolArray(&block
->argNames
)->symbols
[op3
]->name
);
99 post(" %02X %02X PushTempVarX '%s'\n", op2
, op3
,
100 slotRawSymbolArray(&block
->varNames
)->symbols
[op3
-numArgNames
]->name
);
103 case 3 : // Extended, PushTempZeroVar
106 numArgNames
= slotRawSymbolArray(&block
->argNames
) ? slotRawSymbolArray(&block
->argNames
)->size
: 0;
107 numVarNames
= slotRawSymbolArray(&block
->varNames
) ? slotRawSymbolArray(&block
->varNames
)->size
: 0;
108 numTemps
= numArgNames
+ numVarNames
;
110 op2
= numTemps
- *ip
++ - 1; // get temp var index
111 if (op2
< numArgNames
) {
112 post(" %02X PushTempZeroVarX '%s'\n", op2
,
113 slotRawSymbolArray(&theBlock
->argNames
)->symbols
[op2
]->name
);
115 post(" %02X PushTempZeroVarX '%s'\n", op2
,
116 slotRawSymbolArray(&theBlock
->varNames
)->symbols
[op2
-numArgNames
]->name
);
119 case 4 : // Extended, PushLiteral
120 op2
= *ip
++; // get literal index
121 // push a block if it is one
122 slot
= slotRawObject(&theBlock
->selectors
)->slots
+ op2
;
123 slotString(slot
, str
);
124 post(" %02X PushLiteralX %s\n", op2
, str
);
126 case 5 : // Extended, PushClassVar
127 op2
= *ip
++; // get class var literal index
128 op3
= *ip
++; // get class var index
129 post(" %02X %02X PushClassVarX\n", op2
, op3
);
131 case 6 : // Extended, PushSpecialValue == push a special class
132 op2
= *ip
++; // get class name index
133 classobj
= gSpecialClasses
[op2
]->u
.classobj
;
134 post(" %02X PushSpecialClass '%s'\n", op2
,
135 slotRawSymbol(&classobj
->name
)->name
);
137 case 7 : // Extended, StoreInstVar
138 op2
= *ip
++; // get inst var index
139 post(" %02X StoreInstVarX '%s'\n", op2
,
140 slotRawSymbolArray(&theClass
->instVarNames
)->symbols
[op2
]->name
);
142 case 8 : // Extended, StoreTempVar
143 op2
= *ip
++; // get temp var level
146 for (i
=op2
; i
--; block
= slotRawBlock(&block
->contextDef
)) { /* noop */ }
147 numArgNames
= slotRawSymbolArray(&block
->argNames
) ? slotRawSymbolArray(&block
->argNames
)->size
: 0;
148 numVarNames
= slotRawSymbolArray(&block
->varNames
) ? slotRawSymbolArray(&block
->varNames
)->size
: 0;
149 numTemps
= numArgNames
+ numVarNames
;
151 op3
= *ip
++; // get temp var index
152 if (op3
< numArgNames
) {
153 post(" %02X %02X StoreTempVarX '%s'\n", op2
, op3
,
154 slotRawSymbolArray(&block
->argNames
)->symbols
[op3
]->name
);
156 post(" %02X %02X StoreTempVarX '%s'\n", op2
, op3
,
157 slotRawSymbolArray(&block
->varNames
)->symbols
[op3
-numArgNames
]->name
);
160 case 9 : // Extended, StoreClassVar
161 op2
= *ip
++; // get class var literal index
162 op3
= *ip
++; // get class var index
163 post(" %02X %02X StoreClassVarX\n", op2
, op3
);
165 case 10 : // Extended, SendMsg
166 op2
= *ip
++; // get num args
167 op3
= *ip
++; // get num key args
168 op4
= *ip
++; // get selector index
169 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op4
]);
170 post(" %02X %02X %02X SendMsgX '%s'\n", op2
, op3
, op4
, selector
->name
);
172 case 11 : // Extended, SuperMsg
173 op2
= *ip
++; // get num args
174 op3
= *ip
++; // get num key args
175 op4
= *ip
++; // get selector index
176 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op4
]);
177 post(" %02X %02X %02X SuperMsgX '%s'\n", op2
, op3
, op4
, selector
->name
);
179 case 12 : // Extended, SendSpecialMsg
180 op2
= *ip
++; // get num args
181 op3
= *ip
++; // get num key args
182 op4
= *ip
++; // get selector index
183 post(" %02X %02X %02X SendSpecialMsgX '%s'\n", op2
, op3
, op4
,
184 gSpecialSelectors
[op4
]->name
);
186 case 13 : // Extended, SendSpecialUnaryArithMsg
187 op2
= *ip
++; // get selector index
188 post(" %02X SendSpecialUnaryArithMsgX '%s'\n", op2
,
189 gSpecialUnarySelectors
[op2
]->name
);
191 case 14 : // Extended, SendSpecialBinaryArithMsg
192 op2
= *ip
++; // get selector index
193 post(" %02X SendSpecialBinaryArithMsgX '%s'\n", op2
,
194 gSpecialBinarySelectors
[op2
]->name
);
196 case 15 : // Extended, SpecialOpcode (none yet)
197 op2
= *ip
++; // get extended special opcode
199 case opgProcess
: // push thisProcess
200 post(" %02X opgProcess\n", op1
, op2
); break;
201 case opgThread
: // push thisThread
202 post(" %02X opgThread\n", op1
, op2
); break;
203 case opgMethod
: // push thisMethod
204 post(" %02X opgMethod\n", op1
, op2
); break;
205 case opgFunctionDef
: // push thisBlock
206 post(" %02X opgFunctionDef\n", op1
, op2
); break;
207 case opgFunction
: // push thisClosure
208 post(" %02X opgFunction\n", op1
, op2
); break;
212 // PushInstVar, 0..15
213 case 16 : case 17 : case 18 : case 19 :
214 case 20 : case 21 : case 22 : case 23 :
215 case 24 : case 25 : case 26 : case 27 :
216 case 28 : case 29 : case 30 : case 31 :
217 post(" PushInstVar '%s'\n",
218 slotRawSymbolArray(&theClass
->instVarNames
)->symbols
[op1
&15]->name
);
224 jmplen
= (op2
<<8) | op3
;
225 post(" %02X %02X JumpIfTrue %d (%d)\n", op2
, op3
, jmplen
, n
+ jmplen
+ 3);
228 case 33 : case 34 : case 35 :
229 case 36 : case 37 : case 38 : case 39 :
230 op2
= op1
& 15; // get temp var level
233 for (i
=op2
; i
--; block
= slotRawBlock(&block
->contextDef
)) { /* noop */ }
234 numArgNames
= slotRawSymbolArray(&block
->argNames
) ? slotRawSymbolArray(&block
->argNames
)->size
: 0;
235 numVarNames
= slotRawSymbolArray(&block
->varNames
) ? slotRawSymbolArray(&block
->varNames
)->size
: 0;
236 numTemps
= numArgNames
+ numVarNames
;
238 op3
= numTemps
- *ip
++ - 1; // get temp var index
239 if (op3
>= 0 && op3
< numArgNames
) {
240 post(" %02X PushTempVar '%s'\n", op3
,
241 slotRawSymbolArray(&block
->argNames
)->symbols
[op3
]->name
);
242 } else if (op3
>= 0) {
243 post(" %02X PushTempVar '%s'\n", op3
,
244 slotRawSymbolArray(&block
->varNames
)->symbols
[op3
-numArgNames
]->name
);
251 slot
= slotRawObject(&theBlock
->constants
)->slots
+ ival
;
252 slotString(slot
, str
);
253 post(" %02X PushConstant %s\n", op5
, str
);
259 ival
= (op4
<< 8) | op5
;
260 slot
= slotRawObject(&theBlock
->constants
)->slots
+ ival
;
261 slotString(slot
, str
);
262 post(" %02X %02X PushConstant %s\n", op4
, op5
, str
);
269 ival
= (op3
<< 16) | (op4
<< 8) | op5
;
270 slot
= slotRawObject(&theBlock
->constants
)->slots
+ ival
;
271 slotString(slot
, str
);
272 post(" %02X %02X %02X PushConstant %s\n", op3
, op4
, op5
, str
);
280 ival
= (op2
<< 24) | (op3
<< 16) | (op4
<< 8) | op5
;
281 slot
= slotRawObject(&theBlock
->constants
)->slots
+ ival
;
282 slotString(slot
, str
);
283 post(" %02X %02X %02X %02X PushConstant %s\n", op2
, op3
, op4
, op5
, str
);
288 ival
= (int32
)(op5
<< 24) >> 24;
289 post(" %02X PushInt %d\n", op5
, ival
);
295 ival
= (int32
)((op4
<< 24) | (op5
<< 16)) >> 16;
296 post(" %02X %02X PushInt %d\n", op4
, op5
, ival
);
303 ival
= (int32
)((op3
<< 24) | (op4
<< 16) | (op5
<< 8)) >> 8;
304 post(" %02X %02X %02X PushInt %d\n", op3
, op4
, op5
, ival
);
312 ival
= (int32
)((op2
<< 24) | (op3
<< 16) | (op4
<< 8) | op5
);
313 post(" %02X %02X %02X %02X PushInt %d\n", op2
, op3
, op4
, op5
, ival
);
316 case 48 : case 49 : case 50 : case 51 :
317 case 52 : case 53 : case 54 : case 55 :
318 case 56 : case 57 : case 58 : case 59 :
319 case 60 : case 61 : case 62 : case 63 :
320 op2
= op1
& 15; // get temp var index
323 numArgNames
= slotRawSymbolArray(&block
->argNames
) ? slotRawSymbolArray(&block
->argNames
)->size
: 0;
324 numVarNames
= slotRawSymbolArray(&block
->varNames
) ? slotRawSymbolArray(&block
->varNames
)->size
: 0;
325 numTemps
= numArgNames
+ numVarNames
;
327 if (op2
< numArgNames
) {
328 post(" PushTempZeroVar '%s'\n",
329 slotRawSymbolArray(&theBlock
->argNames
)->symbols
[op2
]->name
);
331 post(" PushTempZeroVar '%s'\n",
332 slotRawSymbolArray(&theBlock
->varNames
)->symbols
[op2
-numArgNames
]->name
);
336 case 64 : case 65 : case 66 : case 67 :
337 case 68 : case 69 : case 70 : case 71 :
338 case 72 : case 73 : case 74 : case 75 :
339 case 76 : case 77 : case 78 : case 79 :
340 op2
= op1
& 15; // get temp var level
341 slot
= slotRawObject(&theBlock
->constants
)->slots
+ op2
;
342 slotString(slot
, str
);
343 post(" PushLiteral %s\n", str
);
347 case 80 : case 81 : case 82 : case 83 :
348 case 84 : case 85 : case 86 : case 87 :
349 case 88 : case 89 : case 90 : case 91 :
350 case 92 : case 93 : case 94 : case 95 :
352 op3
= *ip
++; // get class var index
353 post(" %02X %02X PushClassVar\n", op2
, op3
);
357 case 96 : post(" PushSpecialValue this\n"); break;
358 case 97 : post(" PushOneAndSubtract\n"); break;
359 case 98 : post(" PushSpecialValue -1\n"); break;
360 case 99 : post(" PushSpecialValue 0\n"); break;
361 case 100 : post(" PushSpecialValue 1\n"); break;
362 case 101 : post(" PushSpecialValue 2\n"); break;
363 case 102 : post(" PushSpecialValue 0.5\n"); break;
364 case 103 : post(" PushSpecialValue -1.0\n"); break;
365 case 104 : post(" PushSpecialValue 0.0\n"); break;
366 case 105 : post(" PushSpecialValue 1.0\n"); break;
367 case 106 : post(" PushSpecialValue 2.0\n"); break;
368 case 107 : post(" PushOneAndAdd\n"); break;
369 case 108 : post(" PushSpecialValue true\n"); break;
370 case 109 : post(" PushSpecialValue false\n"); break;
371 case 110 : post(" PushSpecialValue nil\n"); break;
372 case 111 : post(" PushSpecialValue 'end'\n"); break;
374 // StoreInstVar, 0..15
375 case 112 : case 113 : case 114 : case 115 :
376 case 116 : case 117 : case 118 : case 119 :
377 case 120 : case 121 : case 122 : case 123 :
378 case 124 : case 125 : case 126 : case 127 :
379 post(" StoreInstVar '%s'\n",
380 slotRawSymbolArray(&theClass
->instVarNames
)->symbols
[op1
& 15]->name
);
384 case 128 : case 129 : case 130 : case 131 :
385 case 132 : case 133 : case 134 : case 135 :
386 op2
= op1
& 15; // get temp var level
389 for (i
=op2
; i
--; block
= slotRawBlock(&block
->contextDef
)) { /* noop */ }
390 numArgNames
= slotRawSymbolArray(&block
->argNames
) ? slotRawSymbolArray(&block
->argNames
)->size
: 0;
391 numVarNames
= slotRawSymbolArray(&block
->varNames
) ? slotRawSymbolArray(&block
->varNames
)->size
: 0;
392 numTemps
= numArgNames
+ numVarNames
;
394 op3
= *ip
++; // get temp var index
395 if (op3
< numArgNames
) {
396 post(" %02X StoreTempVar '%s'\n", op3
,
397 slotRawSymbolArray(&block
->argNames
)->symbols
[op3
]->name
);
399 post(" %02X StoreTempVar '%s'\n", op3
,
400 slotRawSymbolArray(&block
->varNames
)->symbols
[op3
-numArgNames
]->name
);
404 op2
= *ip
++; // get inst var index
405 op3
= *ip
++; // get selector index
406 selector
= gSpecialSelectors
[op3
];
407 post(" %02X %02X PushInstVarAndSendSpecialMsg '%s' '%s'\n", op2
, op3
,
408 slotRawSymbolArray(&theClass
->instVarNames
)->symbols
[op2
]->name
, selector
->name
);
411 op2
= *ip
++; // get selector index
412 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
]);
413 post(" %02X PushAllArgs+SendMsg '%s'\n",
414 op2
, selector
->name
);
417 op2
= *ip
++; // get selector index
418 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
]);
419 post(" %02X PushAllButFirstArg+SendMsg '%s'\n",
420 op2
, selector
->name
);
423 op2
= *ip
++; // get selector index
424 selector
= gSpecialSelectors
[op2
];
425 post(" %02X PushAllArgs+SendSpecialMsg '%s'\n",
426 op2
, selector
->name
);
429 op2
= *ip
++; // get selector index
430 selector
= gSpecialSelectors
[op2
];
431 post(" %02X PushAllButFirstArg+SendSpecialMsg '%s'\n",
432 op2
, selector
->name
);
435 op2
= *ip
++; // get selector index
436 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
]);
437 post(" %02X PushAllButFirstTwoArgs+SendMsg '%s'\n",
438 op2
, selector
->name
);
441 op2
= *ip
++; // get selector index
442 selector
= gSpecialSelectors
[op2
];
443 post(" %02X PushAllButFirstTwoArgs+SendSpecialMsg '%s'\n",
444 op2
, selector
->name
);
447 op2
= *ip
++; // get loop opcode
448 if (op2
< 23 || op2
> 27) {
449 post(" %02X ControlOpcode\n", op2
); break;
453 jmplen
= ((op3
& 0xFF)<<8) | (op4
& 0xFF);
454 post(" %02X %02X %02X ControlOpcode %d (%d)\n", op2
, op3
, op4
, jmplen
, n
+ jmplen
+ 3); break;
459 case 144 : case 145 : case 146 : case 147 :
460 case 148 : case 149 : case 150 : case 151 :
461 case 152 : case 153 : case 154 : case 155 :
462 case 156 : case 157 : case 158 : case 159 :
464 op3
= *ip
++; // get class var index
465 post(" %02X StoreClassVar\n", op3
);
469 case 160 : case 161 : case 162 : case 163 :
470 case 164 : case 165 : case 166 : case 167 :
471 case 168 : case 169 : case 170 : case 171 :
472 case 172 : case 173 : case 174 : case 175 :
473 op2
= *ip
++; // get selector index
474 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
]);
475 post(" %02X SendMsg '%s'\n", op2
, selector
->name
);
478 // TailCallReturnFromFunction
480 post(" TailCallReturnFromFunction\n");
484 case 177 : case 178 : case 179 :
485 case 180 : case 181 : case 182 : case 183 :
486 case 184 : case 185 : case 186 : case 187 :
487 case 188 : case 189 : case 190 : case 191 :
488 op2
= *ip
++; // get selector index
489 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
]);
490 post(" %02X SuperMsg '%s'\n", op2
, selector
->name
);
494 case 192 : case 193 : case 194 : case 195 :
495 case 196 : case 197 : case 198 : case 199 :
496 case 200 : case 201 : case 202 : case 203 :
497 case 204 : case 205 : case 206 : case 207 :
498 op2
= *ip
++; // get selector index
499 selector
= gSpecialSelectors
[op2
];
500 post(" %02X SendSpecialMsg '%s'\n", op2
, selector
->name
);
503 // SendSpecialUnaryArithMsg
504 case 208 : case 209 : case 210 : case 211 :
505 case 212 : case 213 : case 214 : case 215 :
506 case 216 : case 217 : case 218 : case 219 :
507 case 220 : case 221 : case 222 : case 223 :
509 selector
= gSpecialUnarySelectors
[op2
];
510 post(" SendSpecialUnaryArithMsg '%s'\n", selector
->name
);
513 // SendSpecialBinaryArithMsg
514 case 224 : case 225 : case 226 : case 227 :
515 case 228 : case 229 : case 230 : case 231 :
516 case 232 : case 233 : case 234 : case 235 :
517 case 236 : case 237 : case 238 : case 239 :
519 selector
= gSpecialBinarySelectors
[op2
];
520 post(" SendSpecialBinaryArithMsg '%s'\n", selector
->name
);
524 case 240 : post(" Drop\n"); break;
525 case 241 : post(" Dup\n"); break; // Dup
527 case 242 : post(" BlockReturn\n"); break; // BlockReturn
528 case 243 : post(" Return\n"); break; // Return
529 case 244 : post(" ReturnSelf\n"); break; // ReturnSelf
530 case 245 : post(" ReturnTrue\n"); break; // ReturnTrue
531 case 246 : post(" ReturnFalse\n"); break; // ReturnFalse
532 case 247 : post(" ReturnNil\n"); break; // ReturnNil
534 case 248 : // JumpIfFalse
537 jmplen
= (op2
<<8) | op3
;
538 post(" %02X %02X JumpIfFalse %d (%d)\n", op2
, op3
, jmplen
, n
+ jmplen
+ 3);
540 case 249 : // JumpIfFalsePushNil
543 jmplen
= ((op2
& 0xFF)<<8) | (op3
& 0xFF);
544 post(" %02X %02X JumpIfFalsePushNil %d (%d)\n", op2
, op3
, jmplen
, n
+ jmplen
+ 3);
546 case 250 : // JumpIfFalsePushFalse
549 jmplen
= (op2
<<8) | op3
;
550 post(" %02X %02X JumpIfFalsePushFalse %d (%d)\n", op2
, op3
, jmplen
, n
+ jmplen
+ 3);
552 case 251 : // JumpIfTruePushTrue
555 jmplen
= (op2
<<8) | op3
;
556 post(" %02X %02X JumpIfTruePushTrue %d (%d)\n", op2
, op3
, jmplen
, n
+ jmplen
+ 3);
558 case 252 : // JumpFwd
561 jmplen
= (op2
<<8) | op3
;
562 post(" %02X %02X JumpFwd %d (%d)\n", op2
, op3
, jmplen
, n
+ jmplen
+ 3);
564 case 253 : // JumpBak
567 jmplen
= (op2
<<8) | op3
;
568 post(" %02X %02X JumpBak %d (%d)\n", op2
, op3
, jmplen
, n
- jmplen
+ 1);
572 post(" %02X SpecialBinaryOpWithAdverb\n", op2
);
575 post(" TailCallReturnFromMethod\n");
583 bool detectSendSelector(PyrBlock
*theBlock
, PyrClass
* theClass
, unsigned char **ipp
, PyrSymbol
*testSelector
);
584 bool detectSendSelector(PyrBlock
*theBlock
, PyrClass
* theClass
, unsigned char **ipp
, PyrSymbol
*testSelector
)
587 PyrSymbol
*selector
= 0;
588 long op1
, op2
, op3
, op4
, op5
, op6
;
589 unsigned char *ip
= *ipp
;
590 if (theClass
== NULL
) {
594 if (isKindOf((PyrObject
*)block
, class_method
)) {
595 theClass
= slotRawClass(&((PyrMethod
*)block
)->ownerclass
);
598 block
= slotRawBlock(&block
->contextDef
);
600 if (theClass
== NULL
) {
601 theClass
= s_interpreter
->u
.classobj
;
606 case 0 : // push class
607 op2
= *ip
++; // get literal index
609 case 1 : // Extended, PushInstVar
610 op2
= *ip
++; // get inst var index
612 case 2 : // Extended, PushTempVar
613 op2
= *ip
++; // get temp var level
614 op3
= *ip
++; // get temp var index
616 case 3 : // Extended, PushTempZeroVar
617 op2
= *ip
++; // get temp var level
619 case 4 : // Extended, PushLiteral
620 op2
= *ip
++; // get literal index
622 case 5 : // Extended, PushClassVar
623 op2
= *ip
++; // get class var literal index
624 op3
= *ip
++; // get class var index
626 case 6 : // Extended, PushSpecialValue == push a special class
627 op2
= *ip
++; // get class name index
629 case 7 : // Extended, StoreInstVar
630 op2
= *ip
++; // get inst var index
632 case 8 : // Extended, StoreTempVar
633 op2
= *ip
++; // get temp var level
634 op3
= *ip
++; // get class var index
636 case 9 : // Extended, StoreClassVar
637 op2
= *ip
++; // get class var literal index
638 op3
= *ip
++; // get class var index
640 case 10 : // Extended, SendMsg
641 op2
= *ip
++; // get num args
642 op3
= *ip
++; // get num key args
643 op4
= *ip
++; // get selector index
644 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op4
]);
646 case 11 : // Extended, SuperMsg
647 op2
= *ip
++; // get num args
648 op3
= *ip
++; // get num key args
649 op4
= *ip
++; // get selector index
650 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op4
]);
652 case 12 : // Extended, SendSpecialMsg
653 op2
= *ip
++; // get num args
654 op3
= *ip
++; // get num key args
655 op4
= *ip
++; // get selector index
656 selector
= gSpecialSelectors
[op4
];
658 case 13 : // Extended, SendSpecialUnaryArithMsg
659 op2
= *ip
++; // get selector index
660 selector
= gSpecialUnarySelectors
[op2
];
662 case 14 : // Extended, SendSpecialBinaryArithMsg
663 op2
= *ip
++; // get selector index
664 selector
= gSpecialBinarySelectors
[op2
];
666 case 15 : // Extended, SpecialOpcode (none yet)
667 op2
= *ip
++; // get extended special opcode
670 // PushInstVar, 0..15
671 case 16 : case 17 : case 18 : case 19 :
672 case 20 : case 21 : case 22 : case 23 :
673 case 24 : case 25 : case 26 : case 27 :
674 case 28 : case 29 : case 30 : case 31 :
676 case 32 : case 33 : case 34 : case 35 :
677 case 36 : case 37 : case 38 : case 39 :
678 case 40 : case 41 : case 42 : case 43 :
679 case 44 : case 45 : case 46 : case 47 :
680 op2
= op1
& 15; // get temp var level
681 op3
= *ip
++; // get num key args
684 case 48 : case 49 : case 50 : case 51 :
685 case 52 : case 53 : case 54 : case 55 :
686 case 56 : case 57 : case 58 : case 59 :
687 case 60 : case 61 : case 62 : case 63 :
690 case 64 : case 65 : case 66 : case 67 :
691 case 68 : case 69 : case 70 : case 71 :
692 case 72 : case 73 : case 74 : case 75 :
693 case 76 : case 77 : case 78 : case 79 :
697 case 80 : case 81 : case 82 : case 83 :
698 case 84 : case 85 : case 86 : case 87 :
699 case 88 : case 89 : case 90 : case 91 :
700 case 92 : case 93 : case 94 : case 95 :
702 op3
= *ip
++; // get class var index
706 case 96 : case 97 : case 98 : case 99 :
707 case 100 : case 101 : case 102 : case 103 :
708 case 104 : case 105 : case 106 : case 107 :
709 case 108 : case 109 : case 110 : case 111 :
712 // StoreInstVar, 0..15
713 case 112 : case 113 : case 114 : case 115 :
714 case 116 : case 117 : case 118 : case 119 :
715 case 120 : case 121 : case 122 : case 123 :
716 case 124 : case 125 : case 126 : case 127 :
720 case 128 : case 129 : case 130 : case 131 :
721 case 132 : case 133 : case 134 : case 135 :
722 op2
= op1
& 15; // get temp var level
723 op3
= *ip
++; // get class var index
726 op2
= *ip
++; // get inst var index
727 op3
= *ip
++; // get selector index
728 selector
= gSpecialSelectors
[op3
];
731 op2
= *ip
++; // get selector index
732 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
]);
735 op2
= *ip
++; // get selector index
736 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
]);
739 op2
= *ip
++; // get selector index
740 selector
= gSpecialSelectors
[op2
];
743 op2
= *ip
++; // get selector index
744 selector
= gSpecialSelectors
[op2
];
747 op2
= *ip
++; // get selector index
748 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
]);
751 op2
= *ip
++; // get selector index
752 selector
= gSpecialSelectors
[op2
];
755 op2
= *ip
++; // get selector index
759 case 144 : case 145 : case 146 : case 147 :
760 case 148 : case 149 : case 150 : case 151 :
761 case 152 : case 153 : case 154 : case 155 :
762 case 156 : case 157 : case 158 : case 159 :
764 op3
= *ip
++; // get class var index
768 case 160 : case 161 : case 162 : case 163 :
769 case 164 : case 165 : case 166 : case 167 :
770 case 168 : case 169 : case 170 : case 171 :
771 case 172 : case 173 : case 174 : case 175 :
772 op2
= *ip
++; // get selector index
773 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
]);
777 case 176 : case 177 : case 178 : case 179 :
778 case 180 : case 181 : case 182 : case 183 :
779 case 184 : case 185 : case 186 : case 187 :
780 case 188 : case 189 : case 190 : case 191 :
781 op2
= *ip
++; // get selector index
782 selector
= slotRawSymbol(&slotRawObject(&theBlock
->selectors
)->slots
[op2
]);
786 case 192 : case 193 : case 194 : case 195 :
787 case 196 : case 197 : case 198 : case 199 :
788 case 200 : case 201 : case 202 : case 203 :
789 case 204 : case 205 : case 206 : case 207 :
790 op2
= *ip
++; // get selector index
791 selector
= gSpecialSelectors
[op2
];
794 // SendSpecialUnaryArithMsg
795 case 208 : case 209 : case 210 : case 211 :
796 case 212 : case 213 : case 214 : case 215 :
797 case 216 : case 217 : case 218 : case 219 :
798 case 220 : case 221 : case 222 : case 223 :
800 selector
= gSpecialUnarySelectors
[op2
];
803 // SendSpecialBinaryArithMsg
804 case 224 : case 225 : case 226 : case 227 :
805 case 228 : case 229 : case 230 : case 231 :
806 case 232 : case 233 : case 234 : case 235 :
807 case 236 : case 237 : case 238 : case 239 :
809 selector
= gSpecialBinarySelectors
[op2
];
813 case 240 : case 241 : case 242 : case 243 :
814 case 244 : case 245 : case 246 : case 247 :
817 case 248 : // JumpIfFalse
818 case 249 : // JumpIfFalsePushNil
819 case 250 : // JumpIfFalsePushFalse
820 case 251 : // JumpIfTruePushTrue
821 case 252 : // JumpFwd
822 case 253 : // JumpBak
826 case 254 : // PushPosInt
827 case 255 : // PushNegInt
845 return testSelector
== selector
;
850 void dumpByteCodes(PyrBlock
*theBlock
);
851 void dumpByteCodes(PyrBlock
*theBlock
)
856 unsigned char *ip
, *ipbeg
, *ipend
;
858 if (slotRawInt8Array(&theBlock
->code
) == NULL
) {
859 post("Code empty.\n");
865 if (isKindOf((PyrObject
*)block
, class_method
)) {
866 theClass
= slotRawClass(&((PyrMethod
*)block
)->ownerclass
);
869 block
= slotRawBlock(&block
->contextDef
);
871 if (theClass
== NULL
) {
872 theClass
= s_interpreter
->u
.classobj
;
875 ip
= ipbeg
= slotRawInt8Array(&theBlock
->code
)->b
;
876 size
= slotRawInt8Array(&theBlock
->code
)->size
;
878 post("BYTECODES: (%d)\n", size
);
880 ip
= dumpOneByteCode(theBlock
, theClass
, ip
);
884 bool detectSendSelectorIn(PyrBlock
*theBlock
, PyrSymbol
*testSelector
);
885 bool detectSendSelectorIn(PyrBlock
*theBlock
, PyrSymbol
*testSelector
)
891 unsigned char *ip
, *ipbeg
, *ipend
;
893 if (slotRawInt8Array(&theBlock
->code
) == NULL
) {
894 PyrMethodRaw
* methraw
= METHRAW(theBlock
);
895 switch (methraw
->methType
) {
897 case methRedirectSuper
:
898 case methForwardInstVar
:
899 case methForwardClassVar
:
900 selector
= slotRawSymbol(&theBlock
->selectors
);
901 return selector
== testSelector
;
909 if (isKindOf((PyrObject
*)block
, class_method
)) {
910 theClass
= slotRawClass(&((PyrMethod
*)block
)->ownerclass
);
913 block
= slotRawBlock(&block
->contextDef
);
915 if (theClass
== NULL
) {
916 theClass
= s_interpreter
->u
.classobj
;
919 ip
= ipbeg
= slotRawInt8Array(&theBlock
->code
)->b
;
920 size
= slotRawInt8Array(&theBlock
->code
)->size
;
924 if ((res
= detectSendSelector(theBlock
, theClass
, &ip
, testSelector
))) break;
930 const char* byteCodeString(int code
);
931 const char* byteCodeString(int code
)
934 case 0 : return "PushClassX";
935 case 1 : return "PushInstVarX";
936 case 2 : return "PushTempVarX";
937 case 3 : return "PushTempZeroVarX";
938 case 4 : return "PushLiteralX";
939 case 5 : return "PushClassVarX";
940 case 6 : return "PushSpecialClass";
941 case 7 : return "StoreInstVarX";
942 case 8 : return "StoreTempVarX";
943 case 9 : return "StoreClassVarX";
944 case 10 : return "SendMsgX";
945 case 11 : return "SuperMsgX";
946 case 12 : return "SendSpecialMsgX";
947 case 13 : return "SendSpecialUnaryArithMsgX";
948 case 14 : return "SendSpecialBinaryArithMsgX";
949 case 15 : return "PushGlobal";
951 case 16 : case 17 : case 18 : case 19 :
952 case 20 : case 21 : case 22 : case 23 :
953 case 24 : case 25 : case 26 : case 27 :
954 case 28 : case 29 : case 30 : case 31 :
955 return "PushInstVar";
957 case 32 : case 33 : case 34 : case 35 :
958 case 36 : case 37 : case 38 : case 39 :
959 case 40 : case 41 : case 42 : case 43 :
960 case 44 : case 45 : case 46 : case 47 :
961 return "PushTempVar";
963 case 48 : case 49 : case 50 : case 51 :
964 case 52 : case 53 : case 54 : case 55 :
965 case 56 : case 57 : case 58 : case 59 :
966 case 60 : case 61 : case 62 : case 63 :
967 return "PushTempZeroVar";
969 case 64 : case 65 : case 66 : case 67 :
970 case 68 : case 69 : case 70 : case 71 :
971 case 72 : case 73 : case 74 : case 75 :
972 case 76 : case 77 : case 78 : case 79 :
973 return "PushLiteral";
975 case 80 : case 81 : case 82 : case 83 :
976 case 84 : case 85 : case 86 : case 87 :
977 case 88 : case 89 : case 90 : case 91 :
978 case 92 : case 93 : case 94 : case 95 :
979 return "PushClassVar";
981 case 96 : return "PushSpecialValue this";
982 case 97 : return "PushOneAndSubtract";
983 case 98 : return "PushSpecialValue -1";
984 case 99 : return "PushSpecialValue 0";
985 case 100 : return "PushSpecialValue 1";
986 case 101 : return "PushSpecialValue 2";
987 case 102 : return "PushSpecialValue 0.5";
988 case 103 : return "PushSpecialValue -1.0";
989 case 104 : return "PushSpecialValue 0.0";
990 case 105 : return "PushSpecialValue 1.0";
991 case 106 : return "PushSpecialValue 2.0";
992 case 107 : return "PushOneAndAdd";
993 case 108 : return "PushSpecialValue true";
994 case 109 : return "PushSpecialValue false";
995 case 110 : return "PushSpecialValue nil";
996 case 111 : return "PushSpecialValue 'end'";
998 case 112 : case 113 : case 114 : case 115 :
999 case 116 : case 117 : case 118 : case 119 :
1000 case 120 : case 121 : case 122 : case 123 :
1001 case 124 : case 125 : case 126 : case 127 :
1002 return "StoreInstVar";
1004 case 128 : case 129 : case 130 : case 131 :
1005 return "StoreTempVar";
1007 case 132 : return "PushInstVarAndSendNext";
1008 case 133 : return "PushInstVarAndSendPrNext";
1009 case 134 : return "PushInstVarAndSendDemandThisNode";
1010 case 135 : return "PushInstVarAndSendSpecialMsg";
1012 case 136 : case 137 : case 138 : case 139 :
1013 case 140 : case 141 : case 142 : case 143 :
1014 return "UndefinedOpcode";
1016 case 144 : case 145 : case 146 : case 147 :
1017 case 148 : case 149 : case 150 : case 151 :
1018 case 152 : case 153 : case 154 : case 155 :
1019 case 156 : case 157 : case 158 : case 159 :
1020 return "StoreClassVar";
1022 case 160 : case 161 : case 162 : case 163 :
1023 case 164 : case 165 : case 166 : case 167 :
1024 case 168 : case 169 : case 170 : case 171 :
1025 case 172 : case 173 : case 174 : case 175 :
1029 return "TailCallReturnFromFunction";
1031 case 177 : case 178 : case 179 :
1032 case 180 : case 181 : case 182 : case 183 :
1033 case 184 : case 185 : case 186 : case 187 :
1034 case 188 : case 189 : case 190 : case 191 :
1037 case 192 : case 193 : case 194 : case 195 :
1038 case 196 : case 197 : case 198 : case 199 :
1039 case 200 : case 201 : case 202 : case 203 :
1040 case 204 : case 205 : case 206 : case 207 :
1041 return "SendSpecialMsg";
1043 case 208 : case 209 : case 210 : case 211 :
1044 case 212 : case 213 : case 214 : case 215 :
1045 case 216 : case 217 : case 218 : case 219 :
1046 case 220 : case 221 : case 222 : case 223 :
1047 return "SendSpecialUnaryArithMsg";
1049 case 224 : case 225 : case 226 : case 227 :
1050 case 228 : case 229 : case 230 : case 231 :
1051 case 232 : case 233 : case 234 : case 235 :
1052 case 236 : case 237 : case 238 : case 239 :
1053 return "SendSpecialBinaryArithMsg";
1056 case 240 : return "Drop";
1057 case 241 : return "Dup"; // Dup
1059 case 242 : return "BlockReturn"; // BlockReturn
1060 case 243 : return "Return"; // Return
1061 case 244 : return "ReturnSelf"; // ReturnSelf
1062 case 245 : return "ReturnTrue"; // ReturnTrue
1063 case 246 : return "ReturnFalse"; // ReturnFalse
1064 case 247 : return "ReturnNil"; // ReturnNil
1066 case 248 : return "JumpIfFalse"; // JumpIfFalse
1067 case 249 : return "JumpIfFalsePushNil"; // JumpIfFalsePushNil
1069 case 250 : return "JumpIfFalsePushFalse"; // JumpIfFalsePushFalse
1070 case 251 : return "JumpIfTruePushTrue"; // JumpIfTruePushTrue
1071 case 252 : return "JumpFwd"; // JumpFwd
1072 case 253 : return "JumpBak"; // JumpBak
1073 case 254 : return "PushPosInt"; // PushPosInt
1074 case 255 : return "TailCallReturnFromMethod"; // TailCallReturnFromMethod
1076 return "unknown opcode";