diff options
| -rw-r--r-- | lcode.c | 258 | ||||
| -rw-r--r-- | lcode.h | 10 | ||||
| -rw-r--r-- | lopcodes.h | 4 | ||||
| -rw-r--r-- | lparser.c | 10 | ||||
| -rw-r--r-- | ltests.c | 87 | ||||
| -rw-r--r-- | lvm.c | 4 |
6 files changed, 166 insertions, 207 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.29 2000/05/08 19:32:53 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.30 2000/05/15 19:48:04 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -37,7 +37,7 @@ static Instruction previous_instruction (FuncState *fs) { | |||
| 37 | 37 | ||
| 38 | 38 | ||
| 39 | int luaK_jump (FuncState *fs) { | 39 | int luaK_jump (FuncState *fs) { |
| 40 | int j = luaK_code0(fs, OP_JMP); | 40 | int j = luaK_code1(fs, OP_JMP, NO_JUMP); |
| 41 | if (j == fs->lasttarget) { /* possible jumps to this jump? */ | 41 | if (j == fs->lasttarget) { /* possible jumps to this jump? */ |
| 42 | luaK_concat(fs, &j, fs->jlt); /* keep them on hold */ | 42 | luaK_concat(fs, &j, fs->jlt); /* keep them on hold */ |
| 43 | fs->jlt = NO_JUMP; | 43 | fs->jlt = NO_JUMP; |
| @@ -279,7 +279,7 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) { | |||
| 279 | SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); | 279 | SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); |
| 280 | } | 280 | } |
| 281 | else | 281 | else |
| 282 | luaK_code0(fs, jump); | 282 | luaK_code1(fs, jump, NO_JUMP); |
| 283 | luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */ | 283 | luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */ |
| 284 | luaK_patchlist(fs, *golist, luaK_getlabel(fs)); | 284 | luaK_patchlist(fs, *golist, luaK_getlabel(fs)); |
| 285 | *golist = NO_JUMP; | 285 | *golist = NO_JUMP; |
| @@ -324,10 +324,11 @@ void luaK_tostack (LexState *ls, expdesc *v, int onlyone) { | |||
| 324 | if (ISJUMP(previous)) | 324 | if (ISJUMP(previous)) |
| 325 | luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in t. list */ | 325 | luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in t. list */ |
| 326 | else { | 326 | else { |
| 327 | j = code_label(fs, OP_JMP, 0); /* to jump over both pushes */ | 327 | j = code_label(fs, OP_JMP, NO_JUMP); /* to jump over both pushes */ |
| 328 | luaK_deltastack(fs, -1); /* next PUSHes may be skipped */ | 328 | luaK_deltastack(fs, -1); /* next PUSHes may be skipped */ |
| 329 | } | 329 | } |
| 330 | p_nil = code_label(fs, OP_PUSHNILJMP, 0); | 330 | p_nil = code_label(fs, OP_PUSHNILJMP, 0); |
| 331 | luaK_deltastack(fs, -1); /* next PUSH is skipped */ | ||
| 331 | p_1 = code_label(fs, OP_PUSHINT, 1); | 332 | p_1 = code_label(fs, OP_PUSHINT, 1); |
| 332 | luaK_patchlist(fs, j, luaK_getlabel(fs)); | 333 | luaK_patchlist(fs, j, luaK_getlabel(fs)); |
| 333 | } | 334 | } |
| @@ -394,12 +395,12 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) { | |||
| 394 | case '/': luaK_code0(fs, OP_DIV); break; | 395 | case '/': luaK_code0(fs, OP_DIV); break; |
| 395 | case '^': luaK_code0(fs, OP_POW); break; | 396 | case '^': luaK_code0(fs, OP_POW); break; |
| 396 | case TK_CONCAT: luaK_code1(fs, OP_CONCAT, 2); break; | 397 | case TK_CONCAT: luaK_code1(fs, OP_CONCAT, 2); break; |
| 397 | case TK_EQ: luaK_code0(fs, OP_JMPEQ); break; | 398 | case TK_EQ: luaK_code1(fs, OP_JMPEQ, NO_JUMP); break; |
| 398 | case TK_NE: luaK_code0(fs, OP_JMPNE); break; | 399 | case TK_NE: luaK_code1(fs, OP_JMPNE, NO_JUMP); break; |
| 399 | case '>': luaK_code0(fs, OP_JMPGT); break; | 400 | case '>': luaK_code1(fs, OP_JMPGT, NO_JUMP); break; |
| 400 | case '<': luaK_code0(fs, OP_JMPLT); break; | 401 | case '<': luaK_code1(fs, OP_JMPLT, NO_JUMP); break; |
| 401 | case TK_GE: luaK_code0(fs, OP_JMPGE); break; | 402 | case TK_GE: luaK_code1(fs, OP_JMPGE, NO_JUMP); break; |
| 402 | case TK_LE: luaK_code0(fs, OP_JMPLE); break; | 403 | case TK_LE: luaK_code1(fs, OP_JMPLE, NO_JUMP); break; |
| 403 | } | 404 | } |
| 404 | } | 405 | } |
| 405 | } | 406 | } |
| @@ -415,196 +416,120 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1) { | |||
| 415 | } | 416 | } |
| 416 | 417 | ||
| 417 | 418 | ||
| 419 | #define VD 100 /* flag for variable delta */ | ||
| 420 | |||
| 418 | 421 | ||
| 419 | int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | 422 | int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { |
| 420 | Instruction i = previous_instruction(fs); | 423 | Instruction i = previous_instruction(fs); |
| 421 | int delta = 0; | 424 | int delta = luaK_opproperties[o].delta; |
| 422 | enum {iO, iU, iS, iAB, iP} mode; /* instruction format (or iP to optimize) */ | 425 | int optm = 0; /* 1 when there is an optimization */ |
| 423 | mode = iP; | ||
| 424 | |||
| 425 | switch (o) { | 426 | switch (o) { |
| 426 | 427 | ||
| 427 | case OP_CLOSURE: | 428 | case OP_CLOSURE: |
| 428 | delta = -arg2+1; | 429 | delta = -arg2+1; |
| 429 | mode = iAB; | ||
| 430 | break; | ||
| 431 | |||
| 432 | case OP_SETLINE: | ||
| 433 | mode = iU; | ||
| 434 | break; | ||
| 435 | |||
| 436 | case OP_CALL: | ||
| 437 | mode = iAB; | ||
| 438 | break; | ||
| 439 | |||
| 440 | case OP_PUSHINT: | ||
| 441 | delta = 1; | ||
| 442 | mode = iS; | ||
| 443 | break; | 430 | break; |
| 444 | 431 | ||
| 445 | case OP_SETTABLE: | 432 | case OP_SETTABLE: |
| 446 | delta = -arg2; | ||
| 447 | mode = iAB; | ||
| 448 | break; | ||
| 449 | |||
| 450 | case OP_SETLIST: | 433 | case OP_SETLIST: |
| 451 | delta = -(arg2+1); | 434 | delta = -arg2; |
| 452 | mode = iAB; | ||
| 453 | break; | 435 | break; |
| 454 | 436 | ||
| 455 | case OP_SETMAP: | 437 | case OP_SETMAP: |
| 456 | delta = -2*(arg1+1); | 438 | delta = -2*(arg1+1); |
| 457 | mode = iU; | ||
| 458 | break; | ||
| 459 | |||
| 460 | case OP_FORLOOP: | ||
| 461 | delta = -3; | ||
| 462 | arg1 = NO_JUMP; | ||
| 463 | mode = iS; | ||
| 464 | break; | ||
| 465 | |||
| 466 | case OP_SETLOCAL: | ||
| 467 | case OP_SETGLOBAL: | ||
| 468 | delta = -1; | ||
| 469 | mode = iU; | ||
| 470 | break; | ||
| 471 | |||
| 472 | case OP_FORPREP: | ||
| 473 | case OP_JMP: | ||
| 474 | arg1 = NO_JUMP; | ||
| 475 | mode = iS; | ||
| 476 | break; | ||
| 477 | |||
| 478 | case OP_LFORPREP: | ||
| 479 | delta = 3; | ||
| 480 | arg1 = NO_JUMP; | ||
| 481 | mode = iS; | ||
| 482 | break; | ||
| 483 | |||
| 484 | case OP_LFORLOOP: | ||
| 485 | delta = -4; | ||
| 486 | arg1 = NO_JUMP; | ||
| 487 | mode = iS; | ||
| 488 | break; | ||
| 489 | |||
| 490 | case OP_END: | ||
| 491 | case OP_PUSHNILJMP: | ||
| 492 | case OP_NOT: | ||
| 493 | mode = iO; | ||
| 494 | break; | ||
| 495 | |||
| 496 | case OP_PUSHSTRING: | ||
| 497 | case OP_PUSHNUM: | ||
| 498 | case OP_PUSHNEGNUM: | ||
| 499 | case OP_PUSHUPVALUE: | ||
| 500 | case OP_GETLOCAL: | ||
| 501 | case OP_GETGLOBAL: | ||
| 502 | case OP_PUSHSELF: | ||
| 503 | case OP_CREATETABLE: | ||
| 504 | delta = 1; | ||
| 505 | mode = iU; | ||
| 506 | break; | ||
| 507 | |||
| 508 | case OP_JMPLT: | ||
| 509 | case OP_JMPLE: | ||
| 510 | case OP_JMPGT: | ||
| 511 | case OP_JMPGE: | ||
| 512 | delta = -2; | ||
| 513 | arg1 = NO_JUMP; | ||
| 514 | mode = iS; | ||
| 515 | break; | ||
| 516 | |||
| 517 | case OP_MULT: | ||
| 518 | case OP_DIV: | ||
| 519 | case OP_POW: | ||
| 520 | delta = -1; | ||
| 521 | mode = iO; | ||
| 522 | break; | 439 | break; |
| 523 | 440 | ||
| 524 | case OP_RETURN: | 441 | case OP_RETURN: |
| 525 | if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) { | 442 | if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) { |
| 526 | SET_OPCODE(i, OP_TAILCALL); | 443 | SET_OPCODE(i, OP_TAILCALL); |
| 527 | SETARG_B(i, arg1); | 444 | SETARG_B(i, arg1); |
| 445 | optm = 1; | ||
| 528 | } | 446 | } |
| 529 | else mode = iU; | ||
| 530 | break; | 447 | break; |
| 531 | 448 | ||
| 532 | case OP_PUSHNIL: | 449 | case OP_PUSHNIL: |
| 533 | delta = arg1; | 450 | delta = arg1; |
| 534 | switch(GET_OPCODE(i)) { | 451 | switch(GET_OPCODE(i)) { |
| 535 | case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); break; | 452 | case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; |
| 536 | default: mode = iU; break; | 453 | default: break; |
| 537 | } | 454 | } |
| 538 | break; | 455 | break; |
| 539 | 456 | ||
| 540 | case OP_POP: | 457 | case OP_POP: |
| 541 | delta = -arg1; | 458 | delta = -arg1; |
| 542 | switch(GET_OPCODE(i)) { | 459 | switch(GET_OPCODE(i)) { |
| 543 | case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); break; | 460 | case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; |
| 544 | default: mode = iU; break; | 461 | default: break; |
| 545 | } | 462 | } |
| 546 | break; | 463 | break; |
| 547 | 464 | ||
| 548 | case OP_GETTABLE: | 465 | case OP_GETTABLE: |
| 549 | delta = -1; | ||
| 550 | switch(GET_OPCODE(i)) { | 466 | switch(GET_OPCODE(i)) { |
| 551 | case OP_PUSHSTRING: SET_OPCODE(i, OP_GETDOTTED); break; /* `t.x' */ | 467 | case OP_PUSHSTRING: /* `t.x' */ |
| 552 | case OP_GETLOCAL: SET_OPCODE(i, OP_GETINDEXED); break; /* `t[i]' */ | 468 | SET_OPCODE(i, OP_GETDOTTED); |
| 553 | default: mode = iO; break; | 469 | optm = 1; |
| 470 | break; | ||
| 471 | case OP_GETLOCAL: /* `t[i]' */ | ||
| 472 | SET_OPCODE(i, OP_GETINDEXED); | ||
| 473 | optm = 1; | ||
| 474 | break; | ||
| 475 | default: break; | ||
| 554 | } | 476 | } |
| 555 | break; | 477 | break; |
| 556 | 478 | ||
| 557 | case OP_ADD: | 479 | case OP_ADD: |
| 558 | delta = -1; | ||
| 559 | switch(GET_OPCODE(i)) { | 480 | switch(GET_OPCODE(i)) { |
| 560 | case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); break; /* `a+k' */ | 481 | case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); optm = 1; break; /* `a+k' */ |
| 561 | default: mode = iO; break; | 482 | default: break; |
| 562 | } | 483 | } |
| 563 | break; | 484 | break; |
| 564 | 485 | ||
| 565 | case OP_SUB: | 486 | case OP_SUB: |
| 566 | delta = -1; | ||
| 567 | switch(GET_OPCODE(i)) { | 487 | switch(GET_OPCODE(i)) { |
| 568 | case OP_PUSHINT: i = CREATE_S(OP_ADDI, -GETARG_S(i)); break; /* `a-k' */ | 488 | case OP_PUSHINT: /* `a-k' */ |
| 569 | default: mode = iO; break; | 489 | i = CREATE_S(OP_ADDI, -GETARG_S(i)); |
| 490 | optm = 1; | ||
| 491 | break; | ||
| 492 | default: break; | ||
| 570 | } | 493 | } |
| 571 | break; | 494 | break; |
| 572 | 495 | ||
| 573 | case OP_CONCAT: | 496 | case OP_CONCAT: |
| 574 | delta = -arg1+1; | 497 | delta = -arg1+1; |
| 575 | switch(GET_OPCODE(i)) { | 498 | switch(GET_OPCODE(i)) { |
| 576 | case OP_CONCAT: SETARG_U(i, GETARG_U(i)+1); break; /* `a..b..c' */ | 499 | case OP_CONCAT: /* `a..b..c' */ |
| 577 | default: mode = iU; break; | 500 | SETARG_U(i, GETARG_U(i)+1); |
| 501 | optm = 1; | ||
| 502 | break; | ||
| 503 | default: break; | ||
| 578 | } | 504 | } |
| 579 | break; | 505 | break; |
| 580 | 506 | ||
| 581 | case OP_MINUS: | 507 | case OP_MINUS: |
| 582 | switch(GET_OPCODE(i)) { | 508 | switch(GET_OPCODE(i)) { |
| 583 | case OP_PUSHINT: SETARG_S(i, -GETARG_S(i)); break; /* `-k' */ | 509 | case OP_PUSHINT: /* `-k' */ |
| 584 | case OP_PUSHNUM: SET_OPCODE(i, OP_PUSHNEGNUM); break; /* `-k' */ | 510 | SETARG_S(i, -GETARG_S(i)); |
| 585 | default: mode = iO; break; | 511 | optm = 1; |
| 512 | break; | ||
| 513 | case OP_PUSHNUM: /* `-k' */ | ||
| 514 | SET_OPCODE(i, OP_PUSHNEGNUM); | ||
| 515 | optm = 1; | ||
| 516 | break; | ||
| 517 | default: break; | ||
| 586 | } | 518 | } |
| 587 | break; | 519 | break; |
| 588 | 520 | ||
| 589 | case OP_JMPNE: | 521 | case OP_JMPNE: |
| 590 | delta = -2; | 522 | if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a~=nil' */ |
| 591 | if (i == CREATE_U(OP_PUSHNIL, 1)) /* `a~=nil' */ | ||
| 592 | i = CREATE_S(OP_JMPT, NO_JUMP); | 523 | i = CREATE_S(OP_JMPT, NO_JUMP); |
| 593 | else { | 524 | optm = 1; |
| 594 | arg1 = NO_JUMP; | ||
| 595 | mode = iS; | ||
| 596 | } | 525 | } |
| 597 | break; | 526 | break; |
| 598 | 527 | ||
| 599 | case OP_JMPEQ: | 528 | case OP_JMPEQ: |
| 600 | delta = -2; | ||
| 601 | if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */ | 529 | if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */ |
| 602 | i = CREATE_0(OP_NOT); | 530 | i = CREATE_0(OP_NOT); |
| 603 | delta = -1; /* just undo effect of previous PUSHNIL */ | 531 | delta = -1; /* just undo effect of previous PUSHNIL */ |
| 604 | } | 532 | optm = 1; |
| 605 | else { | ||
| 606 | arg1 = NO_JUMP; | ||
| 607 | mode = iS; | ||
| 608 | } | 533 | } |
| 609 | break; | 534 | break; |
| 610 | 535 | ||
| @@ -612,11 +537,9 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 612 | case OP_JMPF: | 537 | case OP_JMPF: |
| 613 | case OP_JMPONT: | 538 | case OP_JMPONT: |
| 614 | case OP_JMPONF: | 539 | case OP_JMPONF: |
| 615 | delta = -1; | ||
| 616 | arg1 = NO_JUMP; | ||
| 617 | switch (GET_OPCODE(i)) { | 540 | switch (GET_OPCODE(i)) { |
| 618 | case OP_NOT: i = CREATE_S(invertjump(o), NO_JUMP); break; | 541 | case OP_NOT: i = CREATE_S(invertjump(o), NO_JUMP); optm = 1; break; |
| 619 | default: mode = iS; break; | 542 | default: break; |
| 620 | } | 543 | } |
| 621 | break; | 544 | break; |
| 622 | 545 | ||
| @@ -625,19 +548,23 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 625 | case OP_TAILCALL: | 548 | case OP_TAILCALL: |
| 626 | case OP_ADDI: | 549 | case OP_ADDI: |
| 627 | LUA_INTERNALERROR(L, "instruction used only for optimizations"); | 550 | LUA_INTERNALERROR(L, "instruction used only for optimizations"); |
| 628 | return 0; /* to avoid warnings */ | 551 | break; |
| 552 | |||
| 553 | default: | ||
| 554 | LUA_ASSERT(L, delta != VD, "invalid delta"); | ||
| 555 | break; | ||
| 629 | 556 | ||
| 630 | } | 557 | } |
| 631 | luaK_deltastack(fs, delta); | 558 | luaK_deltastack(fs, delta); |
| 632 | switch (mode) { /* handle instruction formats */ | 559 | if (optm) { /* optimize: put instruction in place of last one */ |
| 560 | fs->f->code[fs->pc-1] = i; /* change previous instruction */ | ||
| 561 | return fs->pc-1; /* do not generate new instruction */ | ||
| 562 | } | ||
| 563 | switch ((enum Mode)luaK_opproperties[o].mode) { | ||
| 633 | case iO: i = CREATE_0(o); break; | 564 | case iO: i = CREATE_0(o); break; |
| 634 | case iU: i = CREATE_U(o, arg1); break; | 565 | case iU: i = CREATE_U(o, arg1); break; |
| 635 | case iS: i = CREATE_S(o, arg1); break; | 566 | case iS: i = CREATE_S(o, arg1); break; |
| 636 | case iAB: i = CREATE_AB(o, arg1, arg2); break; | 567 | case iAB: i = CREATE_AB(o, arg1, arg2); break; |
| 637 | case iP: { /* optimize: put instruction in place of last one */ | ||
| 638 | fs->f->code[fs->pc-1] = i; /* change previous instruction */ | ||
| 639 | return fs->pc-1; | ||
| 640 | } | ||
| 641 | } | 568 | } |
| 642 | /* actually create the new instruction */ | 569 | /* actually create the new instruction */ |
| 643 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT); | 570 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT); |
| @@ -645,3 +572,56 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 645 | return fs->pc++; | 572 | return fs->pc++; |
| 646 | } | 573 | } |
| 647 | 574 | ||
| 575 | |||
| 576 | const struct OpProperties luaK_opproperties[OP_SETLINE+1] = { | ||
| 577 | {iO, 0}, /* OP_END */ | ||
| 578 | {iU, 0}, /* OP_RETURN */ | ||
| 579 | {iAB, 0}, /* OP_CALL */ | ||
| 580 | {iAB, 0}, /* OP_TAILCALL */ | ||
| 581 | {iU, VD}, /* OP_PUSHNIL */ | ||
| 582 | {iU, VD}, /* OP_POP */ | ||
| 583 | {iS, 1}, /* OP_PUSHINT */ | ||
| 584 | {iU, 1}, /* OP_PUSHSTRING */ | ||
| 585 | {iU, 1}, /* OP_PUSHNUM */ | ||
| 586 | {iU, 1}, /* OP_PUSHNEGNUM */ | ||
| 587 | {iU, 1}, /* OP_PUSHUPVALUE */ | ||
| 588 | {iU, 1}, /* OP_GETLOCAL */ | ||
| 589 | {iU, 1}, /* OP_GETGLOBAL */ | ||
| 590 | {iO, -1}, /* OP_GETTABLE */ | ||
| 591 | {iU, 0}, /* OP_GETDOTTED */ | ||
| 592 | {iU, 0}, /* OP_GETINDEXED */ | ||
| 593 | {iU, 1}, /* OP_PUSHSELF */ | ||
| 594 | {iU, 1}, /* OP_CREATETABLE */ | ||
| 595 | {iU, -1}, /* OP_SETLOCAL */ | ||
| 596 | {iU, -1}, /* OP_SETGLOBAL */ | ||
| 597 | {iAB, VD}, /* OP_SETTABLE */ | ||
| 598 | {iAB, VD}, /* OP_SETLIST */ | ||
| 599 | {iU, VD}, /* OP_SETMAP */ | ||
| 600 | {iO, -1}, /* OP_ADD */ | ||
| 601 | {iS, 0}, /* OP_ADDI */ | ||
| 602 | {iO, -1}, /* OP_SUB */ | ||
| 603 | {iO, -1}, /* OP_MULT */ | ||
| 604 | {iO, -1}, /* OP_DIV */ | ||
| 605 | {iO, -1}, /* OP_POW */ | ||
| 606 | {iU, VD}, /* OP_CONCAT */ | ||
| 607 | {iO, 0}, /* OP_MINUS */ | ||
| 608 | {iO, 0}, /* OP_NOT */ | ||
| 609 | {iS, -2}, /* OP_JMPNE */ | ||
| 610 | {iS, -2}, /* OP_JMPEQ */ | ||
| 611 | {iS, -2}, /* OP_JMPLT */ | ||
| 612 | {iS, -2}, /* OP_JMPLE */ | ||
| 613 | {iS, -2}, /* OP_JMPGT */ | ||
| 614 | {iS, -2}, /* OP_JMPGE */ | ||
| 615 | {iS, -1}, /* OP_JMPT */ | ||
| 616 | {iS, -1}, /* OP_JMPF */ | ||
| 617 | {iS, -1}, /* OP_JMPONT */ | ||
| 618 | {iS, -1}, /* OP_JMPONF */ | ||
| 619 | {iS, 0}, /* OP_JMP */ | ||
| 620 | {iO, 1}, /* OP_PUSHNILJMP */ | ||
| 621 | {iS, 0}, /* OP_FORPREP */ | ||
| 622 | {iS, -3}, /* OP_FORLOOP */ | ||
| 623 | {iS, 3}, /* OP_LFORPREP */ | ||
| 624 | {iS, -4}, /* OP_LFORLOOP */ | ||
| 625 | {iAB, VD}, /* OP_CLOSURE */ | ||
| 626 | {iU, 0} /* OP_SETLINE */ | ||
| 627 | }; | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.h,v 1.11 2000/04/07 19:35:20 roberto Exp roberto $ | 2 | ** $Id: lcode.h,v 1.12 2000/04/12 18:47:03 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -20,6 +20,14 @@ | |||
| 20 | #define NO_JUMP (-1) | 20 | #define NO_JUMP (-1) |
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | enum Mode {iO, iU, iS, iAB}; /* instruction format */ | ||
| 24 | |||
| 25 | extern const struct OpProperties { | ||
| 26 | char mode; | ||
| 27 | signed char delta; | ||
| 28 | } luaK_opproperties[]; | ||
| 29 | |||
| 30 | |||
| 23 | void luaK_error (LexState *ls, const char *msg); | 31 | void luaK_error (LexState *ls, const char *msg); |
| 24 | int luaK_code0 (FuncState *fs, OpCode o); | 32 | int luaK_code0 (FuncState *fs, OpCode o); |
| 25 | int luaK_code1 (FuncState *fs, OpCode o, int arg1); | 33 | int luaK_code1 (FuncState *fs, OpCode o, int arg1); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.60 2000/04/27 17:39:15 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.61 2000/05/15 19:48:04 roberto Exp roberto $ |
| 3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -112,7 +112,7 @@ OP_SETLOCAL,/* L x - LOC[l]=x */ | |||
| 112 | OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */ | 112 | OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */ |
| 113 | OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ | 113 | OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ |
| 114 | 114 | ||
| 115 | OP_SETLIST,/* A B v_b-v_0 t t t[i+a*FPF]=v_i */ | 115 | OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */ |
| 116 | OP_SETMAP,/* U v_u k_u - v_0 k_0 t t t[k_i]=v_i */ | 116 | OP_SETMAP,/* U v_u k_u - v_0 k_0 t t t[k_i]=v_i */ |
| 117 | 117 | ||
| 118 | OP_ADD,/* - y x x+y */ | 118 | OP_ADD,/* - y x x+y */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.86 2000/05/12 18:12:04 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.87 2000/05/15 19:48:04 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -626,12 +626,12 @@ static int listfields (LexState *ls) { | |||
| 626 | checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH, | 626 | checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH, |
| 627 | "items in a list initializer"); | 627 | "items in a list initializer"); |
| 628 | if (++mod_n == LFIELDS_PER_FLUSH) { | 628 | if (++mod_n == LFIELDS_PER_FLUSH) { |
| 629 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH-1); | 629 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); |
| 630 | mod_n = 0; | 630 | mod_n = 0; |
| 631 | } | 631 | } |
| 632 | } | 632 | } |
| 633 | if (mod_n > 0) | 633 | if (mod_n > 0) |
| 634 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, mod_n-1); | 634 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, mod_n); |
| 635 | return n; | 635 | return n; |
| 636 | } | 636 | } |
| 637 | 637 | ||
| @@ -911,12 +911,12 @@ static void repeatstat (LexState *ls, int line) { | |||
| 911 | 911 | ||
| 912 | static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { | 912 | static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { |
| 913 | FuncState *fs = ls->fs; | 913 | FuncState *fs = ls->fs; |
| 914 | int prep = luaK_code0(fs, prepfor); | 914 | int prep = luaK_code1(fs, prepfor, NO_JUMP); |
| 915 | int blockinit = luaK_getlabel(fs); | 915 | int blockinit = luaK_getlabel(fs); |
| 916 | check(ls, TK_DO); | 916 | check(ls, TK_DO); |
| 917 | block(ls); | 917 | block(ls); |
| 918 | luaK_patchlist(fs, prep, luaK_getlabel(fs)); | 918 | luaK_patchlist(fs, prep, luaK_getlabel(fs)); |
| 919 | luaK_patchlist(fs, luaK_code0(fs, loopfor), blockinit); | 919 | luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); |
| 920 | } | 920 | } |
| 921 | 921 | ||
| 922 | 922 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 1.18 2000/05/10 16:33:20 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.19 2000/05/15 19:48:04 roberto Exp roberto $ |
| 3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -14,6 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | #include "lapi.h" | 15 | #include "lapi.h" |
| 16 | #include "lauxlib.h" | 16 | #include "lauxlib.h" |
| 17 | #include "lcode.h" | ||
| 17 | #include "ldo.h" | 18 | #include "ldo.h" |
| 18 | #include "lmem.h" | 19 | #include "lmem.h" |
| 19 | #include "lopcodes.h" | 20 | #include "lopcodes.h" |
| @@ -49,71 +50,41 @@ static void setnameval (lua_State *L, lua_Object t, const char *name, int val) { | |||
| 49 | */ | 50 | */ |
| 50 | 51 | ||
| 51 | 52 | ||
| 52 | #define O(o) sprintf(buff, "%s", o) | 53 | static const char *const instrname[OP_SETLINE+1] = { |
| 53 | #define U(o) sprintf(buff, "%-12s%4u", o, GETARG_U(i)) | 54 | "END", "RETURN", "CALL", "TAILCALL", "PUSHNIL", "POP", "PUSHINT", |
| 54 | #define S(o) sprintf(buff, "%-12s%4d", o, GETARG_S(i)) | 55 | "PUSHSTRING", "PUSHNUM", "PUSHNEGNUM", "PUSHUPVALUE", "GETLOCAL", |
| 55 | #define AB(o) sprintf(buff, "%-12s%4d %4d", o, GETARG_A(i), GETARG_B(i)) | 56 | "GETGLOBAL", "GETTABLE", "GETDOTTED", "GETINDEXED", "PUSHSELF", |
| 56 | 57 | "CREATETABLE", "SETLOCAL", "SETGLOBAL", "SETTABLE", "SETLIST", "SETMAP", | |
| 58 | "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT", | ||
| 59 | "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF", | ||
| 60 | "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP", | ||
| 61 | "LFORLOOP", "CLOSURE", "SETLINE" | ||
| 62 | }; | ||
| 57 | 63 | ||
| 58 | 64 | ||
| 59 | static int pushop (lua_State *L, Instruction i) { | 65 | static int pushop (lua_State *L, Instruction i) { |
| 60 | char buff[100]; | 66 | char buff[100]; |
| 61 | switch (GET_OPCODE(i)) { | 67 | OpCode o = GET_OPCODE(i); |
| 62 | case OP_END: O("END"); lua_pushstring(L, buff); return 0; | 68 | const char *name = instrname[o]; |
| 63 | case OP_RETURN: U("RETURN"); break; | 69 | switch ((enum Mode)luaK_opproperties[o].mode) { |
| 64 | case OP_CALL: AB("CALL"); break; | 70 | case iO: |
| 65 | case OP_TAILCALL: AB("TAILCALL"); break; | 71 | sprintf(buff, "%s", name); |
| 66 | case OP_PUSHNIL: U("PUSHNIL"); break; | 72 | break; |
| 67 | case OP_POP: U("POP"); break; | 73 | case iU: |
| 68 | case OP_PUSHINT: S("PUSHINT"); break; | 74 | sprintf(buff, "%-12s%4u", name, GETARG_U(i)); |
| 69 | case OP_PUSHSTRING: U("PUSHSTRING"); break; | 75 | break; |
| 70 | case OP_PUSHNUM: U("PUSHNUM"); break; | 76 | case iS: |
| 71 | case OP_PUSHNEGNUM: U("PUSHNEGNUM"); break; | 77 | sprintf(buff, "%-12s%4d", name, GETARG_S(i)); |
| 72 | case OP_PUSHUPVALUE: U("PUSHUPVALUE"); break; | 78 | break; |
| 73 | case OP_GETLOCAL: U("GETLOCAL"); break; | 79 | case iAB: |
| 74 | case OP_GETGLOBAL: U("GETGLOBAL"); break; | 80 | sprintf(buff, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i)); |
| 75 | case OP_GETTABLE: O("GETTABLE"); break; | 81 | break; |
| 76 | case OP_GETDOTTED: U("GETDOTTED"); break; | ||
| 77 | case OP_GETINDEXED: U("GETINDEXED"); break; | ||
| 78 | case OP_PUSHSELF: U("PUSHSELF"); break; | ||
| 79 | case OP_CREATETABLE: U("CREATETABLE"); break; | ||
| 80 | case OP_SETLOCAL: U("SETLOCAL"); break; | ||
| 81 | case OP_SETGLOBAL: U("SETGLOBAL"); break; | ||
| 82 | case OP_SETTABLE: AB("SETTABLE"); break; | ||
| 83 | case OP_SETLIST: AB("SETLIST"); break; | ||
| 84 | case OP_SETMAP: U("SETMAP"); break; | ||
| 85 | case OP_ADD: O("ADD"); break; | ||
| 86 | case OP_ADDI: S("ADDI"); break; | ||
| 87 | case OP_SUB: O("SUB"); break; | ||
| 88 | case OP_MULT: O("MULT"); break; | ||
| 89 | case OP_DIV: O("DIV"); break; | ||
| 90 | case OP_POW: O("POW"); break; | ||
| 91 | case OP_CONCAT: U("CONCAT"); break; | ||
| 92 | case OP_MINUS: O("MINUS"); break; | ||
| 93 | case OP_NOT: O("NOT"); break; | ||
| 94 | case OP_JMPNE: S("JMPNE"); break; | ||
| 95 | case OP_JMPEQ: S("JMPEQ"); break; | ||
| 96 | case OP_JMPLT: S("JMPLT"); break; | ||
| 97 | case OP_JMPLE: S("JMPLE"); break; | ||
| 98 | case OP_JMPGT: S("JMPGT"); break; | ||
| 99 | case OP_JMPGE: S("JMPGE"); break; | ||
| 100 | case OP_JMPT: S("JMPT"); break; | ||
| 101 | case OP_JMPF: S("JMPF"); break; | ||
| 102 | case OP_JMPONT: S("JMPONT"); break; | ||
| 103 | case OP_JMPONF: S("JMPONF"); break; | ||
| 104 | case OP_JMP: S("JMP"); break; | ||
| 105 | case OP_PUSHNILJMP: O("PUSHNILJMP"); break; | ||
| 106 | case OP_FORPREP: S("FORPREP"); break; | ||
| 107 | case OP_FORLOOP: S("FORLOOP"); break; | ||
| 108 | case OP_LFORPREP: S("LFORPREP"); break; | ||
| 109 | case OP_LFORLOOP: S("LFORLOOP"); break; | ||
| 110 | case OP_CLOSURE: AB("CLOSURE"); break; | ||
| 111 | case OP_SETLINE: U("SETLINE"); break; | ||
| 112 | } | 82 | } |
| 113 | lua_pushstring(L, buff); | 83 | lua_pushstring(L, buff); |
| 114 | return 1; | 84 | return (o != OP_END); |
| 115 | } | 85 | } |
| 116 | 86 | ||
| 87 | |||
| 117 | static void listcode (lua_State *L) { | 88 | static void listcode (lua_State *L) { |
| 118 | lua_Object o = luaL_nonnullarg(L, 1); | 89 | lua_Object o = luaL_nonnullarg(L, 1); |
| 119 | lua_Object t = lua_createtable(L); | 90 | lua_Object t = lua_createtable(L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.105 2000/05/08 19:32:53 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.106 2000/05/15 19:48:04 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -470,7 +470,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 470 | 470 | ||
| 471 | case OP_SETLIST: { | 471 | case OP_SETLIST: { |
| 472 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; | 472 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; |
| 473 | int n = GETARG_B(i)+1; | 473 | int n = GETARG_B(i); |
| 474 | Hash *arr = avalue(top-n-1); | 474 | Hash *arr = avalue(top-n-1); |
| 475 | L->top = top-n; /* final value of `top' (in case of errors) */ | 475 | L->top = top-n; /* final value of `top' (in case of errors) */ |
| 476 | for (; n; n--) | 476 | for (; n; n--) |
