diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-10-24 16:40:29 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-10-24 16:40:29 -0200 |
commit | 18cd7adac6e5745cad93fecacbe6a2ed16dd3e18 (patch) | |
tree | 5f21e7ec2add2058933cebff6e575a107a2e2771 /lua.stx | |
parent | 41223a01eccafa03990ca6d89124b0955001a9ce (diff) | |
download | lua-18cd7adac6e5745cad93fecacbe6a2ed16dd3e18.tar.gz lua-18cd7adac6e5745cad93fecacbe6a2ed16dd3e18.tar.bz2 lua-18cd7adac6e5745cad93fecacbe6a2ed16dd3e18.zip |
optimization to handle <a.x> (new opcode).
Diffstat (limited to 'lua.stx')
-rw-r--r-- | lua.stx | 68 |
1 files changed, 47 insertions, 21 deletions
@@ -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); } |