lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 18cd7adac6e5745cad93fecacbe6a2ed16dd3e18
parent 41223a01eccafa03990ca6d89124b0955001a9ce
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Fri, 24 Oct 1997 16:40:08 -0200

optimization to handle <a.x> (new opcode).

Diffstat:
Mlopcodes.h | 13++++++++++++-
Mlua.stx | 68+++++++++++++++++++++++++++++++++++++++++++++++---------------------
Mlvm.c | 16+++++++++++++++-
3 files changed, 74 insertions(+), 23 deletions(-)

diff --git a/lopcodes.h b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.10 1997/10/16 21:14:47 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.11 1997/10/24 17:17:24 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -67,6 +67,17 @@ GETGLOBALW,/* w - VAR[CNST[w]] */ GETTABLE,/* - i t t[i] */ +GETDOTTED,/* b t t[CONST[b]] */ +GETDOTTED0,/* - t t[CONST[0]] */ +GETDOTTED1,/* - t t[CONST[1]] */ +GETDOTTED2,/* - t t[CONST[2]] */ +GETDOTTED3,/* - t t[CONST[3]] */ +GETDOTTED4,/* - t t[CONST[4]] */ +GETDOTTED5,/* - t t[CONST[5]] */ +GETDOTTED6,/* - t t[CONST[6]] */ +GETDOTTED7,/* - t t[CONST[7]] */ +GETDOTTEDW,/* w t t[CONST[w]] */ + PUSHSELF,/* b t t t[CNST[b]] */ PUSHSELFW,/* w t t t[CNST[w]] */ diff --git a/lua.stx b/lua.stx @@ -1,6 +1,6 @@ %{ /* -** $Id: lua.stx,v 1.12 1997/10/18 16:46:39 roberto Exp roberto $ +** $Id: lua.stx,v 1.13 1997/10/24 17:17:24 roberto Exp roberto $ ** Syntax analizer and code generator ** See Copyright Notice in lua.h */ @@ -31,6 +31,8 @@ int luaY_parse (void); /* maximum number of local variables */ #define MAXLOCALS 32 +#define MINGLOBAL (MAXLOCALS+1) + /* maximum number of variables in a multiple assignment */ #define MAXVAR 32 @@ -41,13 +43,21 @@ int luaY_parse (void); #define MAXUPVALUES 16 /* -** Variable descriptor: if n>0, represents global variable indexed -** by (n-1); if n<0, represents local variable index (-n)-1; -** if n==0, represents an indexed variable (table and index on top of stack) +** Variable descriptor: +** if 0<n<MINGLOBAL, represents local variable indexed by (n-1); +** if MINGLOBAL<=n, represents global variable at position (n-MINGLOBAL); +** if n<0, indexed variable with index (-n)-1 (table on top of stack); +** if n==0, an indexed variable (table and index on top of stack) ** Must be long to store negative Word values. */ typedef long vardesc; +#define isglobal(v) (MINGLOBAL<=(v)) +#define globalindex(v) ((v)-MINGLOBAL) +#define islocal(v) (0<(v) && (v)<MINGLOBAL) +#define localindex(v) ((v)-1) +#define isdot(v) (v<0) +#define dotindex(v) ((-(v))-1) /* state needed to generate code for a given function */ typedef struct State { @@ -313,11 +323,25 @@ static void add_localvar (TaggedString *name) currState->nlocalvar++; } + +/* +** dotted variables <a.x> must be stored like regular indexed vars <a["x"]> +*/ +static vardesc var2store (vardesc var) +{ + if (isdot(var)) { + code_constant(dotindex(var)); + var = 0; + } + return var; +} + + static void add_varbuffer (vardesc var, int n) { if (n >= MAXVAR) luaY_error("variable buffer overflow"); - currState->varbuffer[n] = var; + currState->varbuffer[n] = var2store(var); } @@ -338,9 +362,9 @@ static vardesc singlevar (TaggedString *n, State *st) for (l=1; l<=(st-mainState); l++) if (aux_localname(n, st-l) >= 0) luaY_syntaxerror("cannot access a variable in outer scope", n->str); - return string_constant(n, st)+1; /* positive value */ + return string_constant(n, st)+MINGLOBAL; /* global value */ } - else return -(i+1); /* negative value */ + else return i+1; /* local value */ } @@ -353,7 +377,7 @@ static int indexupvalue (TaggedString *n) return i; } /* new one */ - if (++currState->nupvalues > MAXUPVALUES) + if (++(currState->nupvalues) > MAXUPVALUES) luaY_error("too many upvalues in a single function"); currState->upvalues[i] = v; /* i = currState->nupvalues - 1 */ return i; @@ -435,25 +459,27 @@ static void code_args (int nparams, int dots) } -static void lua_pushvar (vardesc number) +static void lua_pushvar (vardesc var) { - if (number > 0) /* global var */ - code_oparg(GETGLOBAL, 8, number-1, 1); - else if (number < 0) /* local var */ - code_oparg(PUSHLOCAL, 8, (-number)-1, 1); + if (isglobal(var)) + code_oparg(GETGLOBAL, 8, globalindex(var), 1); + else if (islocal(var)) + code_oparg(PUSHLOCAL, 8, localindex(var), 1); + else if (isdot(var)) + code_oparg(GETDOTTED, 8, dotindex(var), 0); else code_pop(GETTABLE); } -static void storevar (vardesc number) +static void storevar (vardesc var) { - if (number == 0) /* indexed var */ + if (var == 0) /* indexed var */ code_opcode(SETTABLE0, -3); - else if (number > 0) /* global var */ - code_oparg(SETGLOBAL, 8, number-1, -1); - else /* number < 0 - local var */ - code_oparg(SETLOCAL, 8, (-number)-1, -1); + else if (isglobal(var)) + code_oparg(SETGLOBAL, 8, globalindex(var), -1); + else /* local var */ + code_oparg(SETLOCAL, 8, localindex(var), -1); } @@ -698,7 +724,7 @@ block : {$<vInt>$ = currState->nlocalvar;} chunk } ; -funcname : var { init_func(); $$ = $1; } +funcname : var { $$ = var2store($1); init_func(); } | varexp ':' NAME { code_string($3); @@ -872,7 +898,7 @@ varlist1 : var { $$ = 1; add_varbuffer($1, 0); } var : NAME { $$ = singlevar($1, currState); } | varexp '[' expr1 ']' { $$ = 0; } /* indexed variable */ - | varexp '.' NAME { code_string($3); $$ = 0; }/* ind. var. */ + | varexp '.' NAME { $$ = (-string_constant($3, currState))-1; } ; varexp : var { lua_pushvar($1); } diff --git a/lvm.c b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.10 1997/10/16 10:59:34 roberto Exp roberto $ +** $Id: lvm.c,v 1.11 1997/10/24 17:17:24 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -335,6 +335,20 @@ StkId luaV_execute (Closure *cl, StkId base) luaV_gettable(); break; + case GETDOTTEDW: + aux = next_word(pc); goto getdotted; + + case GETDOTTED: + aux = *pc++; goto getdotted; + + case GETDOTTED0: case GETDOTTED1: case GETDOTTED2: case GETDOTTED3: + case GETDOTTED4: case GETDOTTED5: case GETDOTTED6: case GETDOTTED7: + aux -= GETDOTTED0; + getdotted: + *luaD_stack.top++ = consts[aux]; + luaV_gettable(); + break; + case PUSHSELFW: aux = next_word(pc); goto pushself;