diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-12-01 17:50:08 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-12-01 17:50:08 -0200 |
commit | fe237ad8085f34e89fcd3610a9771215af63f03f (patch) | |
tree | f7ee5d8f7d1ffb74e94f049aa6f31eb03606cdf6 /lvm.c | |
parent | 3181dfefee40b9a424b80aa779c671f5f458904c (diff) | |
download | lua-github-fe237ad8085f34e89fcd3610a9771215af63f03f.tar.gz |
fixed stack; first version.
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 351 |
1 files changed, 178 insertions, 173 deletions
@@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.67 1999/11/25 18:59:43 roberto Exp roberto $ +** $Id: lvm.c,v 1.68 1999/11/29 18:27:49 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -83,13 +83,12 @@ void luaV_setn (lua_State *L, Hash *t, int val) { void luaV_closure (lua_State *L, int nelems) { if (nelems > 0) { - struct Stack *S = &L->stack; Closure *c = luaF_newclosure(L, nelems); - c->consts[0] = *(S->top-1); - memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject)); - S->top -= nelems; - ttype(S->top-1) = LUA_T_CLOSURE; - (S->top-1)->value.cl = c; + c->consts[0] = *(L->top-1); + L->top -= nelems; + memcpy(&c->consts[1], L->top-1, nelems*sizeof(TObject)); + ttype(L->top-1) = LUA_T_CLOSURE; + (L->top-1)->value.cl = c; } } @@ -99,7 +98,7 @@ void luaV_closure (lua_State *L, int nelems) { ** Receives the table at top-2 and the index at top-1. */ void luaV_gettable (lua_State *L) { - TObject *table = L->stack.top-2; + TObject *table = L->top-2; const TObject *im; if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */ im = luaT_getimbyObj(L, table, IM_GETTABLE); @@ -117,7 +116,7 @@ void luaV_gettable (lua_State *L) { luaD_callTM(L, im, 2, 1); /* calls it */ } else { - L->stack.top--; + L->top--; *table = *h; /* "push" result into table position */ } return; @@ -132,8 +131,7 @@ void luaV_gettable (lua_State *L) { /* ** Receives table at *t, index at *(t+1) and value at top. */ -void luaV_settable (lua_State *L, const TObject *t) { - struct Stack *S = &L->stack; +void luaV_settable (lua_State *L, StkId t) { const TObject *im; if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */ im = luaT_getimbyObj(L, t, IM_SETTABLE); @@ -143,29 +141,28 @@ void luaV_settable (lua_State *L, const TObject *t) { else { /* object is a table... */ im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE); if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */ - luaH_set(L, avalue(t), t+1, S->top-1); - S->top--; /* pop value */ + luaH_set(L, avalue(t), t+1, L->top-1); + L->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 */ /* 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 */ + *(L->top+1) = *(L->top-1); + *(L->top) = *(t+1); + *(L->top-1) = *t; + L->top += 2; /* WARNING: caller must assure stack space */ luaD_callTM(L, im, 3, 0); } -void luaV_rawsettable (lua_State *L, const TObject *t) { +void luaV_rawsettable (lua_State *L, StkId t) { if (ttype(t) != LUA_T_ARRAY) lua_error(L, "indexed expression not a table"); else { - struct Stack *S = &L->stack; - luaH_set(L, avalue(t), t+1, S->top-1); - S->top -= 3; + luaH_set(L, avalue(t), t+1, L->top-1); + L->top -= 3; } } @@ -178,17 +175,16 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv) { case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: { TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL); if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */ - struct Stack *S = &L->stack; - ttype(S->top) = LUA_T_STRING; - tsvalue(S->top) = gv->name; /* global name */ - S->top++; - *S->top++ = *value; + ttype(L->top) = LUA_T_STRING; + tsvalue(L->top) = gv->name; /* global name */ + L->top++; + *L->top++ = *value; luaD_callTM(L, im, 2, 1); return; } /* else no tag method: go through to default behavior */ } - default: *L->stack.top++ = *value; /* default behavior */ + default: *L->top++ = *value; /* default behavior */ } } @@ -197,26 +193,26 @@ void luaV_setglobal (lua_State *L, GlobalVar *gv) { const TObject *oldvalue = &gv->value; const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL); if (ttype(im) == LUA_T_NIL) /* is there a tag method? */ - gv->value = *(--L->stack.top); + gv->value = *(--L->top); else { /* WARNING: caller must assure stack space */ - struct Stack *S = &L->stack; TObject newvalue; - newvalue = *(S->top-1); - ttype(S->top-1) = LUA_T_STRING; - tsvalue(S->top-1) = gv->name; - *S->top++ = *oldvalue; - *S->top++ = newvalue; + newvalue = *(L->top-1); + ttype(L->top-1) = LUA_T_STRING; + tsvalue(L->top-1) = gv->name; + *L->top++ = *oldvalue; + *L->top++ = newvalue; luaD_callTM(L, im, 3, 0); } } -static void call_binTM (lua_State *L, IMS event, const char *msg) { +static void call_binTM (lua_State *L, StkId top, IMS event, const char *msg) { /* try first operand */ - const TObject *im = luaT_getimbyObj(L, L->stack.top-2, event); + const TObject *im = luaT_getimbyObj(L, top-2, event); + L->top = top; if (ttype(im) == LUA_T_NIL) { - im = luaT_getimbyObj(L, L->stack.top-1, event); /* try second operand */ + im = luaT_getimbyObj(L, top-1, event); /* try second operand */ if (ttype(im) == LUA_T_NIL) { im = luaT_getim(L, 0, event); /* try a 'global' i.m. */ if (ttype(im) == LUA_T_NIL) @@ -228,8 +224,8 @@ static void call_binTM (lua_State *L, IMS event, const char *msg) { } -static void call_arith (lua_State *L, IMS event) { - call_binTM(L, event, "unexpected type in arithmetic operation"); +static void call_arith (lua_State *L, StkId top, IMS event) { + call_binTM(L, top, event, "unexpected type in arithmetic operation"); } @@ -249,11 +245,10 @@ static int luaV_strcomp (const char *l, long ll, const char *r, long lr) { } } -void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal, - lua_Type ttype_great, IMS op) { - struct Stack *S = &L->stack; - const TObject *l = S->top-2; - const TObject *r = S->top-1; +void luaV_comparison (lua_State *L, StkId top, lua_Type ttype_less, + lua_Type ttype_equal, lua_Type ttype_great, IMS op) { + const TObject *l = top-2; + const TObject *r = top-1; real result; if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) result = nvalue(l)-nvalue(r); @@ -261,39 +256,41 @@ void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal, result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len, svalue(r), tsvalue(r)->u.s.len); else { - call_binTM(L, op, "unexpected type in comparison"); + call_binTM(L, top, op, "unexpected type in comparison"); return; } - S->top--; - nvalue(S->top-1) = 1; - ttype(S->top-1) = (result < 0) ? ttype_less : + nvalue(top-2) = 1; + ttype(top-2) = (result < 0) ? ttype_less : (result == 0) ? ttype_equal : ttype_great; } -void luaV_pack (lua_State *L, StkId firstel, int nvararg, TObject *tab) { - TObject *firstelem = L->stack.stack+firstel; +void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { int i; Hash *htab; - if (nvararg < 0) nvararg = 0; - htab = avalue(tab) = luaH_new(L, nvararg+1); /* +1 for field 'n' */ + htab = avalue(tab) = luaH_new(L, nvararg+1); /* +1 for field `n' */ ttype(tab) = LUA_T_ARRAY; for (i=0; i<nvararg; i++) luaH_setint(L, htab, i+1, firstelem+i); - luaV_setn(L, htab, nvararg); /* store counter in field "n" */ + luaV_setn(L, htab, nvararg); /* store counter in field `n' */ } -static void adjust_varargs (lua_State *L, StkId first_extra_arg) { +static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { TObject arg; - luaV_pack(L, first_extra_arg, - (L->stack.top-L->stack.stack)-first_extra_arg, &arg); - luaD_adjusttop(L, first_extra_arg); - *L->stack.top++ = arg; + int nvararg = (L->top-base) - nfixargs; + if (nvararg < 0) { + luaV_pack(L, base, 0, &arg); + luaD_adjusttop(L, base, nfixargs); + } + else { + luaV_pack(L, base+nfixargs, nvararg, &arg); + L->top = base+nfixargs; + } + *L->top++ = arg; } - /* ** Execute the given opcode, until a RET. Parameters are between ** [stack+base,top). Returns n such that the the results are between @@ -301,25 +298,26 @@ static void adjust_varargs (lua_State *L, StkId first_extra_arg) { */ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base) { - struct Stack *S = &L->stack; /* to optimize */ + register StkId top; /* keep top local, for performance */ register const Byte *pc = tf->code; const TObject *consts = tf->consts; if (L->callhook) luaD_callHook(L, base, tf, 0); luaD_checkstack(L, (*pc++)+EXTRA_STACK); if (*pc < ZEROVARARG) - luaD_adjusttop(L, base+*(pc++)); + luaD_adjusttop(L, base, *(pc++)); else { /* varargs */ + adjust_varargs(L, base, (*pc++)-ZEROVARARG); luaC_checkGC(L); - adjust_varargs(L, base+(*pc++)-ZEROVARARG); } + top = L->top; for (;;) { register int aux = 0; switchentry: switch ((OpCode)*pc++) { case ENDCODE: - S->top = S->stack + base; + top = base; goto ret; case RETCODE: @@ -327,238 +325,240 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, goto ret; case CALL: aux = *pc++; - luaD_call(L, (S->stack+base) + *pc++, aux); + L->top = top; + luaD_call(L, base+(*pc++), aux); + top = L->top; break; case TAILCALL: aux = *pc++; - luaD_call(L, (S->stack+base) + *pc++, MULT_RET); + L->top = top; + luaD_call(L, base+(*pc++), MULT_RET); + top = L->top; base += aux; goto ret; case PUSHNIL: aux = *pc++; do { - ttype(S->top++) = LUA_T_NIL; + ttype(top++) = LUA_T_NIL; } while (aux--); break; case POP: aux = *pc++; - S->top -= aux; + top -= aux; break; case PUSHNUMBERW: aux += highbyte(L, *pc++); case PUSHNUMBER: aux += *pc++; - ttype(S->top) = LUA_T_NUMBER; - nvalue(S->top) = aux; - S->top++; + ttype(top) = LUA_T_NUMBER; + nvalue(top) = aux; + top++; break; case PUSHNUMBERNEGW: aux += highbyte(L, *pc++); case PUSHNUMBERNEG: aux += *pc++; - ttype(S->top) = LUA_T_NUMBER; - nvalue(S->top) = -aux; - S->top++; + ttype(top) = LUA_T_NUMBER; + nvalue(top) = -aux; + top++; break; case PUSHCONSTANTW: aux += highbyte(L, *pc++); case PUSHCONSTANT: aux += *pc++; - *S->top++ = consts[aux]; + *top++ = consts[aux]; break; case PUSHUPVALUE: aux = *pc++; - *S->top++ = cl->consts[aux+1]; + *top++ = cl->consts[aux+1]; break; case PUSHLOCAL: aux = *pc++; - *S->top++ = *((S->stack+base) + aux); + *top++ = *(base+aux); break; case GETGLOBALW: aux += highbyte(L, *pc++); case GETGLOBAL: aux += *pc++; + L->top = top; luaV_getglobal(L, tsvalue(&consts[aux])->u.s.gv); + top++; break; case GETTABLE: + L->top = top; luaV_gettable(L); + top--; break; case GETDOTTEDW: aux += highbyte(L, *pc++); case GETDOTTED: aux += *pc++; - *S->top++ = consts[aux]; + *top++ = consts[aux]; + L->top = top; luaV_gettable(L); + top--; break; case PUSHSELFW: aux += highbyte(L, *pc++); case PUSHSELF: aux += *pc++; { TObject receiver; - receiver = *(S->top-1); - *S->top++ = consts[aux]; + receiver = *(top-1); + *top++ = consts[aux]; + L->top = top; luaV_gettable(L); - *S->top++ = receiver; + *(top-1) = receiver; break; } case CREATEARRAYW: aux += highbyte(L, *pc++); case CREATEARRAY: aux += *pc++; + L->top = top; luaC_checkGC(L); - avalue(S->top) = luaH_new(L, aux); - ttype(S->top) = LUA_T_ARRAY; - S->top++; + avalue(top) = luaH_new(L, aux); + ttype(top) = LUA_T_ARRAY; + top++; break; case SETLOCAL: aux = *pc++; - *((S->stack+base) + aux) = *(--S->top); + *(base+aux) = *(--top); break; case SETGLOBALW: aux += highbyte(L, *pc++); case SETGLOBAL: aux += *pc++; + L->top = top; luaV_setglobal(L, tsvalue(&consts[aux])->u.s.gv); + top--; break; case SETTABLEPOP: - luaV_settable(L, S->top-3); - S->top -= 2; /* pop table and index */ + L->top = top; + luaV_settable(L, top-3); + top -= 3; /* pop table, index, and value */ break; case SETTABLE: - luaV_settable(L, S->top-3-(*pc++)); + L->top = top; + luaV_settable(L, top-3-(*pc++)); + top--; /* pop value */ break; case SETLISTW: aux += highbyte(L, *pc++); case SETLIST: aux += *pc++; { int n = *(pc++); - Hash *arr = avalue(S->top-n-1); + Hash *arr = avalue(top-n-1); aux *= LFIELDS_PER_FLUSH; for (; n; n--) - luaH_setint(L, arr, n+aux, --S->top); + luaH_setint(L, arr, n+aux, --top); break; } case SETMAP: aux = *pc++; { - Hash *arr = avalue(S->top-(2*aux)-3); + Hash *arr = avalue(top-(2*aux)-3); do { - luaH_set(L, arr, S->top-2, S->top-1); - S->top-=2; + luaH_set(L, arr, top-2, top-1); + top-=2; } while (aux--); break; } case NEQOP: aux = 1; case EQOP: { - int res = luaO_equalObj(S->top-2, S->top-1); + int res = luaO_equalObj(top-2, top-1); if (aux) res = !res; - S->top--; - ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; - nvalue(S->top-1) = 1; + top--; + ttype(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; + nvalue(top-1) = 1; break; } case LTOP: - luaV_comparison(L, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); + luaV_comparison(L, top, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); + top--; break; case LEOP: - luaV_comparison(L, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE); + luaV_comparison(L, top, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE); + top--; break; case GTOP: - luaV_comparison(L, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT); + luaV_comparison(L, top, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT); + top--; break; case GEOP: - luaV_comparison(L, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE); + luaV_comparison(L, top, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE); + top--; break; - case ADDOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(L, IM_ADD); - else { - nvalue(l) += nvalue(r); - --S->top; - } + case ADDOP: + if (tonumber(top-1) || tonumber(top-2)) + call_arith(L, top, IM_ADD); + else + nvalue(top-2) += nvalue(top-1); + top--; break; - } - case SUBOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(L, IM_SUB); - else { - nvalue(l) -= nvalue(r); - --S->top; - } + case SUBOP: + if (tonumber(top-1) || tonumber(top-2)) + call_arith(L, top, IM_SUB); + else + nvalue(top-2) -= nvalue(top-1); + top--; break; - } - case MULTOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(L, IM_MUL); - else { - nvalue(l) *= nvalue(r); - --S->top; - } + case MULTOP: + if (tonumber(top-1) || tonumber(top-2)) + call_arith(L, top, IM_MUL); + else + nvalue(top-2) *= nvalue(top-1); + top--; break; - } - case DIVOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(L, IM_DIV); - else { - nvalue(l) /= nvalue(r); - --S->top; - } + case DIVOP: + if (tonumber(top-1) || tonumber(top-2)) + call_arith(L, top, IM_DIV); + else + nvalue(top-2) /= nvalue(top-1); + top--; break; - } case POWOP: - call_binTM(L, IM_POW, "undefined operation"); + call_binTM(L, top, IM_POW, "undefined operation"); + top--; break; - case CONCOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tostring(L, l) || tostring(L, r)) - call_binTM(L, IM_CONCAT, "unexpected type for concatenation"); - else { - tsvalue(l) = strconc(L, tsvalue(l), tsvalue(r)); - --S->top; - } + case CONCOP: + if (tostring(L, top-2) || tostring(L, top-1)) + call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation"); + else + tsvalue(top-2) = strconc(L, tsvalue(top-2), tsvalue(top-1)); + L->top = top; luaC_checkGC(L); + top--; break; - } case MINUSOP: - if (tonumber(S->top-1)) { - ttype(S->top) = LUA_T_NIL; - S->top++; - call_arith(L, IM_UNM); + if (tonumber(top-1)) { + ttype(top) = LUA_T_NIL; + call_arith(L, top+1, IM_UNM); } else - nvalue(S->top-1) = - nvalue(S->top-1); + nvalue(top-1) = - nvalue(top-1); break; case NOTOP: - ttype(S->top-1) = - (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; - nvalue(S->top-1) = 1; + ttype(top-1) = + (ttype(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; + nvalue(top-1) = 1; break; case ONTJMPW: aux += highbyte(L, *pc++); case ONTJMP: aux += *pc++; - if (ttype(S->top-1) != LUA_T_NIL) pc += aux; - else S->top--; + if (ttype(top-1) != LUA_T_NIL) pc += aux; + else top--; break; case ONFJMPW: aux += highbyte(L, *pc++); case ONFJMP: aux += *pc++; - if (ttype(S->top-1) == LUA_T_NIL) pc += aux; - else S->top--; + if (ttype(top-1) == LUA_T_NIL) pc += aux; + else top--; break; case JMPW: aux += highbyte(L, *pc++); @@ -568,35 +568,40 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, case IFFJMPW: aux += highbyte(L, *pc++); case IFFJMP: aux += *pc++; - if (ttype(--S->top) == LUA_T_NIL) pc += aux; + if (ttype(--top) == LUA_T_NIL) pc += aux; break; case IFTUPJMPW: aux += highbyte(L, *pc++); case IFTUPJMP: aux += *pc++; - if (ttype(--S->top) != LUA_T_NIL) pc -= aux; + if (ttype(--top) != LUA_T_NIL) pc -= aux; break; case IFFUPJMPW: aux += highbyte(L, *pc++); case IFFUPJMP: aux += *pc++; - if (ttype(--S->top) == LUA_T_NIL) pc -= aux; + if (ttype(--top) == LUA_T_NIL) pc -= aux; break; case CLOSUREW: aux += highbyte(L, *pc++); case CLOSURE: aux += *pc++; - *S->top++ = consts[aux]; - luaV_closure(L, *pc++); + *top++ = consts[aux]; + L->top = top; + aux = *pc++; + luaV_closure(L, aux); luaC_checkGC(L); + top -= aux; break; case SETLINEW: aux += highbyte(L, *pc++); case SETLINE: aux += *pc++; - if ((S->stack+base-1)->ttype != LUA_T_LINE) { + L->top = top; + if ((base-1)->ttype != LUA_T_LINE) { /* open space for LINE value */ - luaD_openstack(L, (S->top-S->stack)-base); + luaD_openstack(L, base); + base->ttype = LUA_T_LINE; base++; - (S->stack+base-1)->ttype = LUA_T_LINE; + top++; } - (S->stack+base-1)->value.i = aux; + (base-1)->value.i = aux; if (L->linehook) luaD_lineHook(L, aux); break; @@ -608,8 +613,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, } } ret: + L->top = top; if (L->callhook) luaD_callHook(L, 0, NULL, 1); return base; } - |