diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-09-22 17:53:20 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-09-22 17:53:20 -0300 |
| commit | d6c867ea507c5f6f9aee730bdcecee8f80a2feed (patch) | |
| tree | 0eda337c0057614118656222e00966dec68a227f /lua.stx | |
| parent | 2079cfe8faa34ebe435d1ef0526b04d3e57b5349 (diff) | |
| download | lua-d6c867ea507c5f6f9aee730bdcecee8f80a2feed.tar.gz lua-d6c867ea507c5f6f9aee730bdcecee8f80a2feed.tar.bz2 lua-d6c867ea507c5f6f9aee730bdcecee8f80a2feed.zip | |
better way to cope with opcode variants
Diffstat (limited to 'lua.stx')
| -rw-r--r-- | lua.stx | 180 |
1 files changed, 60 insertions, 120 deletions
| @@ -1,6 +1,6 @@ | |||
| 1 | %{ | 1 | %{ |
| 2 | /* | 2 | /* |
| 3 | ** $Id: lua.stx,v 1.2 1997/09/19 18:40:32 roberto Exp roberto $ | 3 | ** $Id: lua.stx,v 1.3 1997/09/19 21:17:52 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 | */ |
| @@ -94,6 +94,22 @@ static void code_byte (Byte c) | |||
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | 96 | ||
| 97 | static void code_word_at (int pc, int n) | ||
| 98 | { | ||
| 99 | Word w = n; | ||
| 100 | if (w != n) | ||
| 101 | luaY_error("block too big"); | ||
| 102 | currState->f->code[pc] = n&0xFF; | ||
| 103 | currState->f->code[pc+1] = n>>8; | ||
| 104 | } | ||
| 105 | |||
| 106 | static void code_word (int n) | ||
| 107 | { | ||
| 108 | code_byte(n&0xFF); | ||
| 109 | code_byte(n>>8); | ||
| 110 | } | ||
| 111 | |||
| 112 | |||
| 97 | static void deltastack (int delta) | 113 | static void deltastack (int delta) |
| 98 | { | 114 | { |
| 99 | currState->stacksize += delta; | 115 | currState->stacksize += delta; |
| @@ -112,9 +128,25 @@ static void code_opcode (OpCode op, int delta) | |||
| 112 | } | 128 | } |
| 113 | 129 | ||
| 114 | 130 | ||
| 115 | static void code_push (OpCode op) | 131 | static void code_opborw(OpCode opbyte, int arg, int delta) |
| 116 | { | 132 | { |
| 117 | code_opcode(op, 1); | 133 | if (arg <= 255) { |
| 134 | code_opcode(opbyte, delta); | ||
| 135 | code_byte(arg); | ||
| 136 | } | ||
| 137 | else { | ||
| 138 | code_opcode(opbyte+1, delta); | ||
| 139 | code_word(arg); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | |||
| 144 | static void code_oparg (OpCode firstop, OpCode opbyte, int arg, int delta) | ||
| 145 | { | ||
| 146 | if (firstop+arg < opbyte) | ||
| 147 | code_opcode(firstop+arg, delta); | ||
| 148 | else | ||
| 149 | code_opborw(opbyte, arg, delta); | ||
| 118 | } | 150 | } |
| 119 | 151 | ||
| 120 | 152 | ||
| @@ -133,31 +165,9 @@ static void code_pop (OpCode op) | |||
| 133 | #define code_unop(op) code_neutralop(op) | 165 | #define code_unop(op) code_neutralop(op) |
| 134 | 166 | ||
| 135 | 167 | ||
| 136 | static void code_word_at (int pc, int n) | ||
| 137 | { | ||
| 138 | Word w = n; | ||
| 139 | if (w != n) | ||
| 140 | luaY_error("block too big"); | ||
| 141 | currState->f->code[pc] = n&0xFF; | ||
| 142 | currState->f->code[pc+1] = n>>8; | ||
| 143 | } | ||
| 144 | |||
| 145 | static void code_word (int n) | ||
| 146 | { | ||
| 147 | code_byte(n&0xFF); | ||
| 148 | code_byte(n>>8); | ||
| 149 | } | ||
| 150 | |||
| 151 | static void code_constant (int c) | 168 | static void code_constant (int c) |
| 152 | { | 169 | { |
| 153 | if (c <= 255) { | 170 | code_opborw(PUSHCONSTANTB, c, 1); |
| 154 | code_push(PUSHCONSTANTB); | ||
| 155 | code_byte(c); | ||
| 156 | } | ||
| 157 | else { | ||
| 158 | code_push(PUSHCONSTANT); | ||
| 159 | code_word(c); | ||
| 160 | } | ||
| 161 | } | 171 | } |
| 162 | 172 | ||
| 163 | 173 | ||
| @@ -216,18 +226,8 @@ static int real_constant (real r) | |||
| 216 | static void code_number (real f) | 226 | static void code_number (real f) |
| 217 | { | 227 | { |
| 218 | Word i; | 228 | Word i; |
| 219 | if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) { | 229 | if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) |
| 220 | /* f has an (short) integer value */ | 230 | code_oparg(PUSH0, PUSHBYTE, i, 1); /* f has an (short) integer value */ |
| 221 | if (i <= 2) code_push(PUSH0 + i); | ||
| 222 | else if (i <= 255) { | ||
| 223 | code_push(PUSHBYTE); | ||
| 224 | code_byte(i); | ||
| 225 | } | ||
| 226 | else { | ||
| 227 | code_push(PUSHWORD); | ||
| 228 | code_word(i); | ||
| 229 | } | ||
| 230 | } | ||
| 231 | else | 231 | else |
| 232 | code_constant(real_constant(f)); | 232 | code_constant(real_constant(f)); |
| 233 | } | 233 | } |
| @@ -344,12 +344,7 @@ static void pushupvalue (TaggedString *n) | |||
| 344 | if (aux_localname(n, currState) >= 0) | 344 | if (aux_localname(n, currState) >= 0) |
| 345 | luaY_syntaxerror("cannot access an upvalue in current scope", n->str); | 345 | luaY_syntaxerror("cannot access an upvalue in current scope", n->str); |
| 346 | i = indexupvalue(n); | 346 | i = indexupvalue(n); |
| 347 | if (i == 0) | 347 | code_oparg(PUSHUPVALUE0, PUSHUPVALUE, i, 1); |
| 348 | code_push(PUSHUPVALUE0); | ||
| 349 | else { | ||
| 350 | code_push(PUSHUPVALUE); | ||
| 351 | code_byte(i); | ||
| 352 | } | ||
| 353 | } | 348 | } |
| 354 | 349 | ||
| 355 | 350 | ||
| @@ -366,18 +361,10 @@ void luaY_codedebugline (int line) | |||
| 366 | 361 | ||
| 367 | static void adjuststack (int n) | 362 | static void adjuststack (int n) |
| 368 | { | 363 | { |
| 369 | if (n > 0) { | 364 | if (n > 0) |
| 370 | code_opcode(POPS, -n); | 365 | code_oparg(POP1-1, POPS, n, -n); /* POP1-1 = POP0 */ |
| 371 | code_byte(n); | 366 | else if (n < 0) |
| 372 | } | 367 | code_oparg(PUSHNIL-1, PUSHNILS, -n, -n); /* PUSHNIL1-1 = PUSHNIL0 */ |
| 373 | else if (n < 0) { | ||
| 374 | if (n == -1) | ||
| 375 | code_push(PUSHNIL); | ||
| 376 | else { | ||
| 377 | code_opcode(PUSHNILS, -n); | ||
| 378 | code_byte(-n); | ||
| 379 | } | ||
| 380 | } | ||
| 381 | } | 368 | } |
| 382 | 369 | ||
| 383 | 370 | ||
| @@ -426,29 +413,12 @@ static void code_args (int dots) | |||
| 426 | 413 | ||
| 427 | static void lua_pushvar (vardesc number) | 414 | static void lua_pushvar (vardesc number) |
| 428 | { | 415 | { |
| 429 | if (number > 0) { /* global var */ | 416 | if (number > 0) /* global var */ |
| 430 | number--; | 417 | code_opborw(GETGLOBALB, number-1, 1); |
| 431 | if (number <= 255) { | 418 | else if (number < 0) /* local var */ |
| 432 | code_push(PUSHGLOBALB); | 419 | code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1); |
| 433 | code_byte(number); | 420 | else |
| 434 | } | ||
| 435 | else { | ||
| 436 | code_push(PUSHGLOBAL); | ||
| 437 | code_word(number); | ||
| 438 | } | ||
| 439 | } | ||
| 440 | else if (number < 0) { /* local var */ | ||
| 441 | number = (-number) - 1; | ||
| 442 | if (number < 10) | ||
| 443 | code_push(PUSHLOCAL0 + number); | ||
| 444 | else { | ||
| 445 | code_push(PUSHLOCAL); | ||
| 446 | code_byte(number); | ||
| 447 | } | ||
| 448 | } | ||
| 449 | else { | ||
| 450 | code_pop(GETTABLE); | 421 | code_pop(GETTABLE); |
| 451 | } | ||
| 452 | } | 422 | } |
| 453 | 423 | ||
| 454 | 424 | ||
| @@ -456,26 +426,10 @@ static void storevar (vardesc number) | |||
| 456 | { | 426 | { |
| 457 | if (number == 0) /* indexed var */ | 427 | if (number == 0) /* indexed var */ |
| 458 | code_opcode(SETTABLE0, -3); | 428 | code_opcode(SETTABLE0, -3); |
| 459 | else if (number > 0) { /* global var */ | 429 | else if (number > 0) /* global var */ |
| 460 | number--; | 430 | code_opborw(SETGLOBALB, number-1, -1); |
| 461 | if (number <= 255) { | 431 | else /* number < 0 - local var */ |
| 462 | code_pop(SETGLOBALB); | 432 | code_oparg(SETLOCAL0, SETLOCAL, (-number)-1, -1); |
| 463 | code_byte(number); | ||
| 464 | } | ||
| 465 | else { | ||
| 466 | code_pop(SETGLOBAL); | ||
| 467 | code_word(number); | ||
| 468 | } | ||
| 469 | } | ||
| 470 | else { /* number < 0 - local var */ | ||
| 471 | number = (-number) - 1; | ||
| 472 | if (number < 10) | ||
| 473 | code_pop(SETLOCAL0 + number); | ||
| 474 | else { | ||
| 475 | code_pop(SETLOCAL); | ||
| 476 | code_byte(number); | ||
| 477 | } | ||
| 478 | } | ||
| 479 | } | 433 | } |
| 480 | 434 | ||
| 481 | 435 | ||
| @@ -535,8 +489,7 @@ static void func_onstack (TProtoFunc *f) | |||
| 535 | currState->f->consts[c].value.tf = (currState+1)->f; | 489 | currState->f->consts[c].value.tf = (currState+1)->f; |
| 536 | for (i=0; i<nupvalues; i++) | 490 | for (i=0; i<nupvalues; i++) |
| 537 | lua_pushvar((currState+1)->upvalues[i]); | 491 | lua_pushvar((currState+1)->upvalues[i]); |
| 538 | code_constant(c); | 492 | code_opborw(CLOSUREB, c, 1-nupvalues); |
| 539 | code_opcode(CLOSURE, -nupvalues); | ||
| 540 | } | 493 | } |
| 541 | 494 | ||
| 542 | 495 | ||
| @@ -771,7 +724,7 @@ expr : '(' expr ')' { $$ = $2; } | |||
| 771 | | varexp { $$ = 0;} | 724 | | varexp { $$ = 0;} |
| 772 | | NUMBER { code_number($1); $$ = 0; } | 725 | | NUMBER { code_number($1); $$ = 0; } |
| 773 | | STRING { code_string($1); $$ = 0; } | 726 | | STRING { code_string($1); $$ = 0; } |
| 774 | | NIL {code_push(PUSHNIL); $$ = 0; } | 727 | | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } |
| 775 | | functioncall { $$ = $1; } | 728 | | functioncall { $$ = $1; } |
| 776 | | expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; } | 729 | | expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; } |
| 777 | | expr1 OR PrepJumpPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; } | 730 | | expr1 OR PrepJumpPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; } |
| @@ -779,14 +732,9 @@ expr : '(' expr ')' { $$ = $2; } | |||
| 779 | ; | 732 | ; |
| 780 | 733 | ||
| 781 | table : | 734 | table : |
| 782 | { | 735 | { code_opcode(CREATEARRAY, 1); $<vInt>$ = currState->pc; code_word(0); } |
| 783 | code_push(CREATEARRAY); | 736 | '{' fieldlist '}' |
| 784 | $<vInt>$ = currState->pc; code_word(0); | 737 | { code_word_at($<vInt>1, $3); } |
| 785 | } | ||
| 786 | '{' fieldlist '}' | ||
| 787 | { | ||
| 788 | code_word_at($<vInt>1, $3); | ||
| 789 | } | ||
| 790 | ; | 738 | ; |
| 791 | 739 | ||
| 792 | functioncall : funcvalue funcParams | 740 | functioncall : funcvalue funcParams |
| @@ -801,8 +749,7 @@ functioncall : funcvalue funcParams | |||
| 801 | funcvalue : varexp { $$ = 0; } | 749 | funcvalue : varexp { $$ = 0; } |
| 802 | | varexp ':' NAME | 750 | | varexp ':' NAME |
| 803 | { | 751 | { |
| 804 | code_push(PUSHSELF); | 752 | code_opborw(PUSHSELFB, string_constant($3, currState), 1); |
| 805 | code_word(string_constant($3, currState)); | ||
| 806 | $$ = 1; | 753 | $$ = 1; |
| 807 | } | 754 | } |
| 808 | ; | 755 | ; |
| @@ -909,15 +856,8 @@ varlist1 : var | |||
| 909 | ; | 856 | ; |
| 910 | 857 | ||
| 911 | var : singlevar { $$ = $1; } | 858 | var : singlevar { $$ = $1; } |
| 912 | | varexp '[' expr1 ']' | 859 | | varexp '[' expr1 ']' { $$ = 0; } /* indexed variable */ |
| 913 | { | 860 | | varexp '.' NAME { code_string($3); $$ = 0; }/* ind. var. */ |
| 914 | $$ = 0; /* indexed variable */ | ||
| 915 | } | ||
| 916 | | varexp '.' NAME | ||
| 917 | { | ||
| 918 | code_string($3); | ||
| 919 | $$ = 0; /* indexed variable */ | ||
| 920 | } | ||
| 921 | ; | 861 | ; |
| 922 | 862 | ||
| 923 | singlevar : NAME { $$ = singlevar($1, currState); } | 863 | singlevar : NAME { $$ = singlevar($1, currState); } |
