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); } |