diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-07-30 19:00:50 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-07-30 19:00:50 -0300 |
| commit | 0892f0e5b75c51f1fee07276a3ba13301b83409e (patch) | |
| tree | 9f3b9ec92f26c05a85c826ffc5f803fda2f48867 /lua.stx | |
| parent | 1d7857bc635c0bfe7c5b1f325d31feb7660e9a5a (diff) | |
| download | lua-0892f0e5b75c51f1fee07276a3ba13301b83409e.tar.gz lua-0892f0e5b75c51f1fee07276a3ba13301b83409e.tar.bz2 lua-0892f0e5b75c51f1fee07276a3ba13301b83409e.zip | |
BIG CHANGE: functions have their own "constant table".
Diffstat (limited to 'lua.stx')
| -rw-r--r-- | lua.stx | 281 |
1 files changed, 156 insertions, 125 deletions
| @@ -1,10 +1,8 @@ | |||
| 1 | %{ | 1 | %{ |
| 2 | 2 | ||
| 3 | char *rcs_luastx = "$Id: lua.stx,v 3.47 1997/06/19 17:46:12 roberto Exp roberto $"; | 3 | char *rcs_luastx = "$Id: lua.stx,v 3.48 1997/07/29 20:38:45 roberto Exp roberto $"; |
| 4 | 4 | ||
| 5 | #include <stdio.h> | ||
| 6 | #include <stdlib.h> | 5 | #include <stdlib.h> |
| 7 | #include <string.h> | ||
| 8 | 6 | ||
| 9 | #include "luadebug.h" | 7 | #include "luadebug.h" |
| 10 | #include "luamem.h" | 8 | #include "luamem.h" |
| @@ -40,6 +38,7 @@ struct State { | |||
| 40 | int pc; /* next position to code */ | 38 | int pc; /* next position to code */ |
| 41 | TaggedString *localvar[MAXLOCALS]; /* store local variable names */ | 39 | TaggedString *localvar[MAXLOCALS]; /* store local variable names */ |
| 42 | int nlocalvar; /* number of active local variables */ | 40 | int nlocalvar; /* number of active local variables */ |
| 41 | int maxconsts; /* size of consts vector */ | ||
| 43 | int nvars; /* total number of local variables (for debugging information) */ | 42 | int nvars; /* total number of local variables (for debugging information) */ |
| 44 | int maxvars; /* = -1 if no debug information */ | 43 | int maxvars; /* = -1 if no debug information */ |
| 45 | } stateMain, stateFunc, *currState; | 44 | } stateMain, stateFunc, *currState; |
| @@ -69,41 +68,106 @@ static void check_space (int i) | |||
| 69 | Byte, codeEM, MAX_INT); | 68 | Byte, codeEM, MAX_INT); |
| 70 | } | 69 | } |
| 71 | 70 | ||
| 71 | |||
| 72 | static void code_byte (Byte c) | 72 | static void code_byte (Byte c) |
| 73 | { | 73 | { |
| 74 | check_space(1); | 74 | check_space(1); |
| 75 | currState->f->code[currState->pc++] = c; | 75 | currState->f->code[currState->pc++] = c; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | static void code_float (real n) | 78 | |
| 79 | static void code_word_at (int pc, int n) | ||
| 79 | { | 80 | { |
| 80 | check_space(sizeof(real)); | 81 | Word w = n; |
| 81 | memcpy(currState->f->code+currState->pc, &n, sizeof(real)); | 82 | if (w != n) |
| 82 | currState->pc += sizeof(real); | 83 | yyerror("block too big"); |
| 84 | currState->f->code[pc] = n&0xFF; | ||
| 85 | currState->f->code[pc+1] = n>>8; | ||
| 83 | } | 86 | } |
| 84 | 87 | ||
| 85 | static void code_code (TFunc *tf) | 88 | static void code_word (int n) |
| 86 | { | 89 | { |
| 87 | check_space(sizeof(TFunc *)); | 90 | code_byte(n&0xFF); |
| 88 | memcpy(currState->f->code+currState->pc, &tf, sizeof(TFunc *)); | 91 | code_byte(n>>8); |
| 89 | currState->pc += sizeof(TFunc *); | ||
| 90 | } | 92 | } |
| 91 | 93 | ||
| 92 | static void code_word_at (int pc, int n) | 94 | static void code_constant (int c) |
| 93 | { | 95 | { |
| 94 | Word w = n; | 96 | if (c <= 255) { |
| 95 | if (w != n) | 97 | code_byte(PUSHCONSTANTB); |
| 96 | yyerror("block too big"); | 98 | code_byte(c); |
| 97 | memcpy(currState->f->code+pc, &w, sizeof(Word)); | 99 | } |
| 100 | else { | ||
| 101 | code_byte(PUSHCONSTANT); | ||
| 102 | code_word(c); | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | |||
| 107 | static int next_constant (void) | ||
| 108 | { | ||
| 109 | if (currState->f->nconsts >= currState->maxconsts) { | ||
| 110 | currState->maxconsts = | ||
| 111 | growvector(&currState->f->consts, currState->maxconsts, | ||
| 112 | TObject, constantEM, MAX_WORD); | ||
| 113 | } | ||
| 114 | return currState->f->nconsts++; | ||
| 115 | } | ||
| 116 | |||
| 117 | |||
| 118 | static int string_constant (TaggedString *s) | ||
| 119 | { | ||
| 120 | int c = s->u.s.constindex; | ||
| 121 | if (!(0 <= c && c < currState->f->nconsts && | ||
| 122 | ttype(&currState->f->consts[c]) == LUA_T_STRING && | ||
| 123 | tsvalue(&currState->f->consts[c]) == s)) { | ||
| 124 | c = next_constant(); | ||
| 125 | ttype(&currState->f->consts[c]) = LUA_T_STRING; | ||
| 126 | tsvalue(&currState->f->consts[c]) = s; | ||
| 127 | s->u.s.constindex = c; /* hint for next time */ | ||
| 128 | luaI_releasestring(s); | ||
| 129 | } | ||
| 130 | return c; | ||
| 98 | } | 131 | } |
| 99 | 132 | ||
| 100 | static void code_word (Word n) | 133 | |
| 134 | static void code_string (TaggedString *s) | ||
| 101 | { | 135 | { |
| 102 | check_space(sizeof(Word)); | 136 | int c = string_constant(s); |
| 103 | memcpy(currState->f->code+currState->pc, &n, sizeof(Word)); | 137 | code_constant(c); |
| 104 | currState->pc += sizeof(Word); | ||
| 105 | } | 138 | } |
| 106 | 139 | ||
| 140 | static void code_float (real n) | ||
| 141 | { | ||
| 142 | int c = next_constant(); | ||
| 143 | ttype(&currState->f->consts[c]) = LUA_T_NUMBER; | ||
| 144 | nvalue(&currState->f->consts[c]) = n; | ||
| 145 | code_constant(c); | ||
| 146 | } | ||
| 147 | |||
| 148 | |||
| 149 | static void code_number (float f) | ||
| 150 | { | ||
| 151 | Word i; | ||
| 152 | if (f >= 0 && f <= (float)MAX_WORD && (float)(i=(Word)f) == f) { | ||
| 153 | /* f has an (short) integer value */ | ||
| 154 | if (i <= 2) code_byte(PUSH0 + i); | ||
| 155 | else if (i <= 255) | ||
| 156 | { | ||
| 157 | code_byte(PUSHBYTE); | ||
| 158 | code_byte(i); | ||
| 159 | } | ||
| 160 | else | ||
| 161 | { | ||
| 162 | code_byte(PUSHWORD); | ||
| 163 | code_word(i); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | else | ||
| 167 | code_float(f); | ||
| 168 | } | ||
| 169 | |||
| 170 | |||
| 107 | static void flush_record (int n) | 171 | static void flush_record (int n) |
| 108 | { | 172 | { |
| 109 | if (n == 0) return; | 173 | if (n == 0) return; |
| @@ -149,6 +213,7 @@ static void luaI_unregisterlocalvar (int line) | |||
| 149 | 213 | ||
| 150 | static void store_localvar (TaggedString *name, int n) | 214 | static void store_localvar (TaggedString *name, int n) |
| 151 | { | 215 | { |
| 216 | luaI_fixstring(name); /* local var names cannot be GC */ | ||
| 152 | if (currState->nlocalvar+n < MAXLOCALS) | 217 | if (currState->nlocalvar+n < MAXLOCALS) |
| 153 | currState->localvar[currState->nlocalvar+n] = name; | 218 | currState->localvar[currState->nlocalvar+n] = name; |
| 154 | else | 219 | else |
| @@ -170,40 +235,6 @@ static void add_varbuffer (Long var) | |||
| 170 | yyerror ("variable buffer overflow"); | 235 | yyerror ("variable buffer overflow"); |
| 171 | } | 236 | } |
| 172 | 237 | ||
| 173 | static void code_string (Word w) | ||
| 174 | { | ||
| 175 | code_byte(PUSHSTRING); | ||
| 176 | code_word(w); | ||
| 177 | } | ||
| 178 | |||
| 179 | static void code_constant (TaggedString *s) | ||
| 180 | { | ||
| 181 | code_string(luaI_findconstant(s)); | ||
| 182 | } | ||
| 183 | |||
| 184 | static void code_number (float f) | ||
| 185 | { | ||
| 186 | Word i; | ||
| 187 | if (f >= 0 && f <= (float)MAX_WORD && (float)(i=(Word)f) == f) { | ||
| 188 | /* f has an (short) integer value */ | ||
| 189 | if (i <= 2) code_byte(PUSH0 + i); | ||
| 190 | else if (i <= 255) | ||
| 191 | { | ||
| 192 | code_byte(PUSHBYTE); | ||
| 193 | code_byte(i); | ||
| 194 | } | ||
| 195 | else | ||
| 196 | { | ||
| 197 | code_byte(PUSHWORD); | ||
| 198 | code_word(i); | ||
| 199 | } | ||
| 200 | } | ||
| 201 | else | ||
| 202 | { | ||
| 203 | code_byte(PUSHFLOAT); | ||
| 204 | code_float(f); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | 238 | ||
| 208 | /* | 239 | /* |
| 209 | ** Search a local name and if find return its index. If do not find return -1 | 240 | ** Search a local name and if find return its index. If do not find return -1 |
| @@ -256,55 +287,6 @@ static void lua_codeadjust (int n) | |||
| 256 | } | 287 | } |
| 257 | 288 | ||
| 258 | 289 | ||
| 259 | static void init_state (TFunc *f) | ||
| 260 | { | ||
| 261 | luaI_initTFunc(f); | ||
| 262 | currState->nlocalvar = 0; | ||
| 263 | currState->f = f; | ||
| 264 | currState->pc = 0; | ||
| 265 | currState->codesize = CODE_BLOCK; | ||
| 266 | f->code = newvector(CODE_BLOCK, Byte); | ||
| 267 | if (lua_debug) { | ||
| 268 | currState->nvars = 0; | ||
| 269 | currState->maxvars = 0; | ||
| 270 | } | ||
| 271 | else | ||
| 272 | currState->maxvars = -1; /* flag no debug information */ | ||
| 273 | } | ||
| 274 | |||
| 275 | |||
| 276 | static void init_func (void) | ||
| 277 | { | ||
| 278 | currState = &stateFunc; | ||
| 279 | init_state(new(TFunc)); | ||
| 280 | luaI_codedebugline(lua_linenumber); | ||
| 281 | } | ||
| 282 | |||
| 283 | |||
| 284 | static void codereturn (void) | ||
| 285 | { | ||
| 286 | if (currState->nlocalvar == 0) | ||
| 287 | code_byte(RETCODE0); | ||
| 288 | else | ||
| 289 | { | ||
| 290 | code_byte(RETCODE); | ||
| 291 | code_byte(currState->nlocalvar); | ||
| 292 | } | ||
| 293 | } | ||
| 294 | |||
| 295 | |||
| 296 | static void close_func (void) | ||
| 297 | { | ||
| 298 | codereturn(); | ||
| 299 | code_byte(ENDCODE); | ||
| 300 | currState->f->code = shrinkvector(currState->f->code, currState->pc, Byte); | ||
| 301 | if (currState->maxvars != -1) { /* debug information? */ | ||
| 302 | luaI_registerlocalvar(NULL, -1); /* flag end of vector */ | ||
| 303 | currState->f->locvars = shrinkvector(currState->f->locvars, | ||
| 304 | currState->nvars, LocVar); | ||
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 308 | 290 | ||
| 309 | void luaI_codedebugline (int line) | 291 | void luaI_codedebugline (int line) |
| 310 | { | 292 | { |
| @@ -350,7 +332,7 @@ static int close_parlist (int dots) | |||
| 350 | else { | 332 | else { |
| 351 | code_byte(VARARGS); | 333 | code_byte(VARARGS); |
| 352 | code_byte(currState->nlocalvar); | 334 | code_byte(currState->nlocalvar); |
| 353 | add_localvar(luaI_createfixedstring("arg")); | 335 | add_localvar(luaI_createstring("arg")); |
| 354 | } | 336 | } |
| 355 | return lua_linenumber; | 337 | return lua_linenumber; |
| 356 | } | 338 | } |
| @@ -423,6 +405,65 @@ static void code_shortcircuit (int pc, Byte jmp) | |||
| 423 | } | 405 | } |
| 424 | 406 | ||
| 425 | 407 | ||
| 408 | static void init_state (TFunc *f) | ||
| 409 | { | ||
| 410 | currState->nlocalvar = 0; | ||
| 411 | currState->f = f; | ||
| 412 | currState->pc = 0; | ||
| 413 | currState->codesize = CODE_BLOCK; | ||
| 414 | f->code = newvector(CODE_BLOCK, Byte); | ||
| 415 | currState->maxconsts = 0; | ||
| 416 | if (lua_debug) { | ||
| 417 | currState->nvars = 0; | ||
| 418 | currState->maxvars = 0; | ||
| 419 | } | ||
| 420 | else | ||
| 421 | currState->maxvars = -1; /* flag no debug information */ | ||
| 422 | } | ||
| 423 | |||
| 424 | |||
| 425 | static void init_func (Long v) | ||
| 426 | { | ||
| 427 | TFunc *f = new(TFunc); | ||
| 428 | int c = next_constant(); | ||
| 429 | ttype(&currState->f->consts[c]) = LUA_T_FUNCTION; | ||
| 430 | currState->f->consts[c].value.tf = f; | ||
| 431 | code_constant(c); | ||
| 432 | storesinglevar(v); | ||
| 433 | currState = &stateFunc; | ||
| 434 | luaI_initTFunc(f); | ||
| 435 | init_state(f); | ||
| 436 | luaI_codedebugline(lua_linenumber); | ||
| 437 | } | ||
| 438 | |||
| 439 | |||
| 440 | static void codereturn (void) | ||
| 441 | { | ||
| 442 | if (currState->nlocalvar == 0) | ||
| 443 | code_byte(RETCODE0); | ||
| 444 | else | ||
| 445 | { | ||
| 446 | code_byte(RETCODE); | ||
| 447 | code_byte(currState->nlocalvar); | ||
| 448 | } | ||
| 449 | } | ||
| 450 | |||
| 451 | |||
| 452 | static void close_func (void) | ||
| 453 | { | ||
| 454 | codereturn(); | ||
| 455 | code_byte(ENDCODE); | ||
| 456 | currState->f->code = shrinkvector(currState->f->code, currState->pc, Byte); | ||
| 457 | currState->f->consts = shrinkvector(currState->f->consts, | ||
| 458 | currState->f->nconsts, TObject); | ||
| 459 | if (currState->maxvars != -1) { /* debug information? */ | ||
| 460 | luaI_registerlocalvar(NULL, -1); /* flag end of vector */ | ||
| 461 | currState->f->locvars = shrinkvector(currState->f->locvars, | ||
| 462 | currState->nvars, LocVar); | ||
| 463 | } | ||
| 464 | } | ||
| 465 | |||
| 466 | |||
| 426 | /* | 467 | /* |
| 427 | ** Parse LUA code. | 468 | ** Parse LUA code. |
| 428 | */ | 469 | */ |
| @@ -444,9 +485,7 @@ void lua_parse (TFunc *tf) | |||
| 444 | int vInt; | 485 | int vInt; |
| 445 | float vFloat; | 486 | float vFloat; |
| 446 | char *pChar; | 487 | char *pChar; |
| 447 | Word vWord; | ||
| 448 | Long vLong; | 488 | Long vLong; |
| 449 | TFunc *pFunc; | ||
| 450 | TaggedString *pTStr; | 489 | TaggedString *pTStr; |
| 451 | } | 490 | } |
| 452 | 491 | ||
| @@ -460,8 +499,7 @@ void lua_parse (TFunc *tf) | |||
| 460 | %token FUNCTION | 499 | %token FUNCTION |
| 461 | %token DOTS | 500 | %token DOTS |
| 462 | %token <vFloat> NUMBER | 501 | %token <vFloat> NUMBER |
| 463 | %token <vWord> STRING | 502 | %token <pTStr> NAME STRING |
| 464 | %token <pTStr> NAME | ||
| 465 | 503 | ||
| 466 | %type <vLong> PrepJump | 504 | %type <vLong> PrepJump |
| 467 | %type <vLong> exprlist, exprlist1 /* if > 0, points to function return | 505 | %type <vLong> exprlist, exprlist1 /* if > 0, points to function return |
| @@ -473,8 +511,7 @@ void lua_parse (TFunc *tf) | |||
| 473 | %type <vInt> ffieldlist, ffieldlist1, semicolonpart | 511 | %type <vInt> ffieldlist, ffieldlist1, semicolonpart |
| 474 | %type <vInt> lfieldlist, lfieldlist1 | 512 | %type <vInt> lfieldlist, lfieldlist1 |
| 475 | %type <vInt> parlist, parlist1, par | 513 | %type <vInt> parlist, parlist1, par |
| 476 | %type <vLong> var, singlevar, funcname | 514 | %type <vLong> var, singlevar |
| 477 | %type <pFunc> body | ||
| 478 | 515 | ||
| 479 | %left AND OR | 516 | %left AND OR |
| 480 | %left EQ NE '>' '<' LE GE | 517 | %left EQ NE '>' '<' LE GE |
| @@ -495,28 +532,21 @@ chunklist : /* empty */ | |||
| 495 | ; | 532 | ; |
| 496 | 533 | ||
| 497 | function : FUNCTION funcname body | 534 | function : FUNCTION funcname body |
| 498 | { | ||
| 499 | code_byte(PUSHFUNCTION); | ||
| 500 | code_code($3); | ||
| 501 | storesinglevar($2); | ||
| 502 | } | ||
| 503 | ; | 535 | ; |
| 504 | 536 | ||
| 505 | funcname : var { $$ =$1; init_func(); } | 537 | funcname : var { init_func($1); } |
| 506 | | varexp ':' NAME | 538 | | varexp ':' NAME |
| 507 | { | 539 | { |
| 508 | code_constant($3); | 540 | code_string($3); |
| 509 | $$ = 0; /* indexed variable */ | 541 | init_func(0); /* indexed variable */ |
| 510 | init_func(); | 542 | add_localvar(luaI_createstring("self")); |
| 511 | add_localvar(luaI_createfixedstring("self")); | ||
| 512 | } | 543 | } |
| 513 | ; | 544 | ; |
| 514 | 545 | ||
| 515 | body : '(' parlist ')' block END | 546 | body : '(' parlist ')' block END |
| 516 | { | 547 | { |
| 517 | close_func(); | 548 | close_func(); |
| 518 | $$ = currState->f; | 549 | currState->f->lineDefined = $2; |
| 519 | $$->lineDefined = $2; | ||
| 520 | currState = &stateMain; /* change back to main code */ | 550 | currState = &stateMain; /* change back to main code */ |
| 521 | } | 551 | } |
| 522 | ; | 552 | ; |
| @@ -658,7 +688,7 @@ funcvalue : varexp { $$ = 0; } | |||
| 658 | | varexp ':' NAME | 688 | | varexp ':' NAME |
| 659 | { | 689 | { |
| 660 | code_byte(PUSHSELF); | 690 | code_byte(PUSHSELF); |
| 661 | code_word(luaI_findconstant($3)); | 691 | code_word(string_constant($3)); |
| 662 | $$ = 1; | 692 | $$ = 1; |
| 663 | } | 693 | } |
| 664 | ; | 694 | ; |
| @@ -735,7 +765,7 @@ ffield : ffieldkey '=' expr1 | |||
| 735 | ; | 765 | ; |
| 736 | 766 | ||
| 737 | ffieldkey : '[' expr1 ']' | 767 | ffieldkey : '[' expr1 ']' |
| 738 | | NAME { code_constant($1); } | 768 | | NAME { code_string($1); } |
| 739 | ; | 769 | ; |
| 740 | 770 | ||
| 741 | lfieldlist : /* empty */ { $$ = 0; } | 771 | lfieldlist : /* empty */ { $$ = 0; } |
| @@ -771,7 +801,7 @@ var : singlevar { $$ = $1; } | |||
| 771 | } | 801 | } |
| 772 | | varexp '.' NAME | 802 | | varexp '.' NAME |
| 773 | { | 803 | { |
| 774 | code_constant($3); | 804 | code_string($3); |
| 775 | $$ = 0; /* indexed variable */ | 805 | $$ = 0; /* indexed variable */ |
| 776 | } | 806 | } |
| 777 | ; | 807 | ; |
| @@ -783,6 +813,7 @@ singlevar : NAME | |||
| 783 | $$ = luaI_findsymbol($1)+1; /* return positive value */ | 813 | $$ = luaI_findsymbol($1)+1; /* return positive value */ |
| 784 | else | 814 | else |
| 785 | $$ = -(local+1); /* return negative value */ | 815 | $$ = -(local+1); /* return negative value */ |
| 816 | luaI_fixstring($1); /* cannot GC variable names */ | ||
| 786 | } | 817 | } |
| 787 | ; | 818 | ; |
| 788 | 819 | ||
