diff options
Diffstat (limited to 'ldebug.c')
| -rw-r--r-- | ldebug.c | 360 |
1 files changed, 195 insertions, 165 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 1.75 2001/03/26 14:31:49 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.76 2001/04/06 18:25:00 roberto Exp roberto $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -22,6 +22,7 @@ | |||
| 22 | #include "ltable.h" | 22 | #include "ltable.h" |
| 23 | #include "ltm.h" | 23 | #include "ltm.h" |
| 24 | #include "luadebug.h" | 24 | #include "luadebug.h" |
| 25 | #include "lvm.h" | ||
| 25 | 26 | ||
| 26 | 27 | ||
| 27 | 28 | ||
| @@ -298,6 +299,10 @@ LUA_API int lua_getinfo (lua_State *L, const l_char *what, lua_Debug *ar) { | |||
| 298 | 299 | ||
| 299 | #define check(x) if (!(x)) return 0; | 300 | #define check(x) if (!(x)) return 0; |
| 300 | 301 | ||
| 302 | #define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) | ||
| 303 | |||
| 304 | #define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) | ||
| 305 | |||
| 301 | 306 | ||
| 302 | static int checklineinfo (const Proto *pt) { | 307 | static int checklineinfo (const Proto *pt) { |
| 303 | int *lineinfo = pt->lineinfo; | 308 | int *lineinfo = pt->lineinfo; |
| @@ -318,231 +323,199 @@ static int precheck (const Proto *pt) { | |||
| 318 | } | 323 | } |
| 319 | 324 | ||
| 320 | 325 | ||
| 321 | /* value for non-initialized entries in array stacklevel */ | 326 | static int checkopenop (Instruction i) { |
| 322 | #define SL_EMPTY 255 | 327 | OpCode op = GET_OPCODE(i); |
| 323 | 328 | switch (op) { | |
| 324 | #define checkjump(pt,sl,top,pc) if (!checkjump_aux(pt,sl,top,pc)) return 0; | 329 | case OP_CALL: |
| 325 | 330 | case OP_RETURN: { | |
| 326 | static int checkjump_aux (const Proto *pt, lu_byte *sl, int top, int pc) { | 331 | check(GETARG_B(i) == NO_REG); |
| 327 | check(0 <= pc && pc < pt->sizecode); | 332 | return 1; |
| 328 | if (sl == NULL) return 1; /* not full checking */ | 333 | } |
| 329 | if (sl[pc] == SL_EMPTY) | 334 | case OP_SETLISTO: return 1; |
| 330 | sl[pc] = (lu_byte)top; | 335 | default: return 0; /* invalid instruction after an open call */ |
| 331 | else | 336 | } |
| 332 | check(sl[pc] == top); | ||
| 333 | return 1; | ||
| 334 | } | 337 | } |
| 335 | 338 | ||
| 336 | 339 | ||
| 337 | static Instruction luaG_symbexec (lua_State *L, const Proto *pt, | 340 | static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { |
| 338 | int lastpc, int stackpos) { | ||
| 339 | int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */ | ||
| 340 | lu_byte *sl = NULL; | ||
| 341 | int top; | ||
| 342 | int pc; | 341 | int pc; |
| 343 | if (stackpos < 0) { /* full check? */ | 342 | int last; /* stores position of last instruction that changed `reg' */ |
| 344 | int i; | 343 | last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ |
| 345 | sl = luaO_openspace(L, pt->sizecode, lu_byte); | 344 | if (reg == NO_REG) /* full check? */ |
| 346 | for (i=0; i<pt->sizecode; i++) /* initialize stack-level array */ | ||
| 347 | sl[i] = SL_EMPTY; | ||
| 348 | check(precheck(pt)); | 345 | check(precheck(pt)); |
| 349 | } | 346 | for (pc = 0; pc < lastpc; pc++) { |
| 350 | top = pt->numparams; | 347 | const Instruction i = pt->code[pc]; |
| 351 | pc = 0; | ||
| 352 | if (pt->is_vararg) /* varargs? */ | ||
| 353 | top++; /* `arg' */ | ||
| 354 | if (sl) sl[0] = (lu_byte)top; | ||
| 355 | while (pc < lastpc) { | ||
| 356 | const Instruction i = pt->code[pc++]; | ||
| 357 | OpCode op = GET_OPCODE(i); | 348 | OpCode op = GET_OPCODE(i); |
| 358 | int arg1 = 0; | 349 | int a = GETARG_A(i); |
| 359 | int arg2 = 0; | 350 | int b = 0; |
| 360 | int push, pop; | 351 | int c = 0; |
| 361 | check(op < NUM_OPCODES); | 352 | #undef check |
| 362 | push = (int)luaK_opproperties[op].push; | 353 | #define check(x) if (!(x)) { \ |
| 363 | pop = (int)luaK_opproperties[op].pop; | 354 | printf(">>>%d %d %d %d %d %d\n", op, a, b, c, pt->maxstacksize, pt->sizek); \ |
| 364 | switch ((enum Mode)luaK_opproperties[op].mode) { | 355 | return 0; } |
| 365 | case iO: break; | 356 | switch (getOpMode(op)) { |
| 366 | case iU: arg1 = GETARG_U(i); check(arg1 >= 0); break; | 357 | case iABC: { |
| 367 | case iS: arg1 = GETARG_S(i); break; | 358 | b = GETARG_B(i); |
| 368 | case iAB: | 359 | c = GETARG_C(i); |
| 369 | arg1 = GETARG_A(i); arg2 = GETARG_B(i); check(arg1 >= 0); break; | 360 | if (testOpMode(op, OpModeBreg)) { |
| 370 | } | 361 | checkreg(pt, b); |
| 371 | switch (op) { | 362 | check(c < pt->maxstacksize || |
| 372 | case OP_RETURN: { | 363 | (c >= MAXSTACK && c-MAXSTACK < pt->sizek)); |
| 373 | check(arg1 <= top); | 364 | } |
| 374 | pop = top-arg1; | ||
| 375 | break; | 365 | break; |
| 376 | } | 366 | } |
| 377 | case OP_CALL: { | 367 | case iABc: { |
| 378 | if (arg2 == MULT_RET) arg2 = 1; | 368 | b = GETARG_Bc(i); |
| 379 | check(arg1 < top); | 369 | if (testOpMode(op, OpModeK)) check(b < pt->sizek); |
| 380 | pop = top-arg1; | ||
| 381 | push = arg2; | ||
| 382 | break; | 370 | break; |
| 383 | } | 371 | } |
| 384 | case OP_PUSHNIL: { | 372 | case iAsBc: { |
| 385 | check(arg1 > 0); | 373 | b = GETARG_sBc(i); |
| 386 | push = arg1; | ||
| 387 | break; | 374 | break; |
| 388 | } | 375 | } |
| 389 | case OP_POP: { | 376 | } |
| 390 | pop = arg1; | 377 | if (testOpMode(op, OpModeAreg)) checkreg(pt, a); |
| 378 | if (testOpMode(op, OpModesetA)) { | ||
| 379 | if (a == reg) last = pc; /* change register `a' */ | ||
| 380 | } | ||
| 381 | if (testOpMode(op, OpModeT)) | ||
| 382 | check(GET_OPCODE(pt->code[pc+1]) == OP_CJMP); | ||
| 383 | switch (op) { | ||
| 384 | case OP_LOADNIL: { | ||
| 385 | if (a <= reg && reg <= b) | ||
| 386 | last = pc; /* set registers from `a' to `b' */ | ||
| 391 | break; | 387 | break; |
| 392 | } | 388 | } |
| 393 | case OP_PUSHSTRING: | 389 | case OP_LOADUPVAL: { |
| 394 | case OP_GETGLOBAL: | 390 | check(b < pt->nupvalues); |
| 395 | case OP_GETDOTTED: | ||
| 396 | case OP_PUSHSELF: | ||
| 397 | case OP_SETGLOBAL: { | ||
| 398 | check(arg1 < pt->sizekstr); | ||
| 399 | break; | 391 | break; |
| 400 | } | 392 | } |
| 401 | case OP_PUSHNUM: | 393 | case OP_GETGLOBAL: |
| 402 | case OP_PUSHNEGNUM: { | 394 | case OP_SETGLOBAL: { |
| 403 | check(arg1 < pt->sizeknum); | 395 | check(ttype(&pt->k[b]) == LUA_TSTRING); |
| 404 | break; | 396 | break; |
| 405 | } | 397 | } |
| 406 | case OP_PUSHUPVALUE: { | 398 | case OP_SELF: { |
| 407 | check(arg1 < pt->nupvalues); | 399 | checkreg(pt, a+1); |
| 400 | if (reg == a+1) last = pc; | ||
| 408 | break; | 401 | break; |
| 409 | } | 402 | } |
| 410 | case OP_GETLOCAL: | 403 | case OP_CONCAT: { |
| 411 | case OP_GETINDEXED: | 404 | check(b < c); /* at least two operands */ |
| 412 | case OP_SETLOCAL: { | ||
| 413 | check(arg1 < top); | ||
| 414 | break; | 405 | break; |
| 415 | } | 406 | } |
| 416 | case OP_SETTABLE: { | 407 | case OP_JMP: |
| 417 | check(3 <= arg1 && arg1 <= top); | 408 | case OP_CJMP: { |
| 418 | pop = arg2; | 409 | int dest = pc+1+b; |
| 410 | check(0 <= dest && dest < pt->sizecode); | ||
| 411 | /* not full check and jump is forward and do not skip `lastpc'? */ | ||
| 412 | if (reg != NO_REG && pc < dest && dest <= lastpc) | ||
| 413 | pc += b; /* do the jump */ | ||
| 419 | break; | 414 | break; |
| 420 | } | 415 | } |
| 421 | case OP_SETLIST: { | 416 | case OP_TESTT: |
| 422 | check(arg2 >= 0); | 417 | case OP_TESTF: { |
| 423 | pop = top-arg2-1; | 418 | if (a != NO_REG) |
| 419 | checkreg(pt, a); | ||
| 424 | break; | 420 | break; |
| 425 | } | 421 | } |
| 426 | case OP_SETMAP: { | 422 | case OP_NILJMP: { |
| 427 | check(arg1 >= 0); | 423 | check(pc+2 < pt->sizecode); /* check its jump */ |
| 428 | pop = top-arg1-1; | ||
| 429 | break; | 424 | break; |
| 430 | } | 425 | } |
| 431 | case OP_CONCAT: { | 426 | case OP_CALL: { |
| 432 | pop = arg1; | 427 | if (b == NO_REG) b = pt->maxstacksize; |
| 428 | if (c == NO_REG) { | ||
| 429 | check(checkopenop(pt->code[pc+1])); | ||
| 430 | c = 1; | ||
| 431 | } | ||
| 432 | check(b > a); | ||
| 433 | checkreg(pt, b-1); | ||
| 434 | checkreg(pt, a+c-1); | ||
| 435 | if (reg >= a) last = pc; /* affect all registers above base */ | ||
| 433 | break; | 436 | break; |
| 434 | } | 437 | } |
| 435 | case OP_CLOSURE: { | 438 | case OP_RETURN: { |
| 436 | check(arg1 < pt->sizekproto); | 439 | if (b == NO_REG) b = pt->maxstacksize; |
| 437 | check(arg2 == pt->kproto[arg1]->nupvalues); | 440 | checkreg(pt, b-1); |
| 438 | pop = arg2; | ||
| 439 | break; | 441 | break; |
| 440 | } | 442 | } |
| 441 | case OP_JMPNE: | 443 | case OP_FORPREP: |
| 442 | case OP_JMPEQ: | 444 | case OP_TFORPREP: { |
| 443 | case OP_JMPLT: | 445 | int dest = pc-b; /* jump is negated here */ |
| 444 | case OP_JMPLE: | 446 | check(0 <= dest && dest < pt->sizecode && |
| 445 | case OP_JMPGT: | 447 | GET_OPCODE(pt->code[dest]) == op+1); |
| 446 | case OP_JMPGE: | ||
| 447 | case OP_JMPT: | ||
| 448 | case OP_JMPF: | ||
| 449 | case OP_JMP: { | ||
| 450 | checkjump(pt, sl, top-pop, pc+arg1); | ||
| 451 | break; | 448 | break; |
| 452 | } | 449 | } |
| 453 | case OP_FORLOOP: | 450 | case OP_FORLOOP: |
| 454 | case OP_LFORLOOP: | 451 | case OP_TFORLOOP: { |
| 455 | case OP_JMPONT: | 452 | int dest = pc+b; |
| 456 | case OP_JMPONF: { | 453 | check(0 <= dest && dest < pt->sizecode && |
| 457 | int newpc = pc+arg1; | 454 | pt->code[dest] == SET_OPCODE(i, op-1)); |
| 458 | checkjump(pt, sl, top, newpc); | 455 | checkreg(pt, a + ((op == OP_FORLOOP) ? 2 : 3)); |
| 459 | /* jump is forward and do not skip `lastpc' and not full check? */ | ||
| 460 | if (pc < newpc && newpc <= lastpc && stackpos >= 0) { | ||
| 461 | stack[top-1] = pc-1; /* value comes from `and'/`or' */ | ||
| 462 | pc = newpc; /* do the jump */ | ||
| 463 | pop = 0; /* do not pop */ | ||
| 464 | } | ||
| 465 | break; | ||
| 466 | } | ||
| 467 | case OP_PUSHNILJMP: { | ||
| 468 | check(GET_OPCODE(pt->code[pc]) == OP_PUSHINT); /* only valid sequence */ | ||
| 469 | break; | 456 | break; |
| 470 | } | 457 | } |
| 471 | case OP_FORPREP: { | 458 | case OP_SETLIST: { |
| 472 | int endfor = pc-arg1-1; /* jump is `negative' here */ | 459 | checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1); |
| 473 | check(top >= 3); | ||
| 474 | checkjump(pt, sl, top+push, endfor); | ||
| 475 | check(GET_OPCODE(pt->code[endfor]) == OP_FORLOOP); | ||
| 476 | check(GETARG_S(pt->code[endfor]) == arg1); | ||
| 477 | break; | ||
| 478 | } | ||
| 479 | case OP_LFORPREP: { | ||
| 480 | int endfor = pc-arg1-1; /* jump is `negative' here */ | ||
| 481 | check(top >= 1); | ||
| 482 | checkjump(pt, sl, top+push, endfor); | ||
| 483 | check(GET_OPCODE(pt->code[endfor]) == OP_LFORLOOP); | ||
| 484 | check(GETARG_S(pt->code[endfor]) == arg1); | ||
| 485 | break; | 460 | break; |
| 486 | } | 461 | } |
| 487 | case OP_PUSHINT: | 462 | case OP_CLOSURE: { |
| 488 | case OP_GETTABLE: | 463 | check(b < pt->sizekproto); |
| 489 | case OP_CREATETABLE: | 464 | checkreg(pt, a + pt->kproto[b]->nupvalues - 1); |
| 490 | case OP_ADD: | ||
| 491 | case OP_ADDI: | ||
| 492 | case OP_SUB: | ||
| 493 | case OP_MULT: | ||
| 494 | case OP_DIV: | ||
| 495 | case OP_POW: | ||
| 496 | case OP_MINUS: | ||
| 497 | case OP_NOT: { | ||
| 498 | break; | 465 | break; |
| 499 | } | 466 | } |
| 467 | default: break; | ||
| 500 | } | 468 | } |
| 501 | top -= pop; | ||
| 502 | check(0 <= top && top+push <= pt->maxstacksize); | ||
| 503 | while (push--) stack[top++] = pc-1; | ||
| 504 | checkjump(pt, sl, top, pc); | ||
| 505 | } | 469 | } |
| 506 | return (stackpos >= 0) ? pt->code[stack[stackpos]] : 1; | 470 | return pt->code[last]; |
| 507 | } | 471 | } |
| 508 | 472 | ||
| 509 | /* }====================================================== */ | 473 | /* }====================================================== */ |
| 510 | 474 | ||
| 511 | 475 | ||
| 512 | int luaG_checkcode (lua_State *L, const Proto *pt) { | 476 | int luaG_checkcode (const Proto *pt) { |
| 513 | return luaG_symbexec(L, pt, pt->sizecode-1, -1); | 477 | return luaG_symbexec(pt, pt->sizecode, NO_REG); |
| 514 | } | 478 | } |
| 515 | 479 | ||
| 516 | 480 | ||
| 517 | static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) { | 481 | static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) { |
| 518 | CallInfo *ci = ci_stack(L, obj); | 482 | CallInfo *ci = ci_stack(L, obj); |
| 519 | if (!isLmark(ci)) | 483 | if (isLmark(ci)) { /* an active Lua function? */ |
| 520 | return NULL; /* not an active Lua function */ | ||
| 521 | else { | ||
| 522 | Proto *p = ci_func(ci)->f.l; | 484 | Proto *p = ci_func(ci)->f.l; |
| 523 | int pc = currentpc(ci); | 485 | int pc = currentpc(ci); |
| 524 | int stackpos = obj - ci->base; | 486 | int stackpos = obj - ci->base; |
| 525 | Instruction i = luaG_symbexec(L, p, pc, stackpos); | 487 | Instruction i; |
| 488 | *name = luaF_getlocalname(p, stackpos+1, pc); | ||
| 489 | if (*name) /* is a local? */ | ||
| 490 | return l_s("local"); | ||
| 491 | i = luaG_symbexec(p, pc, stackpos); /* try symbolic execution */ | ||
| 526 | lua_assert(pc != -1); | 492 | lua_assert(pc != -1); |
| 527 | switch (GET_OPCODE(i)) { | 493 | switch (GET_OPCODE(i)) { |
| 528 | case OP_GETGLOBAL: { | 494 | case OP_GETGLOBAL: { |
| 529 | *name = getstr(p->kstr[GETARG_U(i)]); | 495 | lua_assert(ttype(&p->k[GETARG_Bc(i)]) == LUA_TSTRING); |
| 496 | *name = getstr(tsvalue(&p->k[GETARG_Bc(i)])); | ||
| 530 | return l_s("global"); | 497 | return l_s("global"); |
| 531 | } | 498 | } |
| 532 | case OP_GETLOCAL: { | 499 | case OP_MOVE: { |
| 533 | *name = luaF_getlocalname(p, GETARG_U(i)+1, pc); | 500 | int a = GETARG_A(i); |
| 534 | lua_assert(*name); | 501 | int b = GETARG_B(i); /* move from `b' to `a' */ |
| 535 | return l_s("local"); | 502 | if (b < a) |
| 503 | return getobjname(L, ci->base+b, name); /* get name for `b' */ | ||
| 504 | break; | ||
| 536 | } | 505 | } |
| 537 | case OP_PUSHSELF: | 506 | case OP_GETTABLE: |
| 538 | case OP_GETDOTTED: { | 507 | case OP_SELF: { |
| 539 | *name = getstr(p->kstr[GETARG_U(i)]); | 508 | int c = GETARG_C(i) - MAXSTACK; |
| 540 | return l_s("field"); | 509 | if (c >= 0 && ttype(&p->k[c]) == LUA_TSTRING) { |
| 510 | *name = getstr(tsvalue(&p->k[c])); | ||
| 511 | return l_s("field"); | ||
| 512 | } | ||
| 513 | break; | ||
| 541 | } | 514 | } |
| 542 | default: | 515 | default: break; |
| 543 | return NULL; /* no useful name found */ | ||
| 544 | } | 516 | } |
| 545 | } | 517 | } |
| 518 | return NULL; /* no useful name found */ | ||
| 546 | } | 519 | } |
| 547 | 520 | ||
| 548 | 521 | ||
| @@ -576,10 +549,18 @@ void luaG_typeerror (lua_State *L, StkId o, const l_char *op) { | |||
| 576 | } | 549 | } |
| 577 | 550 | ||
| 578 | 551 | ||
| 579 | void luaG_binerror (lua_State *L, StkId p1, int t, const l_char *op) { | 552 | void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { |
| 580 | if (ttype(p1) == t) p1++; | 553 | if (ttype(p1) == LUA_TSTRING) p1 = p2; |
| 581 | lua_assert(ttype(p1) != t); | 554 | lua_assert(ttype(p1) != LUA_TSTRING); |
| 582 | luaG_typeerror(L, p1, op); | 555 | luaG_typeerror(L, p1, l_s("concat")); |
| 556 | } | ||
| 557 | |||
| 558 | |||
| 559 | void luaG_aritherror (lua_State *L, StkId p1, TObject *p2) { | ||
| 560 | TObject temp; | ||
| 561 | if (luaV_tonumber(p1, &temp) != NULL) | ||
| 562 | p1 = p2; /* first operand is OK; error is in the second */ | ||
| 563 | luaG_typeerror(L, p1, l_s("perform arithmetic on")); | ||
| 583 | } | 564 | } |
| 584 | 565 | ||
| 585 | 566 | ||
| @@ -592,3 +573,52 @@ void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) { | |||
| 592 | luaO_verror(L, l_s("attempt to compare %.10s with %.10s"), t1, t2); | 573 | luaO_verror(L, l_s("attempt to compare %.10s with %.10s"), t1, t2); |
| 593 | } | 574 | } |
| 594 | 575 | ||
| 576 | |||
| 577 | |||
| 578 | #define opmode(t,a,b,c,sa,k,m) (((t)<<OpModeT) | \ | ||
| 579 | ((a)<<OpModeAreg) | ((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \ | ||
| 580 | ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m)) | ||
| 581 | |||
| 582 | |||
| 583 | const unsigned char luaG_opmodes[] = { | ||
| 584 | /* T A B C sA K mode opcode */ | ||
| 585 | opmode(0,1,1,0, 1,0,iABC), /* OP_MOVE */ | ||
| 586 | opmode(0,1,0,0, 1,1,iABc), /* OP_LOADK */ | ||
| 587 | opmode(0,1,0,0, 1,0,iAsBc), /* OP_LOADINT */ | ||
| 588 | opmode(0,1,1,0, 1,0,iABC), /* OP_LOADNIL */ | ||
| 589 | opmode(0,1,0,0, 1,0,iABc), /* OP_LOADUPVAL */ | ||
| 590 | opmode(0,1,0,0, 1,1,iABc), /* OP_GETGLOBAL */ | ||
| 591 | opmode(0,1,1,1, 1,0,iABC), /* OP_GETTABLE */ | ||
| 592 | opmode(0,1,0,0, 0,1,iABc), /* OP_SETGLOBAL */ | ||
| 593 | opmode(0,1,1,1, 0,0,iABC), /* OP_SETTABLE */ | ||
| 594 | opmode(0,1,0,0, 1,0,iABc), /* OP_NEWTABLE */ | ||
| 595 | opmode(0,1,1,1, 1,0,iABC), /* OP_SELF */ | ||
| 596 | opmode(0,1,1,1, 1,0,iABC), /* OP_ADD */ | ||
| 597 | opmode(0,1,1,1, 1,0,iABC), /* OP_SUB */ | ||
| 598 | opmode(0,1,1,1, 1,0,iABC), /* OP_MUL */ | ||
| 599 | opmode(0,1,1,1, 1,0,iABC), /* OP_DIV */ | ||
| 600 | opmode(0,1,1,1, 1,0,iABC), /* OP_POW */ | ||
| 601 | opmode(0,1,1,0, 1,0,iABC), /* OP_UNM */ | ||
| 602 | opmode(0,1,1,0, 1,0,iABC), /* OP_NOT */ | ||
| 603 | opmode(0,1,1,1, 1,0,iABC), /* OP_CONCAT */ | ||
| 604 | opmode(0,0,0,0, 0,0,iAsBc), /* OP_JMP */ | ||
| 605 | opmode(0,0,0,0, 0,0,iAsBc), /* OP_CJMP */ | ||
| 606 | opmode(1,0,1,1, 0,0,iABC), /* OP_TESTEQ */ | ||
| 607 | opmode(1,0,1,1, 0,0,iABC), /* OP_TESTNE */ | ||
| 608 | opmode(1,0,1,1, 0,0,iABC), /* OP_TESTLT */ | ||
| 609 | opmode(1,0,1,1, 0,0,iABC), /* OP_TESTLE */ | ||
| 610 | opmode(1,0,1,1, 0,0,iABC), /* OP_TESTGT */ | ||
| 611 | opmode(1,0,1,1, 0,0,iABC), /* OP_TESTGE */ | ||
| 612 | opmode(1,0,1,0, 1,0,iABC), /* OP_TESTT */ | ||
| 613 | opmode(1,0,1,0, 1,0,iABC), /* OP_TESTF */ | ||
| 614 | opmode(0,1,0,0, 1,0,iAsBc), /* OP_NILJMP */ | ||
| 615 | opmode(0,1,0,0, 0,0,iABC), /* OP_CALL */ | ||
| 616 | opmode(0,1,0,0, 0,0,iABC), /* OP_RETURN */ | ||
| 617 | opmode(0,1,0,0, 0,0,iAsBc), /* OP_FORPREP */ | ||
| 618 | opmode(0,1,0,0, 0,0,iAsBc), /* OP_FORLOOP */ | ||
| 619 | opmode(0,1,0,0, 0,0,iAsBc), /* OP_TFORPREP */ | ||
| 620 | opmode(0,1,0,0, 0,0,iAsBc), /* OP_TFORLOOP */ | ||
| 621 | opmode(0,1,0,0, 0,0,iABc), /* OP_SETLIST */ | ||
| 622 | opmode(0,1,0,0, 0,0,iABc), /* OP_SETLIST0 */ | ||
| 623 | opmode(0,1,0,0, 0,0,iABc) /* OP_CLOSURE */ | ||
| 624 | }; | ||
