diff options
Diffstat (limited to '')
| -rw-r--r-- | lopcodes.h | 13 | ||||
| -rw-r--r-- | lua.stx | 68 | ||||
| -rw-r--r-- | lvm.c | 16 |
3 files changed, 74 insertions, 23 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.10 1997/10/16 21:14:47 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.11 1997/10/24 17:17:24 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 | */ |
| @@ -67,6 +67,17 @@ GETGLOBALW,/* w - VAR[CNST[w]] */ | |||
| 67 | 67 | ||
| 68 | GETTABLE,/* - i t t[i] */ | 68 | GETTABLE,/* - i t t[i] */ |
| 69 | 69 | ||
| 70 | GETDOTTED,/* b t t[CONST[b]] */ | ||
| 71 | GETDOTTED0,/* - t t[CONST[0]] */ | ||
| 72 | GETDOTTED1,/* - t t[CONST[1]] */ | ||
| 73 | GETDOTTED2,/* - t t[CONST[2]] */ | ||
| 74 | GETDOTTED3,/* - t t[CONST[3]] */ | ||
| 75 | GETDOTTED4,/* - t t[CONST[4]] */ | ||
| 76 | GETDOTTED5,/* - t t[CONST[5]] */ | ||
| 77 | GETDOTTED6,/* - t t[CONST[6]] */ | ||
| 78 | GETDOTTED7,/* - t t[CONST[7]] */ | ||
| 79 | GETDOTTEDW,/* w t t[CONST[w]] */ | ||
| 80 | |||
| 70 | PUSHSELF,/* b t t t[CNST[b]] */ | 81 | PUSHSELF,/* b t t t[CNST[b]] */ |
| 71 | PUSHSELFW,/* w t t t[CNST[w]] */ | 82 | PUSHSELFW,/* w t t t[CNST[w]] */ |
| 72 | 83 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | %{ | 1 | %{ |
| 2 | /* | 2 | /* |
| 3 | ** $Id: lua.stx,v 1.12 1997/10/18 16:46:39 roberto Exp roberto $ | 3 | ** $Id: lua.stx,v 1.13 1997/10/24 17:17:24 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 | */ |
| @@ -31,6 +31,8 @@ int luaY_parse (void); | |||
| 31 | /* maximum number of local variables */ | 31 | /* maximum number of local variables */ |
| 32 | #define MAXLOCALS 32 | 32 | #define MAXLOCALS 32 |
| 33 | 33 | ||
| 34 | #define MINGLOBAL (MAXLOCALS+1) | ||
| 35 | |||
| 34 | /* maximum number of variables in a multiple assignment */ | 36 | /* maximum number of variables in a multiple assignment */ |
| 35 | #define MAXVAR 32 | 37 | #define MAXVAR 32 |
| 36 | 38 | ||
| @@ -41,13 +43,21 @@ int luaY_parse (void); | |||
| 41 | #define MAXUPVALUES 16 | 43 | #define MAXUPVALUES 16 |
| 42 | 44 | ||
| 43 | /* | 45 | /* |
| 44 | ** Variable descriptor: if n>0, represents global variable indexed | 46 | ** Variable descriptor: |
| 45 | ** by (n-1); if n<0, represents local variable index (-n)-1; | 47 | ** if 0<n<MINGLOBAL, represents local variable indexed by (n-1); |
| 46 | ** if n==0, represents an indexed variable (table and index on top of stack) | 48 | ** if MINGLOBAL<=n, represents global variable at position (n-MINGLOBAL); |
| 49 | ** if n<0, indexed variable with index (-n)-1 (table on top of stack); | ||
| 50 | ** if n==0, an indexed variable (table and index on top of stack) | ||
| 47 | ** Must be long to store negative Word values. | 51 | ** Must be long to store negative Word values. |
| 48 | */ | 52 | */ |
| 49 | typedef long vardesc; | 53 | typedef long vardesc; |
| 50 | 54 | ||
| 55 | #define isglobal(v) (MINGLOBAL<=(v)) | ||
| 56 | #define globalindex(v) ((v)-MINGLOBAL) | ||
| 57 | #define islocal(v) (0<(v) && (v)<MINGLOBAL) | ||
| 58 | #define localindex(v) ((v)-1) | ||
| 59 | #define isdot(v) (v<0) | ||
| 60 | #define dotindex(v) ((-(v))-1) | ||
| 51 | 61 | ||
| 52 | /* state needed to generate code for a given function */ | 62 | /* state needed to generate code for a given function */ |
| 53 | typedef struct State { | 63 | typedef struct State { |
| @@ -313,11 +323,25 @@ static void add_localvar (TaggedString *name) | |||
| 313 | currState->nlocalvar++; | 323 | currState->nlocalvar++; |
| 314 | } | 324 | } |
| 315 | 325 | ||
| 326 | |||
| 327 | /* | ||
| 328 | ** dotted variables <a.x> must be stored like regular indexed vars <a["x"]> | ||
| 329 | */ | ||
| 330 | static vardesc var2store (vardesc var) | ||
| 331 | { | ||
| 332 | if (isdot(var)) { | ||
| 333 | code_constant(dotindex(var)); | ||
| 334 | var = 0; | ||
| 335 | } | ||
| 336 | return var; | ||
| 337 | } | ||
| 338 | |||
| 339 | |||
| 316 | static void add_varbuffer (vardesc var, int n) | 340 | static void add_varbuffer (vardesc var, int n) |
| 317 | { | 341 | { |
| 318 | if (n >= MAXVAR) | 342 | if (n >= MAXVAR) |
| 319 | luaY_error("variable buffer overflow"); | 343 | luaY_error("variable buffer overflow"); |
| 320 | currState->varbuffer[n] = var; | 344 | currState->varbuffer[n] = var2store(var); |
| 321 | } | 345 | } |
| 322 | 346 | ||
| 323 | 347 | ||
| @@ -338,9 +362,9 @@ static vardesc singlevar (TaggedString *n, State *st) | |||
| 338 | for (l=1; l<=(st-mainState); l++) | 362 | for (l=1; l<=(st-mainState); l++) |
| 339 | if (aux_localname(n, st-l) >= 0) | 363 | if (aux_localname(n, st-l) >= 0) |
| 340 | luaY_syntaxerror("cannot access a variable in outer scope", n->str); | 364 | luaY_syntaxerror("cannot access a variable in outer scope", n->str); |
| 341 | return string_constant(n, st)+1; /* positive value */ | 365 | return string_constant(n, st)+MINGLOBAL; /* global value */ |
| 342 | } | 366 | } |
| 343 | else return -(i+1); /* negative value */ | 367 | else return i+1; /* local value */ |
| 344 | } | 368 | } |
| 345 | 369 | ||
| 346 | 370 | ||
| @@ -353,7 +377,7 @@ static int indexupvalue (TaggedString *n) | |||
| 353 | return i; | 377 | return i; |
| 354 | } | 378 | } |
| 355 | /* new one */ | 379 | /* new one */ |
| 356 | if (++currState->nupvalues > MAXUPVALUES) | 380 | if (++(currState->nupvalues) > MAXUPVALUES) |
| 357 | luaY_error("too many upvalues in a single function"); | 381 | luaY_error("too many upvalues in a single function"); |
| 358 | currState->upvalues[i] = v; /* i = currState->nupvalues - 1 */ | 382 | currState->upvalues[i] = v; /* i = currState->nupvalues - 1 */ |
| 359 | return i; | 383 | return i; |
| @@ -435,25 +459,27 @@ static void code_args (int nparams, int dots) | |||
| 435 | } | 459 | } |
| 436 | 460 | ||
| 437 | 461 | ||
| 438 | static void lua_pushvar (vardesc number) | 462 | static void lua_pushvar (vardesc var) |
| 439 | { | 463 | { |
| 440 | if (number > 0) /* global var */ | 464 | if (isglobal(var)) |
| 441 | code_oparg(GETGLOBAL, 8, number-1, 1); | 465 | code_oparg(GETGLOBAL, 8, globalindex(var), 1); |
| 442 | else if (number < 0) /* local var */ | 466 | else if (islocal(var)) |
| 443 | code_oparg(PUSHLOCAL, 8, (-number)-1, 1); | 467 | code_oparg(PUSHLOCAL, 8, localindex(var), 1); |
| 468 | else if (isdot(var)) | ||
| 469 | code_oparg(GETDOTTED, 8, dotindex(var), 0); | ||
| 444 | else | 470 | else |
| 445 | code_pop(GETTABLE); | 471 | code_pop(GETTABLE); |
| 446 | } | 472 | } |
| 447 | 473 | ||
| 448 | 474 | ||
| 449 | static void storevar (vardesc number) | 475 | static void storevar (vardesc var) |
| 450 | { | 476 | { |
| 451 | if (number == 0) /* indexed var */ | 477 | if (var == 0) /* indexed var */ |
| 452 | code_opcode(SETTABLE0, -3); | 478 | code_opcode(SETTABLE0, -3); |
| 453 | else if (number > 0) /* global var */ | 479 | else if (isglobal(var)) |
| 454 | code_oparg(SETGLOBAL, 8, number-1, -1); | 480 | code_oparg(SETGLOBAL, 8, globalindex(var), -1); |
| 455 | else /* number < 0 - local var */ | 481 | else /* local var */ |
| 456 | code_oparg(SETLOCAL, 8, (-number)-1, -1); | 482 | code_oparg(SETLOCAL, 8, localindex(var), -1); |
| 457 | } | 483 | } |
| 458 | 484 | ||
| 459 | 485 | ||
| @@ -698,7 +724,7 @@ block : {$<vInt>$ = currState->nlocalvar;} chunk | |||
| 698 | } | 724 | } |
| 699 | ; | 725 | ; |
| 700 | 726 | ||
| 701 | funcname : var { init_func(); $$ = $1; } | 727 | funcname : var { $$ = var2store($1); init_func(); } |
| 702 | | varexp ':' NAME | 728 | | varexp ':' NAME |
| 703 | { | 729 | { |
| 704 | code_string($3); | 730 | code_string($3); |
| @@ -872,7 +898,7 @@ varlist1 : var { $$ = 1; add_varbuffer($1, 0); } | |||
| 872 | 898 | ||
| 873 | var : NAME { $$ = singlevar($1, currState); } | 899 | var : NAME { $$ = singlevar($1, currState); } |
| 874 | | varexp '[' expr1 ']' { $$ = 0; } /* indexed variable */ | 900 | | varexp '[' expr1 ']' { $$ = 0; } /* indexed variable */ |
| 875 | | varexp '.' NAME { code_string($3); $$ = 0; }/* ind. var. */ | 901 | | varexp '.' NAME { $$ = (-string_constant($3, currState))-1; } |
| 876 | ; | 902 | ; |
| 877 | 903 | ||
| 878 | varexp : var { lua_pushvar($1); } | 904 | varexp : var { lua_pushvar($1); } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.10 1997/10/16 10:59:34 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.11 1997/10/24 17:17:24 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 | */ |
| @@ -335,6 +335,20 @@ StkId luaV_execute (Closure *cl, StkId base) | |||
| 335 | luaV_gettable(); | 335 | luaV_gettable(); |
| 336 | break; | 336 | break; |
| 337 | 337 | ||
| 338 | case GETDOTTEDW: | ||
| 339 | aux = next_word(pc); goto getdotted; | ||
| 340 | |||
| 341 | case GETDOTTED: | ||
| 342 | aux = *pc++; goto getdotted; | ||
| 343 | |||
| 344 | case GETDOTTED0: case GETDOTTED1: case GETDOTTED2: case GETDOTTED3: | ||
| 345 | case GETDOTTED4: case GETDOTTED5: case GETDOTTED6: case GETDOTTED7: | ||
| 346 | aux -= GETDOTTED0; | ||
| 347 | getdotted: | ||
| 348 | *luaD_stack.top++ = consts[aux]; | ||
| 349 | luaV_gettable(); | ||
| 350 | break; | ||
| 351 | |||
| 338 | case PUSHSELFW: | 352 | case PUSHSELFW: |
| 339 | aux = next_word(pc); goto pushself; | 353 | aux = next_word(pc); goto pushself; |
| 340 | 354 | ||
