diff --git a/lapi.c b/lapi.c index 60eefc80..d75a824d 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.33 1999/02/03 16:42:42 roberto Exp roberto $ +** $Id: lapi.c,v 1.34 1999/02/04 17:47:59 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -181,7 +181,8 @@ lua_Object lua_rawgettable (void) void lua_settable (void) { checkCparams(3); - luaV_settable(L->stack.top-3, 0); + luaV_settable(L->stack.top-3); + L->stack.top -= 2; /* pop table and index */ } diff --git a/lopcodes.h b/lopcodes.h index 9d29fed9..e58f3f79 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.20 1999/02/02 19:41:17 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.21 1999/02/04 16:36:16 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -55,8 +55,8 @@ SETGLOBAL,/* b x - VAR[CNST[b]]=x */ SETGLOBALDUPW,/*w x x VAR[CNST[w]]=x */ SETGLOBALDUP,/* b x x VAR[CNST[b]]=x */ -SETTABLE0,/* - v i t - t[i]=v */ -SETTABLEDUP,/* - v i t v t[i]=v */ +SETTABLEPOP,/* - v i t - t[i]=v */ +SETTABPPDUP,/* - v i t v t[i]=v */ SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ diff --git a/lparser.c b/lparser.c index 4dcae7d3..297eebd6 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.15 1999/02/04 16:36:16 roberto Exp roberto $ +** $Id: lparser.c,v 1.16 1999/02/04 17:47:59 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -490,7 +490,7 @@ static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) { static void storevar (LexState *ls, vardesc *var) { - static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLE0}; + static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLEPOP}; genstorevar(ls, var, codes); } @@ -954,7 +954,7 @@ static void exp0 (LexState *ls, vardesc *v) { static void Gexp (LexState *ls, vardesc *v) { /* Gexp -> exp0 | var '=' exp1 */ - static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABLEDUP}; + static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABPPDUP}; exp0(ls, v); if (v->k != VEXP && optional(ls, '=')) { /* assignment expression? */ unloaddot(ls, v); diff --git a/lvm.c b/lvm.c index 56f90acf..6dc34dd4 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.44 1999/02/04 16:36:16 roberto Exp roberto $ +** $Id: lvm.c,v 1.45 1999/02/04 17:47:59 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -110,64 +110,62 @@ void luaV_closure (int nelems) { ** Receives the table at top-2 and the index at top-1. */ void luaV_gettable (void) { - struct Stack *S = &L->stack; + TObject *table = L->stack.top-2; TObject *im; - if (ttype(S->top-2) != LUA_T_ARRAY) /* not a table, get "gettable" method */ - im = luaT_getimbyObj(S->top-2, IM_GETTABLE); + if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */ + im = luaT_getimbyObj(table, IM_GETTABLE); + if (ttype(im) == LUA_T_NIL) + lua_error("indexed expression not a table"); + } else { /* object is a table... */ - int tg = (S->top-2)->value.a->htag; + int tg = table->value.a->htag; im = luaT_getim(tg, IM_GETTABLE); if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */ - TObject *h = luaH_get(avalue(S->top-2), S->top-1); - if (ttype(h) != LUA_T_NIL) { - --S->top; - *(S->top-1) = *h; + TObject *h = luaH_get(avalue(table), table+1); + if (ttype(h) == LUA_T_NIL && + (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)) { + /* result is nil and there is an "index" tag method */ + luaD_callTM(im, 2, 1); /* calls it */ } - else if (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL) - luaD_callTM(im, 2, 1); else { - --S->top; - ttype(S->top-1) = LUA_T_NIL; + L->stack.top--; + *table = *h; /* "push" result into table position */ } return; } /* else it has a "gettable" method, go through to next command */ } /* object is not a table, or it has a "gettable" method */ - if (ttype(im) == LUA_T_NIL) - lua_error("indexed expression not a table"); luaD_callTM(im, 2, 1); } /* -** Function to store indexed based on values at the stack.top -** deep = 1: "deep L->stack.stack" store (with tag methods) +** Receives table at *t, index at *(t+1) and value at top. */ -void luaV_settable (TObject *t, int deep) { +void luaV_settable (TObject *t) { struct Stack *S = &L->stack; TObject *im; - if (ttype(t) != LUA_T_ARRAY) /* not a table, get "settable" method */ + if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */ im = luaT_getimbyObj(t, IM_SETTABLE); + if (ttype(im) == LUA_T_NIL) + lua_error("indexed expression not a table"); + } else { /* object is a table... */ im = luaT_getim(avalue(t)->htag, IM_SETTABLE); if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */ luaH_set(avalue(t), t+1, S->top-1); - /* if deep, pop only value; otherwise, pop table, index and value */ - S->top -= (deep) ? 1 : 3; + S->top--; /* pop value */ return; } /* else it has a "settable" method, go through to next command */ } /* object is not a table, or it has a "settable" method */ - if (ttype(im) == LUA_T_NIL) - lua_error("indexed expression not a table"); - if (deep) { /* table and index were not on top; copy them */ - *(S->top+1) = *(L->stack.top-1); - *(S->top) = *(t+1); - *(S->top-1) = *t; - S->top += 2; /* WARNING: caller must assure stack space */ - } + /* prepare arguments and call the tag method */ + *(S->top+1) = *(L->stack.top-1); + *(S->top) = *(t+1); + *(S->top-1) = *t; + S->top += 2; /* WARNING: caller must assure stack space */ luaD_callTM(im, 3, 0); } @@ -421,19 +419,21 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) { luaV_setglobal(tsvalue(&consts[aux])); break; - case SETTABLE0: - luaV_settable(S->top-3, 0); + case SETTABLEPOP: + luaV_settable(S->top-3); + S->top -= 2; /* pop table and index */ break; - case SETTABLEDUP: { + case SETTABPPDUP: { TObject temp = *(S->top-1); - luaV_settable(S->top-3, 0); - *(S->top++) = temp; + luaV_settable(S->top-3); + S->top--; /* pop index (temp goes into "table" position) */ + *(S->top-1) = temp; break; } case SETTABLE: - luaV_settable(S->top-3-(*pc++), 1); + luaV_settable(S->top-3-(*pc++)); break; case SETLISTW: aux += highbyte(*pc++); diff --git a/lvm.h b/lvm.h index ee962945..ed66403b 100644 --- a/lvm.h +++ b/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 1.6 1998/12/30 13:16:50 roberto Exp roberto $ +** $Id: lvm.h,v 1.7 1998/12/30 17:26:49 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -22,7 +22,7 @@ int luaV_tonumber (TObject *obj); int luaV_tostring (TObject *obj); void luaV_setn (Hash *t, int val); void luaV_gettable (void); -void luaV_settable (TObject *t, int deep); +void luaV_settable (TObject *t); void luaV_rawsettable (TObject *t); void luaV_getglobal (TaggedString *ts); void luaV_setglobal (TaggedString *ts);