00001
00012 #define TS_ISEQ 'S'
00013 #define TS_LINDEX 'L'
00014 #define TS_OFFSET 'O'
00015 #define TS_GENTRY 'G'
00016 #define TS_VARIABLE '.'
00017 #define TS_FUNCPTR 'F'
00018 #define TS_IC 'C'
00019 #define TS_ID 'I'
00020 #define TS_VALUE 'V'
00021 #define TS_CDHASH 'H'
00022 #define TS_DINDEX 'D'
00023 #define TS_NUM 'N'
00024
00025 static const char *const insn_name_info[] = {
00026 "nop",
00027 "getlocal",
00028 "setlocal",
00029 "getspecial",
00030 "setspecial",
00031 "getdynamic",
00032 "setdynamic",
00033 "getinstancevariable",
00034 "setinstancevariable",
00035 "getclassvariable",
00036 "setclassvariable",
00037 "getconstant",
00038 "setconstant",
00039 "getglobal",
00040 "setglobal",
00041 "putnil",
00042 "putself",
00043 "putobject",
00044 "putspecialobject",
00045 "putiseq",
00046 "putstring",
00047 "concatstrings",
00048 "tostring",
00049 "toregexp",
00050 "newarray",
00051 "duparray",
00052 "expandarray",
00053 "concatarray",
00054 "splatarray",
00055 "checkincludearray",
00056 "newhash",
00057 "newrange",
00058 "pop",
00059 "dup",
00060 "dupn",
00061 "swap",
00062 "reput",
00063 "topn",
00064 "setn",
00065 "adjuststack",
00066 "defined",
00067 "trace",
00068 "defineclass",
00069 "send",
00070 "invokesuper",
00071 "invokeblock",
00072 "leave",
00073 "finish",
00074 "throw",
00075 "jump",
00076 "branchif",
00077 "branchunless",
00078 "getinlinecache",
00079 "onceinlinecache",
00080 "setinlinecache",
00081 "opt_case_dispatch",
00082 "opt_checkenv",
00083 "opt_plus",
00084 "opt_minus",
00085 "opt_mult",
00086 "opt_div",
00087 "opt_mod",
00088 "opt_eq",
00089 "opt_neq",
00090 "opt_lt",
00091 "opt_le",
00092 "opt_gt",
00093 "opt_ge",
00094 "opt_ltlt",
00095 "opt_aref",
00096 "opt_aset",
00097 "opt_length",
00098 "opt_size",
00099 "opt_succ",
00100 "opt_not",
00101 "opt_regexpmatch1",
00102 "opt_regexpmatch2",
00103 "opt_call_c_function",
00104 "bitblt",
00105 "answer",
00106
00107 };
00108
00109 static const char *const insn_operand_info[] = {
00110 "",
00111 "L",
00112 "L",
00113 "VN",
00114 "V",
00115 "DN",
00116 "DN",
00117 "IC",
00118 "IC",
00119 "I",
00120 "I",
00121 "I",
00122 "I",
00123 "G",
00124 "G",
00125 "",
00126 "",
00127 "V",
00128 "N",
00129 "S",
00130 "V",
00131 "N",
00132 "",
00133 "NN",
00134 "N",
00135 "V",
00136 "NN",
00137 "",
00138 "V",
00139 "V",
00140 "N",
00141 "N",
00142 "",
00143 "",
00144 "N",
00145 "",
00146 "",
00147 "N",
00148 "N",
00149 "N",
00150 "NVV",
00151 "N",
00152 "ISN",
00153 "INSNC",
00154 "NSN",
00155 "NN",
00156 "",
00157 "",
00158 "N",
00159 "O",
00160 "O",
00161 "O",
00162 "OC",
00163 "OC",
00164 "C",
00165 "HO",
00166 "",
00167 "C",
00168 "C",
00169 "C",
00170 "C",
00171 "C",
00172 "C",
00173 "CC",
00174 "C",
00175 "C",
00176 "C",
00177 "C",
00178 "C",
00179 "C",
00180 "C",
00181 "C",
00182 "C",
00183 "C",
00184 "C",
00185 "V",
00186 "",
00187 "F",
00188 "",
00189 "",
00190
00191 };
00192
00193 static const int insn_len_info[] = {
00194 1,
00195 2,
00196 2,
00197 3,
00198 2,
00199 3,
00200 3,
00201 3,
00202 3,
00203 2,
00204 2,
00205 2,
00206 2,
00207 2,
00208 2,
00209 1,
00210 1,
00211 2,
00212 2,
00213 2,
00214 2,
00215 2,
00216 1,
00217 3,
00218 2,
00219 2,
00220 3,
00221 1,
00222 2,
00223 2,
00224 2,
00225 2,
00226 1,
00227 1,
00228 2,
00229 1,
00230 1,
00231 2,
00232 2,
00233 2,
00234 4,
00235 2,
00236 4,
00237 6,
00238 4,
00239 3,
00240 1,
00241 1,
00242 2,
00243 2,
00244 2,
00245 2,
00246 3,
00247 3,
00248 2,
00249 3,
00250 1,
00251 2,
00252 2,
00253 2,
00254 2,
00255 2,
00256 2,
00257 3,
00258 2,
00259 2,
00260 2,
00261 2,
00262 2,
00263 2,
00264 2,
00265 2,
00266 2,
00267 2,
00268 2,
00269 2,
00270 1,
00271 2,
00272 1,
00273 1,
00274
00275 };
00276
00277 #ifdef USE_INSN_RET_NUM
00278 static const int insn_stack_push_num_info[] = {
00279 0,
00280 1,
00281 0,
00282 1,
00283 0,
00284 1,
00285 0,
00286 1,
00287 0,
00288 1,
00289 0,
00290 1,
00291 0,
00292 1,
00293 0,
00294 1,
00295 1,
00296 1,
00297 1,
00298 1,
00299 1,
00300 1,
00301 1,
00302 1,
00303 1,
00304 1,
00305 1,
00306 1,
00307 1,
00308 2,
00309 1,
00310 1,
00311 0,
00312 2,
00313 1,
00314 2,
00315 1,
00316 1,
00317 1,
00318 1,
00319 1,
00320 0,
00321 1,
00322 1,
00323 1,
00324 1,
00325 1,
00326 1,
00327 1,
00328 0,
00329 0,
00330 0,
00331 1,
00332 1,
00333 1,
00334 0,
00335 0,
00336 1,
00337 1,
00338 1,
00339 1,
00340 1,
00341 1,
00342 1,
00343 1,
00344 1,
00345 1,
00346 1,
00347 1,
00348 1,
00349 1,
00350 1,
00351 1,
00352 1,
00353 1,
00354 1,
00355 1,
00356 0,
00357 1,
00358 1,
00359
00360 };
00361 #endif
00362
00363 #ifdef USE_INSN_STACK_INCREASE
00364 static int
00365 insn_stack_increase(int depth, int insn, VALUE *opes)
00366 {
00367 switch(insn){
00368 case BIN(nop):{
00369 return depth + 0;
00370 }
00371 case BIN(getlocal):{
00372 return depth + 1;
00373 }
00374 case BIN(setlocal):{
00375 return depth + -1;
00376 }
00377 case BIN(getspecial):{
00378 return depth + 1;
00379 }
00380 case BIN(setspecial):{
00381 return depth + -1;
00382 }
00383 case BIN(getdynamic):{
00384 return depth + 1;
00385 }
00386 case BIN(setdynamic):{
00387 return depth + -1;
00388 }
00389 case BIN(getinstancevariable):{
00390 return depth + 1;
00391 }
00392 case BIN(setinstancevariable):{
00393 return depth + -1;
00394 }
00395 case BIN(getclassvariable):{
00396 return depth + 1;
00397 }
00398 case BIN(setclassvariable):{
00399 return depth + -1;
00400 }
00401 case BIN(getconstant):{
00402 return depth + 0;
00403 }
00404 case BIN(setconstant):{
00405 return depth + -2;
00406 }
00407 case BIN(getglobal):{
00408 return depth + 1;
00409 }
00410 case BIN(setglobal):{
00411 return depth + -1;
00412 }
00413 case BIN(putnil):{
00414 return depth + 1;
00415 }
00416 case BIN(putself):{
00417 return depth + 1;
00418 }
00419 case BIN(putobject):{
00420 return depth + 1;
00421 }
00422 case BIN(putspecialobject):{
00423 return depth + 1;
00424 }
00425 case BIN(putiseq):{
00426 return depth + 1;
00427 }
00428 case BIN(putstring):{
00429 return depth + 1;
00430 }
00431 case BIN(concatstrings):{
00432 int inc = 0;
00433 int num = FIX2INT(opes[0]);
00434 inc += 1 - num;;
00435 return depth + inc;
00436 }
00437 case BIN(tostring):{
00438 return depth + 0;
00439 }
00440 case BIN(toregexp):{
00441 int inc = 0;
00442 int cnt = FIX2INT(opes[1]);
00443 inc += 1 - cnt;;
00444 return depth + inc;
00445 }
00446 case BIN(newarray):{
00447 int inc = 0;
00448 int num = FIX2INT(opes[0]);
00449 inc += 1 - num;;
00450 return depth + inc;
00451 }
00452 case BIN(duparray):{
00453 return depth + 1;
00454 }
00455 case BIN(expandarray):{
00456 int inc = 0;
00457 int num = FIX2INT(opes[0]);
00458 int flag = FIX2INT(opes[1]);
00459 inc += num - 1 + (flag & 1 ? 1 : 0);;
00460 return depth + inc;
00461 }
00462 case BIN(concatarray):{
00463 return depth + -1;
00464 }
00465 case BIN(splatarray):{
00466 return depth + 0;
00467 }
00468 case BIN(checkincludearray):{
00469 return depth + 0;
00470 }
00471 case BIN(newhash):{
00472 int inc = 0;
00473 int num = FIX2INT(opes[0]);
00474 inc += 1 - num;;
00475 return depth + inc;
00476 }
00477 case BIN(newrange):{
00478 return depth + -1;
00479 }
00480 case BIN(pop):{
00481 return depth + -1;
00482 }
00483 case BIN(dup):{
00484 return depth + 1;
00485 }
00486 case BIN(dupn):{
00487 int inc = 0;
00488 int n = FIX2INT(opes[0]);
00489 inc += n;;
00490 return depth + inc;
00491 }
00492 case BIN(swap):{
00493 return depth + 0;
00494 }
00495 case BIN(reput):{
00496 int inc = 0;
00497 inc += 0;;
00498 return depth + inc;
00499 }
00500 case BIN(topn):{
00501 int inc = 0;
00502 inc += 1;;
00503 return depth + inc;
00504 }
00505 case BIN(setn):{
00506 int inc = 0;
00507 inc += 0;
00508 return depth + inc;
00509 }
00510 case BIN(adjuststack):{
00511 int inc = 0;
00512 int n = FIX2INT(opes[0]);
00513 inc -= n;
00514 return depth + inc;
00515 }
00516 case BIN(defined):{
00517 return depth + 0;
00518 }
00519 case BIN(trace):{
00520 return depth + 0;
00521 }
00522 case BIN(defineclass):{
00523 return depth + -1;
00524 }
00525 case BIN(send):{
00526 int inc = 0;
00527 int op_argc = FIX2INT(opes[1]);
00528 int op_flag = FIX2INT(opes[3]);
00529 inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));;
00530 return depth + inc;
00531 }
00532 case BIN(invokesuper):{
00533 int inc = 0;
00534 int op_argc = FIX2INT(opes[0]);
00535 int op_flag = FIX2INT(opes[2]);
00536 inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));;
00537 return depth + inc;
00538 }
00539 case BIN(invokeblock):{
00540 int inc = 0;
00541 int num = FIX2INT(opes[0]);
00542 inc += 1 - num;;
00543 return depth + inc;
00544 }
00545 case BIN(leave):{
00546 return depth + 0;
00547 }
00548 case BIN(finish):{
00549 return depth + 0;
00550 }
00551 case BIN(throw):{
00552 return depth + 0;
00553 }
00554 case BIN(jump):{
00555 return depth + 0;
00556 }
00557 case BIN(branchif):{
00558 return depth + -1;
00559 }
00560 case BIN(branchunless):{
00561 return depth + -1;
00562 }
00563 case BIN(getinlinecache):{
00564 return depth + 1;
00565 }
00566 case BIN(onceinlinecache):{
00567 return depth + 1;
00568 }
00569 case BIN(setinlinecache):{
00570 return depth + 0;
00571 }
00572 case BIN(opt_case_dispatch):{
00573 int inc = 0;
00574 inc += -1;;
00575 return depth + inc;
00576 }
00577 case BIN(opt_checkenv):{
00578 return depth + 0;
00579 }
00580 case BIN(opt_plus):{
00581 return depth + -1;
00582 }
00583 case BIN(opt_minus):{
00584 return depth + -1;
00585 }
00586 case BIN(opt_mult):{
00587 return depth + -1;
00588 }
00589 case BIN(opt_div):{
00590 return depth + -1;
00591 }
00592 case BIN(opt_mod):{
00593 return depth + -1;
00594 }
00595 case BIN(opt_eq):{
00596 return depth + -1;
00597 }
00598 case BIN(opt_neq):{
00599 return depth + -1;
00600 }
00601 case BIN(opt_lt):{
00602 return depth + -1;
00603 }
00604 case BIN(opt_le):{
00605 return depth + -1;
00606 }
00607 case BIN(opt_gt):{
00608 return depth + -1;
00609 }
00610 case BIN(opt_ge):{
00611 return depth + -1;
00612 }
00613 case BIN(opt_ltlt):{
00614 return depth + -1;
00615 }
00616 case BIN(opt_aref):{
00617 return depth + -1;
00618 }
00619 case BIN(opt_aset):{
00620 return depth + -2;
00621 }
00622 case BIN(opt_length):{
00623 return depth + 0;
00624 }
00625 case BIN(opt_size):{
00626 return depth + 0;
00627 }
00628 case BIN(opt_succ):{
00629 return depth + 0;
00630 }
00631 case BIN(opt_not):{
00632 return depth + 0;
00633 }
00634 case BIN(opt_regexpmatch1):{
00635 return depth + 0;
00636 }
00637 case BIN(opt_regexpmatch2):{
00638 return depth + -1;
00639 }
00640 case BIN(opt_call_c_function):{
00641 return depth + 0;
00642 }
00643 case BIN(bitblt):{
00644 return depth + 1;
00645 }
00646 case BIN(answer):{
00647 return depth + 1;
00648 }
00649
00650 default:
00651 rb_bug("insn_sp_increase: unreachable");
00652 }
00653 return 0;
00654 }
00655 #endif
00656
00657
00658
00659 static int
00660 insn_len(VALUE insn)
00661 {
00662 return insn_len_info[(int)insn];
00663 }
00664
00665 static const char *
00666 insn_name(VALUE insn)
00667 {
00668 return insn_name_info[(int)insn];
00669 }
00670
00671 static const char *
00672 insn_op_types(VALUE insn)
00673 {
00674 return insn_operand_info[(int)insn];
00675 }
00676
00677 static int
00678 insn_op_type(VALUE insn, long pos)
00679 {
00680 int len = insn_len(insn) - 1;
00681 if(pos < len){
00682 return insn_operand_info[(int)insn][pos];
00683 }
00684 else{
00685 return 0;
00686 }
00687 }
00688
00689 #ifdef USE_INSN_RET_NUM
00690 static int
00691 insn_ret_num(VALUE insn)
00692 {
00693 return insn_stack_push_num_info[(int)insn];
00694 }
00695 #endif
00696