diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-10-01 17:05:34 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-10-01 17:05:34 -0300 |
| commit | 28d47a0aaa646f8762085cc7fcf8953b62df0927 (patch) | |
| tree | be44656bb1a639f82c24a013f0f9d44de22f77e0 | |
| parent | eb617df2d87f8476e722ade7319998d7912a6edf (diff) | |
| download | lua-28d47a0aaa646f8762085cc7fcf8953b62df0927.tar.gz lua-28d47a0aaa646f8762085cc7fcf8953b62df0927.tar.bz2 lua-28d47a0aaa646f8762085cc7fcf8953b62df0927.zip | |
all jumps have byte variants; WHILE optimization
Diffstat (limited to '')
| -rw-r--r-- | lopcodes.h | 9 | ||||
| -rw-r--r-- | lua.stx | 129 | ||||
| -rw-r--r-- | lvm.c | 64 |
3 files changed, 126 insertions, 76 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.5 1997/09/24 19:43:11 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 | */ |
| @@ -76,6 +76,7 @@ GETTABLE,/* i t t[i] */ | |||
| 76 | PUSHSELFB,/* b t t t[CNST[b]] */ | 76 | PUSHSELFB,/* b t t t[CNST[b]] */ |
| 77 | PUSHSELF,/* w t t t[CNST[w]] */ | 77 | PUSHSELF,/* w t t t[CNST[w]] */ |
| 78 | 78 | ||
| 79 | CREATEARRAYB,/* b - newarray(size = b) */ | ||
| 79 | CREATEARRAY,/* w - newarray(size = w) */ | 80 | CREATEARRAY,/* w - newarray(size = w) */ |
| 80 | 81 | ||
| 81 | SETLOCAL0,/* x - LOC[0]=x */ | 82 | SETLOCAL0,/* x - LOC[0]=x */ |
| @@ -118,10 +119,12 @@ NOTOP,/* x (x==nil)? 1 : nil */ | |||
| 118 | /* NOTICE: all jumps are relative to the position following the opcode */ | 119 | /* NOTICE: all jumps are relative to the position following the opcode */ |
| 119 | ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */ | 120 | ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */ |
| 120 | ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */ | 121 | ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */ |
| 122 | JMPB,/* b - - PC+=b */ | ||
| 121 | JMP,/* w - - PC+=w */ | 123 | JMP,/* w - - PC+=w */ |
| 122 | UPJMPB,/* b - - PC-=b */ | 124 | IFFJMPB,/* b x - (x==nil)? PC+=b */ |
| 123 | UPJMP,/* w - - PC-=w */ | ||
| 124 | IFFJMP,/* w x - (x==nil)? PC+=w */ | 125 | IFFJMP,/* w x - (x==nil)? PC+=w */ |
| 126 | IFTUPJMPB,/* b x - (x!=nil)? PC-=b */ | ||
| 127 | IFTUPJMP,/* w x - (x!=nil)? PC-=w */ | ||
| 125 | IFFUPJMPB,/* b x - (x==nil)? PC-=b */ | 128 | IFFUPJMPB,/* b x - (x==nil)? PC-=b */ |
| 126 | IFFUPJMP,/* w x - (x==nil)? PC-=w */ | 129 | IFFUPJMP,/* w x - (x==nil)? PC-=w */ |
| 127 | 130 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | %{ | 1 | %{ |
| 2 | /* | 2 | /* |
| 3 | ** $Id: lua.stx,v 1.5 1997/09/24 19:43:11 roberto Exp roberto $ | 3 | ** $Id: lua.stx,v 1.6 1997/09/26 15:02:26 roberto Exp roberto $ |
| 4 | ** Syntax analizer and code generator | 4 | ** Syntax analizer and code generator |
| 5 | ** See Copyright Notice in lua.h | 5 | ** See Copyright Notice in lua.h |
| 6 | */ | 6 | */ |
| @@ -28,6 +28,9 @@ int luaY_parse (void); | |||
| 28 | #define free luaM_free | 28 | #define free luaM_free |
| 29 | 29 | ||
| 30 | 30 | ||
| 31 | /* size of a "normal" jump instruction: OpCode + 1 byte */ | ||
| 32 | #define JMPSIZE 2 | ||
| 33 | |||
| 31 | /* maximum number of local variables */ | 34 | /* maximum number of local variables */ |
| 32 | #define MAXLOCALS 32 | 35 | #define MAXLOCALS 32 |
| 33 | 36 | ||
| @@ -85,11 +88,32 @@ void luaY_error (char *s) | |||
| 85 | } | 88 | } |
| 86 | 89 | ||
| 87 | 90 | ||
| 88 | static void code_byte (Byte c) | 91 | static void check_pc (int n) |
| 89 | { | 92 | { |
| 90 | if (currState->pc >= currState->maxcode) | 93 | if (currState->pc+n > currState->maxcode) |
| 91 | currState->maxcode = luaM_growvector(&currState->f->code, | 94 | currState->maxcode = luaM_growvector(&currState->f->code, |
| 92 | currState->maxcode, Byte, codeEM, MAX_INT); | 95 | currState->maxcode, Byte, codeEM, MAX_INT); |
| 96 | } | ||
| 97 | |||
| 98 | |||
| 99 | static void movecode_up (int d, int s, int n) | ||
| 100 | { | ||
| 101 | while (n--) | ||
| 102 | currState->f->code[d+n] = currState->f->code[s+n]; | ||
| 103 | } | ||
| 104 | |||
| 105 | |||
| 106 | static void movecode_down (int d, int s, int n) | ||
| 107 | { | ||
| 108 | int i; | ||
| 109 | for (i=0; i<n; i++) | ||
| 110 | currState->f->code[d+i] = currState->f->code[s+i]; | ||
| 111 | } | ||
| 112 | |||
| 113 | |||
| 114 | static void code_byte (Byte c) | ||
| 115 | { | ||
| 116 | check_pc(1); | ||
| 93 | currState->f->code[currState->pc++] = c; | 117 | currState->f->code[currState->pc++] = c; |
| 94 | } | 118 | } |
| 95 | 119 | ||
| @@ -103,19 +127,36 @@ static void code_word_at (int pc, int n) | |||
| 103 | } | 127 | } |
| 104 | 128 | ||
| 105 | 129 | ||
| 106 | static void fix_jump (int pc, OpCode op, int n) | 130 | static void code_word (int n) |
| 107 | { | 131 | { |
| 108 | currState->f->code[pc] = op; | 132 | check_pc(2); |
| 109 | code_word_at(pc+1, n); | 133 | currState->pc += 2; |
| 134 | code_word_at(currState->pc-2, n); | ||
| 110 | } | 135 | } |
| 111 | 136 | ||
| 112 | 137 | ||
| 113 | static void code_word (int n) | 138 | static int fix_opcode (int pc, OpCode op, int n) |
| 114 | { | 139 | { |
| 115 | if (n > MAX_WORD) | 140 | if (n <= 255) { |
| 116 | luaY_error("construction too big; unable to compile"); | 141 | currState->f->code[pc] = op; |
| 117 | code_byte(n&0xFF); | 142 | currState->f->code[pc+1] = n; |
| 118 | code_byte(n>>8); | 143 | return 0; |
| 144 | } | ||
| 145 | else { | ||
| 146 | check_pc(1); /* open space */ | ||
| 147 | movecode_up(pc+1, pc, currState->pc-pc); | ||
| 148 | currState->pc++; | ||
| 149 | currState->f->code[pc] = op+1; /* opcode must be word variant */ | ||
| 150 | code_word_at(pc+1, n); | ||
| 151 | return 1; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | static int fix_jump (int pc, OpCode op, int n) | ||
| 156 | { | ||
| 157 | n -= pc+1; /* jump is relative to position following jump opcode */ | ||
| 158 | if (n > 255) n++; /* jump must be 1 bigger */ | ||
| 159 | return fix_opcode(pc, op, n); | ||
| 119 | } | 160 | } |
| 120 | 161 | ||
| 121 | 162 | ||
| @@ -462,14 +503,14 @@ static int lua_codestore (int i, int left) | |||
| 462 | 503 | ||
| 463 | static void codeIf (int thenAdd, int elseAdd) | 504 | static void codeIf (int thenAdd, int elseAdd) |
| 464 | { | 505 | { |
| 465 | int elseinit = elseAdd+sizeof(Word)+1; | 506 | int elseinit = elseAdd+JMPSIZE; |
| 466 | if (currState->pc == elseinit) { /* no else part */ | 507 | if (currState->pc == elseinit) { /* no else part */ |
| 467 | currState->pc -= sizeof(Word)+1; | 508 | currState->pc -= JMPSIZE; |
| 468 | elseinit = currState->pc; | 509 | elseinit = currState->pc; |
| 469 | } | 510 | } |
| 470 | else | 511 | else |
| 471 | fix_jump(elseAdd, JMP, currState->pc-(elseAdd+1)); | 512 | elseinit += fix_jump(elseAdd, JMPB, currState->pc); |
| 472 | fix_jump(thenAdd, IFFJMP, elseinit-(thenAdd+1)); | 513 | fix_jump(thenAdd, IFFJMPB, elseinit); |
| 473 | } | 514 | } |
| 474 | 515 | ||
| 475 | 516 | ||
| @@ -593,7 +634,7 @@ TProtoFunc *luaY_parser (ZIO *z, char *chunkname) | |||
| 593 | %token <vReal> NUMBER | 634 | %token <vReal> NUMBER |
| 594 | %token <pTStr> NAME STRING | 635 | %token <pTStr> NAME STRING |
| 595 | 636 | ||
| 596 | %type <vInt> PrepJump, PrepJumpPop, PrepJumpSC | 637 | %type <vInt> SaveWord, cond, GetPC, SaveWordPop, SaveWordPush |
| 597 | %type <vLong> exprlist, exprlist1 /* if > 0, points to function return | 638 | %type <vLong> exprlist, exprlist1 /* if > 0, points to function return |
| 598 | counter (which has list length); if <= 0, -list lenght */ | 639 | counter (which has list length); if <= 0, -list lenght */ |
| 599 | %type <vLong> functioncall, expr /* if != 0, points to function return | 640 | %type <vLong> functioncall, expr /* if != 0, points to function return |
| @@ -628,18 +669,24 @@ statlist : /* empty */ | |||
| 628 | 669 | ||
| 629 | sc : /* empty */ | ';' ; | 670 | sc : /* empty */ | ';' ; |
| 630 | 671 | ||
| 631 | stat : IF expr1 THEN PrepJumpPop block PrepJump elsepart END | 672 | stat : IF cond THEN block SaveWord elsepart END |
| 632 | { codeIf($4, $6); } | 673 | { codeIf($2, $5); } |
| 633 | 674 | ||
| 634 | | WHILE {$<vInt>$=currState->pc;} expr1 DO PrepJumpPop block END | 675 | | WHILE GetPC cond DO block END |
| 635 | { | 676 | {{ |
| 636 | code_opborw(UPJMPB, currState->pc+1 - ($<vInt>2), 0); | 677 | int expsize = $3-$2; |
| 637 | fix_jump($5, IFFJMP, currState->pc - ($5+1)); | 678 | int newpos = $2+JMPSIZE; |
| 638 | } | 679 | check_pc(expsize); |
| 680 | memcpy(&currState->f->code[currState->pc], | ||
| 681 | &currState->f->code[$2], expsize); | ||
| 682 | movecode_down($2, $3, currState->pc-$2); | ||
| 683 | newpos += fix_jump($2, JMPB, currState->pc-expsize); | ||
| 684 | code_opborw(IFTUPJMPB, currState->pc+1 - newpos, 0); | ||
| 685 | }} | ||
| 639 | 686 | ||
| 640 | | REPEAT {$<vInt>$=currState->pc;} block UNTIL expr1 | 687 | | REPEAT GetPC block UNTIL expr1 |
| 641 | { | 688 | { |
| 642 | code_opborw(IFFUPJMPB, currState->pc+1 - ($<vInt>2), -1); | 689 | code_opborw(IFFUPJMPB, currState->pc+1 - $2, -1); |
| 643 | } | 690 | } |
| 644 | 691 | ||
| 645 | | varlist1 '=' exprlist1 | 692 | | varlist1 '=' exprlist1 |
| @@ -687,8 +734,8 @@ body : '(' parlist ')' chunk END { $$ = close_func(); } | |||
| 687 | 734 | ||
| 688 | elsepart : /* empty */ | 735 | elsepart : /* empty */ |
| 689 | | ELSE block | 736 | | ELSE block |
| 690 | | ELSEIF expr1 THEN PrepJumpPop block PrepJump elsepart | 737 | | ELSEIF cond THEN block SaveWord elsepart |
| 691 | { codeIf($4, $6); } | 738 | { codeIf($2, $5); } |
| 692 | ; | 739 | ; |
| 693 | 740 | ||
| 694 | ret : /* empty */ | 741 | ret : /* empty */ |
| @@ -699,19 +746,19 @@ ret : /* empty */ | |||
| 699 | } | 746 | } |
| 700 | ; | 747 | ; |
| 701 | 748 | ||
| 702 | PrepJump : /* empty */ | 749 | GetPC : /* empty */ { $$ = currState->pc; } |
| 703 | { | 750 | ; |
| 704 | $$ = currState->pc; | 751 | |
| 705 | code_byte(0); /* open space */ | 752 | SaveWord : GetPC { $$ = $1; code_word(0); /* open space */ } |
| 706 | code_word(0); | ||
| 707 | } | ||
| 708 | ; | 753 | ; |
| 709 | 754 | ||
| 710 | PrepJumpSC : /* empty */ | 755 | SaveWordPop : SaveWord { $$ = $1; deltastack(-1); /* pop condition */ } |
| 711 | { $$ = currState->pc; code_opcode(0, -1); code_byte(0); } | 756 | ; |
| 757 | |||
| 758 | SaveWordPush : SaveWord { $$ = $1; deltastack(1); /* push a value */ } | ||
| 712 | ; | 759 | ; |
| 713 | 760 | ||
| 714 | PrepJumpPop : PrepJump { $$ = $1; deltastack(-1); /* pop condition */ } | 761 | cond : expr1 SaveWordPop { $$ = $2; } |
| 715 | ; | 762 | ; |
| 716 | 763 | ||
| 717 | expr1 : expr { adjust_functioncall($1, 1); } | 764 | expr1 : expr { adjust_functioncall($1, 1); } |
| @@ -739,14 +786,11 @@ expr : '(' expr ')' { $$ = $2; } | |||
| 739 | | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } | 786 | | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } |
| 740 | | functioncall { $$ = $1; } | 787 | | functioncall { $$ = $1; } |
| 741 | | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } | 788 | | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } |
| 742 | | expr1 AND PrepJumpSC expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; } | 789 | | expr1 AND SaveWordPop expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; } |
| 743 | | expr1 OR PrepJumpSC expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; } | 790 | | expr1 OR SaveWordPop expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; } |
| 744 | ; | 791 | ; |
| 745 | 792 | ||
| 746 | table : | 793 | table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAYB, $3); } |
| 747 | { $<vInt>$ = currState->pc+1; code_opw(CREATEARRAY, 0, 1); } | ||
| 748 | '{' fieldlist '}' | ||
| 749 | { code_word_at($<vInt>1, $3); } | ||
| 750 | ; | 794 | ; |
| 751 | 795 | ||
| 752 | functioncall : funcvalue funcParams | 796 | functioncall : funcvalue funcParams |
| @@ -892,3 +936,4 @@ decinit : /* empty */ { $$ = 0; } | |||
| 892 | ; | 936 | ; |
| 893 | 937 | ||
| 894 | %% | 938 | %% |
| 939 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.5 1997/09/24 19:43:11 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.6 1997/09/26 15:02:26 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 | */ |
| @@ -452,8 +452,13 @@ StkId luaV_execute (Closure *cl, StkId base) | |||
| 452 | break; | 452 | break; |
| 453 | 453 | ||
| 454 | case CREATEARRAY: | 454 | case CREATEARRAY: |
| 455 | aux = next_word(pc); goto createarray; | ||
| 456 | |||
| 457 | case CREATEARRAYB: | ||
| 458 | aux = *pc++; | ||
| 459 | createarray: | ||
| 455 | luaC_checkGC(); | 460 | luaC_checkGC(); |
| 456 | avalue(luaD_stack.top) = luaH_new(next_word(pc)); | 461 | avalue(luaD_stack.top) = luaH_new(aux); |
| 457 | ttype(luaD_stack.top) = LUA_T_ARRAY; | 462 | ttype(luaD_stack.top) = LUA_T_ARRAY; |
| 458 | luaD_stack.top++; | 463 | luaD_stack.top++; |
| 459 | break; | 464 | break; |
| @@ -565,54 +570,51 @@ StkId luaV_execute (Closure *cl, StkId base) | |||
| 565 | break; | 570 | break; |
| 566 | 571 | ||
| 567 | case ONTJMP: | 572 | case ONTJMP: |
| 568 | if (ttype(luaD_stack.top-1) != LUA_T_NIL) | 573 | if (ttype(luaD_stack.top-1) != LUA_T_NIL) pc += *pc; |
| 569 | pc += *pc; | 574 | else { pc++; luaD_stack.top--; } |
| 570 | else { | ||
| 571 | pc++; | ||
| 572 | luaD_stack.top--; | ||
| 573 | } | ||
| 574 | break; | 575 | break; |
| 575 | 576 | ||
| 576 | case ONFJMP: | 577 | case ONFJMP: |
| 577 | if (ttype(luaD_stack.top-1) == LUA_T_NIL) | 578 | if (ttype(luaD_stack.top-1) == LUA_T_NIL) pc += *pc; |
| 578 | pc += *pc; | 579 | else { pc++; luaD_stack.top--; } |
| 579 | else { | 580 | break; |
| 580 | pc++; | 581 | |
| 581 | luaD_stack.top--; | 582 | case JMPB: |
| 582 | } | 583 | pc += *pc; |
| 583 | break; | 584 | break; |
| 584 | 585 | ||
| 585 | case JMP: | 586 | case JMP: |
| 586 | pc += get_word(pc); | 587 | pc += get_word(pc); |
| 587 | break; | 588 | break; |
| 588 | 589 | ||
| 589 | case UPJMPB: | 590 | case IFFJMPB: |
| 590 | pc -= *pc; | 591 | if (ttype(--luaD_stack.top) == LUA_T_NIL) pc += *pc; |
| 592 | else pc++; | ||
| 591 | break; | 593 | break; |
| 592 | 594 | ||
| 593 | case UPJMP: | 595 | case IFFJMP: |
| 594 | pc -= get_word(pc); | 596 | if (ttype(--luaD_stack.top) == LUA_T_NIL) pc += get_word(pc); |
| 597 | else skip_word(pc); | ||
| 595 | break; | 598 | break; |
| 596 | 599 | ||
| 597 | case IFFJMP: | 600 | case IFTUPJMPB: |
| 598 | if (ttype(--luaD_stack.top) == LUA_T_NIL) | 601 | if (ttype(--luaD_stack.top) != LUA_T_NIL) pc -= *pc; |
| 599 | pc += get_word(pc); | 602 | else pc++; |
| 600 | else | 603 | break; |
| 601 | skip_word(pc); | 604 | |
| 605 | case IFTUPJMP: | ||
| 606 | if (ttype(--luaD_stack.top) != LUA_T_NIL) pc -= get_word(pc); | ||
| 607 | else skip_word(pc); | ||
| 602 | break; | 608 | break; |
| 603 | 609 | ||
| 604 | case IFFUPJMPB: | 610 | case IFFUPJMPB: |
| 605 | if (ttype(--luaD_stack.top) == LUA_T_NIL) | 611 | if (ttype(--luaD_stack.top) == LUA_T_NIL) pc -= *pc; |
| 606 | pc -= *pc; | 612 | else pc++; |
| 607 | else | ||
| 608 | pc++; | ||
| 609 | break; | 613 | break; |
| 610 | 614 | ||
| 611 | case IFFUPJMP: | 615 | case IFFUPJMP: |
| 612 | if (ttype(--luaD_stack.top) == LUA_T_NIL) | 616 | if (ttype(--luaD_stack.top) == LUA_T_NIL) pc -= get_word(pc); |
| 613 | pc -= get_word(pc); | 617 | else skip_word(pc); |
| 614 | else | ||
| 615 | skip_word(pc); | ||
| 616 | break; | 618 | break; |
| 617 | 619 | ||
| 618 | case CLOSURE: | 620 | case CLOSURE: |
