From 7178a5e34aa56c09a01a6664bb7a61c6771700d4 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy <roberto@inf.puc-rio.br> Date: Wed, 7 Feb 2001 16:13:49 -0200 Subject: new way to handle top x L->top --- lapi.c | 10 +-- lcode.c | 39 ++++++----- ldebug.c | 18 ++--- ldebug.h | 4 +- ldo.c | 11 +--- ldo.h | 3 +- lgc.c | 9 ++- lvm.c | 227 ++++++++++++++++++++++++++++----------------------------------- lvm.h | 12 ++-- 9 files changed, 153 insertions(+), 180 deletions(-) diff --git a/lapi.c b/lapi.c index 387f7a21..e58fe789 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.124 2001/02/01 16:03:38 roberto Exp roberto $ +** $Id: lapi.c,v 1.125 2001/02/02 15:13:05 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -208,7 +208,7 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { o1 = luaA_indexAcceptable(L, index1); o2 = luaA_indexAcceptable(L, index2); i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */ - : luaV_lessthan(L, o1, o2, L->top); + : luaV_lessthan(L, o1, o2); LUA_UNLOCK(L); return i; } @@ -364,7 +364,7 @@ LUA_API void lua_gettable (lua_State *L, int index) { StkId t; LUA_LOCK(L); t = Index(L, index); - luaV_gettable(L, t, L->top, L->top-1); + luaV_gettable(L, t, L->top-1, L->top-1); LUA_UNLOCK(L); } @@ -433,7 +433,7 @@ LUA_API void lua_newtable (lua_State *L) { LUA_API void lua_setglobal (lua_State *L, const char *name) { LUA_LOCK(L); - luaV_setglobal(L, luaS_new(L, name), L->top); + luaV_setglobal(L, luaS_new(L, name), L->top - 1); L->top--; /* remove element from the top */ LUA_UNLOCK(L); } @@ -443,7 +443,7 @@ LUA_API void lua_settable (lua_State *L, int index) { StkId t; LUA_LOCK(L); t = Index(L, index); - luaV_settable(L, t, L->top - 2, L->top); + luaV_settable(L, t, L->top - 2, L->top - 1); L->top -= 2; /* pop index and value */ LUA_UNLOCK(L); } diff --git a/lcode.c b/lcode.c index 8fb0f70c..321af3c9 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.58 2001/01/29 13:14:49 roberto Exp roberto $ +** $Id: lcode.c,v 1.59 2001/01/29 15:26:40 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -460,25 +460,26 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1) { int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { Proto *f; Instruction i = previous_instruction(fs); - int delta = (int)luaK_opproperties[o].push - (int)luaK_opproperties[o].pop; + int push = (int)luaK_opproperties[o].push; + int pop = (int)luaK_opproperties[o].pop; int optm = 0; /* 1 when there is an optimization */ switch (o) { case OP_CLOSURE: { - delta = -arg2+1; + pop = arg2; break; } case OP_SETTABLE: { - delta = -arg2; + pop = arg2; break; } case OP_SETLIST: { if (arg2 == 0) return NO_JUMP; /* nothing to do */ - delta = -arg2; + pop = arg2; break; } case OP_SETMAP: { if (arg1 == 0) return NO_JUMP; /* nothing to do */ - delta = -2*arg1; + pop = 2*arg1; break; } case OP_RETURN: { @@ -491,7 +492,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { } case OP_PUSHNIL: { if (arg1 == 0) return NO_JUMP; /* nothing to do */ - delta = arg1; + push = arg1; switch(GET_OPCODE(i)) { case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; default: break; @@ -500,7 +501,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { } case OP_POP: { if (arg1 == 0) return NO_JUMP; /* nothing to do */ - delta = -arg1; + pop = arg1; switch(GET_OPCODE(i)) { case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; default: break; @@ -539,7 +540,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { break; } case OP_CONCAT: { - delta = -arg1+1; + pop = arg1; switch(GET_OPCODE(i)) { case OP_CONCAT: /* `a..b..c' */ SETARG_U(i, GETARG_U(i)+1); @@ -573,7 +574,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { case OP_JMPEQ: { if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */ i = CREATE_0(OP_NOT); - delta = -1; /* just undo effect of previous PUSHNIL */ + pop = 1; /* just undo effect of previous PUSHNIL */ optm = 1; } break; @@ -637,12 +638,14 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { break; } default: { - lua_assert(delta != VD); break; } } f = fs->f; - luaK_deltastack(fs, delta); + lua_assert(push != VD); + lua_assert(pop != VD); + luaK_deltastack(fs, push); + luaK_deltastack(fs, -pop); if (optm) { /* optimize: put instruction in place of last one */ f->code[fs->pc-1] = i; /* change previous instruction */ return fs->pc-1; /* do not generate new instruction */ @@ -668,7 +671,7 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = { {iAB, 0, 0}, /* OP_CALL */ {iAB, 0, 0}, /* OP_TAILCALL */ {iU, VD, 0}, /* OP_PUSHNIL */ - {iU, VD, 0}, /* OP_POP */ + {iU, 0, VD}, /* OP_POP */ {iS, 1, 0}, /* OP_PUSHINT */ {iU, 1, 0}, /* OP_PUSHSTRING */ {iU, 1, 0}, /* OP_PUSHNUM */ @@ -683,16 +686,16 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = { {iU, 1, 0}, /* OP_CREATETABLE */ {iU, 0, 1}, /* OP_SETLOCAL */ {iU, 0, 1}, /* OP_SETGLOBAL */ - {iAB, VD, 0}, /* OP_SETTABLE */ - {iAB, VD, 0}, /* OP_SETLIST */ - {iU, VD, 0}, /* OP_SETMAP */ + {iAB, 0, VD}, /* OP_SETTABLE */ + {iAB, 0, VD}, /* OP_SETLIST */ + {iU, 0, VD}, /* OP_SETMAP */ {iO, 1, 2}, /* OP_ADD */ {iS, 1, 1}, /* OP_ADDI */ {iO, 1, 2}, /* OP_SUB */ {iO, 1, 2}, /* OP_MULT */ {iO, 1, 2}, /* OP_DIV */ {iO, 1, 2}, /* OP_POW */ - {iU, VD, 0}, /* OP_CONCAT */ + {iU, 1, VD}, /* OP_CONCAT */ {iO, 1, 1}, /* OP_MINUS */ {iO, 1, 1}, /* OP_NOT */ {iS, 0, 2}, /* OP_JMPNE */ @@ -711,6 +714,6 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = { {iS, 0, 3}, /* OP_FORLOOP */ {iS, 3, 0}, /* OP_LFORPREP */ {iS, 0, 4}, /* OP_LFORLOOP */ - {iAB, VD, 0} /* OP_CLOSURE */ + {iAB, 1, VD} /* OP_CLOSURE */ }; diff --git a/ldebug.c b/ldebug.c index 0cb93494..a54b293c 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 1.58 2001/01/29 17:16:58 roberto Exp roberto $ +** $Id: ldebug.c,v 1.59 2001/02/02 15:13:05 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -397,10 +397,12 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { } default: { OpCode op = GET_OPCODE(i); - lua_assert(luaK_opproperties[op].push != VD); - top -= (int)luaK_opproperties[op].pop; - lua_assert(top >= 0); - top = pushpc(stack, pc, top, luaK_opproperties[op].push); + int push = (int)luaK_opproperties[op].push; + int pop = (int)luaK_opproperties[op].pop; + lua_assert(push != VD && pop != VD); + lua_assert(0 <= top-pop && top+push <= pt->maxstacksize); + top -= pop; + top = pushpc(stack, pc, top, push); } } } @@ -482,9 +484,9 @@ void luaG_binerror (lua_State *L, StkId p1, int t, const char *op) { } -void luaG_ordererror (lua_State *L, StkId top) { - const char *t1 = luaT_typename(G(L), top-2); - const char *t2 = luaT_typename(G(L), top-1); +void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) { + const char *t1 = luaT_typename(G(L), p1); + const char *t2 = luaT_typename(G(L), p2); if (t1[2] == t2[2]) luaO_verror(L, "attempt to compare two %.10s values", t1); else diff --git a/ldebug.h b/ldebug.h index dd217513..bab4d1d7 100644 --- a/ldebug.h +++ b/ldebug.h @@ -1,5 +1,5 @@ /* -** $Id: ldebug.h,v 1.6 2000/10/02 20:10:55 roberto Exp roberto $ +** $Id: ldebug.h,v 1.7 2000/10/05 12:14:08 roberto Exp roberto $ ** Auxiliary functions from Debug Interface module ** See Copyright Notice in lua.h */ @@ -15,7 +15,7 @@ void luaG_typeerror (lua_State *L, StkId o, const char *op); void luaG_binerror (lua_State *L, StkId p1, int t, const char *op); int luaG_getline (int *lineinfo, int pc, int refline, int *refi); -void luaG_ordererror (lua_State *L, StkId top); +void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); #endif diff --git a/ldo.c b/ldo.c index 24f4a169..39ef5626 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.121 2001/02/02 15:13:05 roberto Exp roberto $ +** $Id: ldo.c,v 1.122 2001/02/02 16:23:20 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -143,14 +143,6 @@ static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) { } -void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) { - StkId base = L->top - nParams; - luaD_openstack(L, base); - setclvalue(base, f); - luaD_call(L, base, nResults); -} - - /* ** Call a function (C or Lua). The function to be called is at *func. ** The arguments are on the stack, right after the function. @@ -182,6 +174,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) { if (callhook) /* same hook that was active at entry */ luaD_callHook(L, func, callhook, "return"); lua_assert(ttype(func) == LUA_TMARK); + setnilvalue(func); /* remove callinfo from the stack */ /* move results to `func' (to erase parameters and function) */ if (nResults == LUA_MULTRET) { while (firstResult < L->top) /* copy all results */ diff --git a/ldo.h b/ldo.h index 42497736..2cd9a91c 100644 --- a/ldo.h +++ b/ldo.h @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 1.28 2000/10/06 12:45:25 roberto Exp roberto $ +** $Id: ldo.h,v 1.29 2001/01/24 15:45:33 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -23,7 +23,6 @@ void luaD_init (lua_State *L, int stacksize); void luaD_adjusttop (lua_State *L, StkId base, int extra); void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook); void luaD_call (lua_State *L, StkId func, int nResults); -void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults); void luaD_checkstack (lua_State *L, int n); void luaD_error (lua_State *L, const char *s); diff --git a/lgc.c b/lgc.c index c8331b69..77927940 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.86 2001/02/02 16:23:20 roberto Exp roberto $ +** $Id: lgc.c,v 1.87 2001/02/02 16:32:00 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -101,11 +101,14 @@ static void markobject (GCState *st, TObject *o) { static void markstacks (lua_State *L, GCState *st) { lua_State *L1 = L; do { /* for each thread */ - StkId o; + StkId o, lim; marktable(st, L1->gt); /* mark table of globals */ for (o=L1->stack; o<L1->top; o++) markobject(st, o); - lua_assert(L->previous->next == L && L->next->previous == L); + lim = (L1->stack_last - L1->top > MAXSTACK) ? L1->top+MAXSTACK + : L1->stack_last; + for (; o<=lim; o++) setnilvalue(o); + lua_assert(L1->previous->next == L1 && L1->next->previous == L1); L1 = L1->next; } while (L1 != L); } diff --git a/lvm.c b/lvm.c index a25f02cd..55a9e433 100644 --- a/lvm.c +++ b/lvm.c @@ -1,10 +1,11 @@ /* -** $Id: lvm.c,v 1.164 2001/02/02 15:13:05 roberto Exp roberto $ +** $Id: lvm.c,v 1.165 2001/02/06 16:01:29 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ +#include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -26,14 +27,6 @@ -/* -** Extra stack size to run a function: -** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...) -*/ -#define EXTRA_FSTACK 8 - - - int luaV_tonumber (TObject *obj) { if (ttype(obj) != LUA_TSTRING) return 1; @@ -58,7 +51,7 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */ } -static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) { +static void traceexec (lua_State *L, StkId base, lua_Hook linehook) { CallInfo *ci = infovalue(base-1); int *lineinfo = ci->func->f.l->lineinfo; int pc = (*ci->pc - ci->func->f.l->code) - 1; @@ -72,7 +65,6 @@ static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) { /* calls linehook when enters a new line or jumps back (loop) */ if (newline != ci->line || pc <= ci->lastpc) { ci->line = newline; - L->top = top; luaD_lineHook(L, base-2, newline, linehook); } ci->lastpc = pc; @@ -104,19 +96,52 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) { } +static void callTM (lua_State *L, const char *fmt, ...) { + va_list argp; + StkId base = L->top; + int has_result = 0; + va_start(argp, fmt); + for (;;) { + switch (*fmt++) { + case 'c': + setclvalue(L->top, va_arg(argp, Closure *)); + break; + case 'o': + setobj(L->top, va_arg(argp, TObject *)); + break; + case 's': + setsvalue(L->top, va_arg(argp, TString *)); + break; + case 'r': + has_result = 1; + /* go through */ + default: + goto endloop; + } + incr_top; + } endloop: + luaD_call(L, base, has_result); + if (has_result) { + L->top--; + setobj(va_arg(argp, TObject *), L->top); + } + va_end(argp); +} + + /* ** Function to index a table. -** Receives the table at `t' and the key at the top (`top'-1), +** Receives the table at `t' and the key at the `key'. ** leaves the result at `res'. */ -void luaV_gettable (lua_State *L, StkId t, StkId top, StkId res) { +void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { Closure *tm; int tg; if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ luaT_gettm(G(L), tg, TM_GETTABLE) == NULL)) { /* or no TM? */ /* do a primitive get */ - const TObject *h = luaH_get(hvalue(t), top-1); + const TObject *h = luaH_get(hvalue(t), key); /* result is no nil or there is no `index' tag method? */ if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL)) { setobj(res, h); @@ -127,116 +152,79 @@ void luaV_gettable (lua_State *L, StkId t, StkId top, StkId res) { else { /* try a `gettable' tag method */ tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE); } - L->top = top; if (tm == NULL) /* no tag method? */ luaG_typeerror(L, t, "index"); - else { /* call tag method */ - luaD_checkstack(L, 2); - setobj(res+2, top-1); /* key */ - setobj(res+1, t); /* table */ - setclvalue(res, tm); /* tag method */ - L->top = res+3; - luaD_call(L, res, 1); - L->top = top; /* will be decremented by the callee */ - } + else + callTM(L, "coor", tm, t, key, res); } + /* -** Receives table at `t', key at `key' and value at top. +** Receives table at `t', key at `key' and value at `val'. */ -void luaV_settable (lua_State *L, StkId t, StkId key, StkId top) { +void luaV_settable (lua_State *L, StkId t, StkId key, StkId val) { int tg; if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ luaT_gettm(G(L), tg, TM_SETTABLE) == NULL)) { /* or no TM? */ - setobj(luaH_set(L, hvalue(t), key), top-1); /* do a primitive set */ + setobj(luaH_set(L, hvalue(t), key), val); /* do a primitive set */ } else { /* try a `settable' tag method */ Closure *tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE); - lua_assert(L->top == top); if (tm == NULL) /* no tag method? */ luaG_typeerror(L, t, "index"); - else { - luaD_checkstack(L, 3); - setobj(top+2, top-1); - setobj(top+1, key); - setobj(top, t); - setclvalue(top-1, tm); - L->top = top+3; - luaD_call(L, top-1, 0); /* call `settable' tag method */ - lua_assert(L->top == top-1); - L->top = top; /* will be decremented by the callee */ - } + else + callTM(L, "cooo", tm, t, key, val); } } -void luaV_getglobal (lua_State *L, TString *s, StkId top) { - const TObject *value = luaH_getstr(L->gt, s); +void luaV_getglobal (lua_State *L, TString *name, StkId res) { + const TObject *value = luaH_getstr(L->gt, name); Closure *tm; if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */ (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) { - setobj(top, value); /* default behavior */ - } - else { /* call tag method */ - L->top = top; - luaD_checkstack(L, 3); - setclvalue(top, tm); - setsvalue(top+1, s); /* global name */ - setobj(top+2, value); - L->top = top+3; - luaD_call(L, top, 1); - lua_assert(L->top == top+1); - L->top = top; /* will be incremented by the callee */ + setobj(res, value); /* default behavior */ } + else + callTM(L, "csor", tm, name, value, res); } -void luaV_setglobal (lua_State *L, TString *s, StkId top) { - TObject *oldvalue = luaH_setstr(L, L->gt, s); +void luaV_setglobal (lua_State *L, TString *name, StkId val) { + TObject *oldvalue = luaH_setstr(L, L->gt, name); Closure *tm; if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */ (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) { - setobj(oldvalue, top-1); /* raw set */ - } - else { /* call tag method */ - lua_assert(L->top == top); - luaD_checkstack(L, 3); - setobj(top+2, top-1); /* new value */ - setobj(top+1, oldvalue); /* old value */ - setsvalue(top, s); /* var name */ - setclvalue(top-1, tm); /* tag method */ - L->top = top+3; - luaD_call(L, top-1, 0); - lua_assert(L->top == top-1); - L->top = top; /* will be decremented by the callee */ + setobj(oldvalue, val); /* raw set */ } + else + callTM(L, "csoo", tm, name, oldvalue, val); } -static int call_binTM (lua_State *L, StkId top, TMS event) { - /* try first operand */ - Closure *tm = luaT_gettmbyObj(G(L), top-2, event); - L->top = top; +static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, + TObject *res, TMS event) { + TString *opname; + Closure *tm = luaT_gettmbyObj(G(L), p1, event); /* try first operand */ if (tm == NULL) { - tm = luaT_gettmbyObj(G(L), top-1, event); /* try second operand */ + tm = luaT_gettmbyObj(G(L), p2, event); /* try second operand */ if (tm == NULL) { tm = luaT_gettm(G(L), 0, event); /* try a `global' method */ if (tm == NULL) - return 0; /* error */ + return 0; /* no tag method */ } } - setsvalue(L->top, luaS_new(L, luaT_eventname[event])); - incr_top; - luaD_callTM(L, tm, 3, 1); + opname = luaS_new(L, luaT_eventname[event]); + callTM(L, "coosr", tm, p1, p2, opname, res); return 1; } -static void call_arith (lua_State *L, StkId top, TMS event) { - if (!call_binTM(L, top, event)) - luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on"); +static void call_arith (lua_State *L, StkId p1, TMS event) { + if (!call_binTM(L, p1, p1+1, p1, event)) + luaG_binerror(L, p1, LUA_TNUMBER, "perform arithmetic on"); } @@ -262,19 +250,14 @@ static int luaV_strlessthan (const TString *ls, const TString *rs) { } -int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) { +int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER) return (nvalue(l) < nvalue(r)); else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING) return luaV_strlessthan(tsvalue(l), tsvalue(r)); - else { /* call TM */ - L->top = top; - luaD_checkstack(L, 2); - setobj(top++, l); - setobj(top++, r); - if (!call_binTM(L, top, TM_LT)) - luaG_ordererror(L, top); - L->top--; + else { /* try TM */ + if (!call_binTM(L, l, r, L->top, TM_LT)) + luaG_ordererror(L, l, r); return (ttype(L->top) != LUA_TNIL); } } @@ -284,7 +267,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) { do { int n = 2; /* number of elements handled in this pass (at least 2) */ if (tostring(L, top-2) || tostring(L, top-1)) { - if (!call_binTM(L, top, TM_CONCAT)) + if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) luaG_binerror(L, top-2, LUA_TSTRING, "concat"); } else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ @@ -350,17 +333,16 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { TString **const kstr = tf->kstr; const lua_Hook linehook = L->linehook; infovalue(base-1)->pc = &pc; - luaD_checkstack(L, tf->maxstacksize+EXTRA_FSTACK); if (tf->is_vararg) /* varargs? */ adjust_varargs(L, base, tf->numparams); - else - luaD_adjusttop(L, base, tf->numparams); - top = L->top; + luaD_adjusttop(L, base, tf->maxstacksize); + top = base+tf->numparams+tf->is_vararg; /* main loop of interpreter */ for (;;) { const Instruction i = *pc++; + lua_assert(L->top == base+tf->maxstacksize); if (linehook) - traceexec(L, base, top, linehook); + traceexec(L, base, linehook); switch (GET_OPCODE(i)) { case OP_RETURN: { L->top = top; @@ -372,6 +354,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { L->top = top; luaD_call(L, base+GETARG_A(i), nres); top = L->top; + L->top = base+tf->maxstacksize; break; } case OP_TAILCALL: { @@ -425,31 +408,27 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; } case OP_GETTABLE: { - luaV_gettable(L, top-2, top, top-2); top--; + luaV_gettable(L, top-1, top, top-1); break; } case OP_GETDOTTED: { setsvalue(top, kstr[GETARG_U(i)]); - luaV_gettable(L, top-1, top+1, top-1); + luaV_gettable(L, top-1, top, top-1); break; } case OP_GETINDEXED: { - setobj(top, base+GETARG_U(i)); - luaV_gettable(L, top-1, top+1, top-1); + luaV_gettable(L, top-1, base+GETARG_U(i), top-1); break; } case OP_PUSHSELF: { - TObject receiver; - setobj(&receiver, top-1); - setsvalue(top, kstr[GETARG_U(i)]); + setobj(top, top-1); + setsvalue(top+1, kstr[GETARG_U(i)]); + luaV_gettable(L, top-1, top+1, top-1); top++; - luaV_gettable(L, top-2, top, top-2); - setobj(top-1, &receiver); break; } case OP_CREATETABLE: { - L->top = top; luaC_checkGC(L); sethvalue(top, luaH_new(L, GETARG_U(i))); top++; @@ -460,15 +439,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; } case OP_SETGLOBAL: { - L->top = top; /* primitive set may generate an error */ - luaV_setglobal(L, kstr[GETARG_U(i)], top); top--; + luaV_setglobal(L, kstr[GETARG_U(i)], top); break; } case OP_SETTABLE: { StkId t = top-GETARG_A(i); - L->top = top; /* primitive set may generate an error */ - luaV_settable(L, t, t+1, top); + luaV_settable(L, t, t+1, top-1); top -= GETARG_B(i); /* pop values */ break; } @@ -476,16 +453,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; int n = GETARG_B(i); Hash *arr = hvalue(top-n-1); - L->top = top-n; for (; n; n--) setobj(luaH_setnum(L, arr, n+aux), --top); break; } case OP_SETMAP: { int n = GETARG_U(i); - StkId finaltop = top-2*n; - Hash *arr = hvalue(finaltop-1); - L->top = finaltop; + Hash *arr = hvalue((top-2*n)-1); for (; n; n--) { top-=2; setobj(luaH_set(L, arr, top), top+1); @@ -494,7 +468,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_ADD: { if (tonumber(top-2) || tonumber(top-1)) - call_arith(L, top, TM_ADD); + call_arith(L, top-2, TM_ADD); else nvalue(top-2) += nvalue(top-1); top--; @@ -503,7 +477,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { case OP_ADDI: { if (tonumber(top-1)) { setnvalue(top, (lua_Number)GETARG_S(i)); - call_arith(L, top+1, TM_ADD); + call_arith(L, top-1, TM_ADD); } else nvalue(top-1) += (lua_Number)GETARG_S(i); @@ -511,7 +485,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_SUB: { if (tonumber(top-2) || tonumber(top-1)) - call_arith(L, top, TM_SUB); + call_arith(L, top-2, TM_SUB); else nvalue(top-2) -= nvalue(top-1); top--; @@ -519,7 +493,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_MULT: { if (tonumber(top-2) || tonumber(top-1)) - call_arith(L, top, TM_MUL); + call_arith(L, top-2, TM_MUL); else nvalue(top-2) *= nvalue(top-1); top--; @@ -527,14 +501,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_DIV: { if (tonumber(top-2) || tonumber(top-1)) - call_arith(L, top, TM_DIV); + call_arith(L, top-2, TM_DIV); else nvalue(top-2) /= nvalue(top-1); top--; break; } case OP_POW: { - if (!call_binTM(L, top, TM_POW)) + if (!call_binTM(L, top-2, top-1, top-2, TM_POW)) luaD_error(L, "undefined operation"); top--; break; @@ -543,14 +517,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { int n = GETARG_U(i); luaV_strconc(L, n, top); top -= n-1; - L->top = top; luaC_checkGC(L); break; } case OP_MINUS: { if (tonumber(top-1)) { setnilvalue(top); - call_arith(L, top+1, TM_UNM); + call_arith(L, top-1, TM_UNM); } else nvalue(top-1) = -nvalue(top-1); @@ -574,22 +547,22 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_JMPLT: { top -= 2; - if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i); + if (luaV_lessthan(L, top, top+1)) dojump(pc, i); break; } case OP_JMPLE: { /* a <= b === !(b<a) */ top -= 2; - if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i); + if (!luaV_lessthan(L, top+1, top)) dojump(pc, i); break; } case OP_JMPGT: { /* a > b === (b<a) */ top -= 2; - if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i); + if (luaV_lessthan(L, top+1, top)) dojump(pc, i); break; } case OP_JMPGE: { /* a >= b === !(a<b) */ top -= 2; - if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i); + if (!luaV_lessthan(L, top, top+1)) dojump(pc, i); break; } case OP_JMPT: { @@ -675,11 +648,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_CLOSURE: { int nup = GETARG_B(i); + luaC_checkGC(L); L->top = top; luaV_Lclosure(L, tf->kproto[GETARG_A(i)], nup); top -= (nup-1); - lua_assert(top == L->top); - luaC_checkGC(L); + L->top = base+tf->maxstacksize; break; } } diff --git a/lvm.h b/lvm.h index ed862f2d..a8513c8a 100644 --- a/lvm.h +++ b/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 1.27 2000/10/05 12:14:08 roberto Exp roberto $ +** $Id: lvm.h,v 1.28 2001/02/01 16:03:38 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -19,14 +19,14 @@ int luaV_tonumber (TObject *obj); int luaV_tostring (lua_State *L, TObject *obj); -void luaV_gettable (lua_State *L, StkId t, StkId top, StkId res); -void luaV_settable (lua_State *L, StkId t, StkId key, StkId top); -void luaV_getglobal (lua_State *L, TString *s, StkId top); -void luaV_setglobal (lua_State *L, TString *s, StkId top); +void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res); +void luaV_settable (lua_State *L, StkId t, StkId key, StkId val); +void luaV_getglobal (lua_State *L, TString *s, StkId res); +void luaV_setglobal (lua_State *L, TString *s, StkId val); StkId luaV_execute (lua_State *L, const Closure *cl, StkId base); void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems); void luaV_Lclosure (lua_State *L, Proto *l, int nelems); -int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top); +int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); void luaV_strconc (lua_State *L, int total, StkId top); #endif -- cgit v1.2.3-55-g6feb