From cbc59592ff684b646b21766a66630df1f7974b25 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 8 Jun 2001 16:01:38 -0300 Subject: new definition for `luaD_call' and `luaD_adjusttop' --- lapi.c | 16 ++++++++----- lcode.c | 8 ++++--- ldebug.c | 4 ++-- ldo.c | 55 +++++++++++++++++---------------------------- ldo.h | 6 ++--- lgc.c | 10 +++++---- lopcodes.h | 4 ++-- lparser.c | 10 ++++----- lvm.c | 76 +++++++++++++++++++++++++++++++++----------------------------- 9 files changed, 94 insertions(+), 95 deletions(-) diff --git a/lapi.c b/lapi.c index 7f4c6e7f..9f8eca5b 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.142 2001/06/05 18:17:01 roberto Exp roberto $ +** $Id: lapi.c,v 1.143 2001/06/06 18:00:19 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -95,11 +95,13 @@ LUA_API int lua_gettop (lua_State *L) { LUA_API void lua_settop (lua_State *L, int index) { lua_lock(L); - if (index >= 0) - luaD_adjusttop(L, L->ci->base, index); + if (index >= 0) { + api_check(L, index <= L->stack_last - L->ci->base); + luaD_adjusttop(L, L->ci->base+index); + } else { api_check(L, -(index+1) <= (L->top - L->ci->base)); - L->top = L->top+index+1; /* index is negative */ + L->top += index+1; /* `subtract' index (index is negative) */ } lua_unlock(L); } @@ -545,9 +547,13 @@ LUA_API int lua_ref (lua_State *L, int lock) { */ LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) { + StkId func; lua_lock(L); api_checknelems(L, nargs+1); - luaD_call(L, L->top-(nargs+1), nresults); + func = L->top - (nargs+1); + luaD_call(L, func); + if (nresults != LUA_MULTRET) + luaD_adjusttop(L, func + nresults); lua_unlock(L); } diff --git a/lcode.c b/lcode.c index e869dac3..ad0c05d2 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.71 2001/06/07 15:01:21 roberto Exp roberto $ +** $Id: lcode.c,v 1.72 2001/06/08 12:29:27 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -261,10 +261,12 @@ static int number_constant (FuncState *fs, lua_Number r) { void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) { if (e->k == VCALL) { /* expression is an open function call? */ - SETARG_C(getcode(fs, e), nresults); /* set number of results */ + int a = GETARG_A(getcode(fs, e)); + int c = (nresults == LUA_MULTRET) ? NO_REG : a + nresults; + SETARG_C(getcode(fs, e), c); if (nresults == 1) { /* `regular' expression? */ e->k = VNONRELOC; - e->u.i.info = GETARG_A(getcode(fs, e)); + e->u.i.info = a; } } } diff --git a/ldebug.c b/ldebug.c index 108a89c7..62372fca 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 1.79 2001/06/07 14:44:51 roberto Exp roberto $ +** $Id: ldebug.c,v 1.80 2001/06/08 12:29:27 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -421,7 +421,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { } check(b > a); checkreg(pt, b-1); - checkreg(pt, a+c-1); + checkreg(pt, c-1); if (reg >= a) last = pc; /* affect all registers above base */ break; } diff --git a/ldo.c b/ldo.c index cbaca68c..c2d0e92d 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.134 2001/04/11 18:39:37 roberto Exp roberto $ +** $Id: ldo.c,v 1.135 2001/06/05 19:27:32 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -62,19 +62,12 @@ void luaD_stackerror (lua_State *L) { /* -** Adjust stack. Set top to base+extra, pushing NILs if needed. -** (we cannot add base+extra unless we are sure it fits in the stack; -** otherwise the result of such operation on pointers is undefined) +** adjust top to new value; assume that new top is valid */ -void luaD_adjusttop (lua_State *L, StkId base, int extra) { - int diff = extra-(L->top-base); - if (diff <= 0) - L->top = base+extra; - else { - luaD_checkstack(L, diff); - while (diff--) - setnilvalue(L->top++); - } +void luaD_adjusttop (lua_State *L, StkId newtop) { + while (L->top < newtop) + setnilvalue(L->top++); + L->top = newtop; /* `newtop' could be lower than `top' */ } @@ -140,11 +133,10 @@ static StkId callCclosure (lua_State *L, const struct Closure *cl) { /* ** Call a function (C or Lua). The function to be called is at *func. ** The arguments are on the stack, right after the function. -** When returns, the results are on the stack, starting at the original +** When returns, all the results are on the stack, starting at the original ** function position. -** The number of results is nResults, unless nResults=LUA_MULTRET. */ -void luaD_call (lua_State *L, StkId func, int nResults) { +void luaD_call (lua_State *L, StkId func) { lua_Hook callhook; StkId firstResult; CallInfo ci; @@ -168,20 +160,9 @@ void luaD_call (lua_State *L, StkId func, int nResults) { luaD_callHook(L, callhook, l_s("return")); L->ci = ci.prev; /* unchain callinfo */ /* move results to `func' (to erase parameters and function) */ - if (nResults == LUA_MULTRET) { - while (firstResult < L->top) /* copy all results */ - setobj(func++, firstResult++); - L->top = func; - } - else { /* copy at most `nResults' */ - for (; nResults > 0 && firstResult < L->top; nResults--) - setobj(func++, firstResult++); - L->top = func; - for (; nResults > 0; nResults--) { /* if there are not enough results */ - setnilvalue(L->top); /* adjust the stack */ - incr_top; /* must check stack space */ - } - } + while (firstResult < L->top) + setobj(func++, firstResult++); + L->top = func; luaC_checkGC(L); } @@ -196,7 +177,9 @@ struct CallS { /* data to `f_call' */ static void f_call (lua_State *L, void *ud) { struct CallS *c = (struct CallS *)ud; - luaD_call(L, c->func, c->nresults); + luaD_call(L, c->func); + if (c->nresults != LUA_MULTRET) + luaD_adjusttop(L, c->func + c->nresults); } @@ -307,12 +290,14 @@ struct lua_longjmp { static void message (lua_State *L, const l_char *s) { - luaV_getglobal(L, luaS_newliteral(L, l_s(LUA_ERRORMESSAGE)), L->top); - if (ttype(L->top) == LUA_TFUNCTION) { + StkId top = L->top; + luaV_getglobal(L, luaS_newliteral(L, l_s(LUA_ERRORMESSAGE)), top); + if (ttype(top) == LUA_TFUNCTION) { incr_top; - setsvalue(L->top, luaS_new(L, s)); + setsvalue(top+1, luaS_new(L, s)); incr_top; - luaD_call(L, L->top-2, 0); + luaD_call(L, top); + L->top = top; } } diff --git a/ldo.h b/ldo.h index eda4f526..618e8bee 100644 --- a/ldo.h +++ b/ldo.h @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 1.32 2001/03/07 18:09:25 roberto Exp roberto $ +** $Id: ldo.h,v 1.33 2001/06/05 19:41:24 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -23,9 +23,9 @@ void luaD_init (lua_State *L, int stacksize); -void luaD_adjusttop (lua_State *L, StkId base, int extra); +void luaD_adjusttop (lua_State *L, StkId newtop); void luaD_lineHook (lua_State *L, int line, lua_Hook linehook); -void luaD_call (lua_State *L, StkId func, int nResults); +void luaD_call (lua_State *L, StkId func); void luaD_stackerror (lua_State *L); void luaD_error (lua_State *L, const l_char *s); diff --git a/lgc.c b/lgc.c index fcd22a86..e7d533d3 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.100 2001/06/06 18:00:19 roberto Exp roberto $ +** $Id: lgc.c,v 1.101 2001/06/07 15:01:21 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -338,12 +338,14 @@ static void callgcTM (lua_State *L, const TObject *obj) { Closure *tm = luaT_gettmbyObj(G(L), obj, TM_GC); if (tm != NULL) { int oldah = L->allowhooks; + StkId top = L->top; L->allowhooks = 0; /* stop debug hooks during GC tag methods */ luaD_checkstack(L, 2); - setclvalue(L->top, tm); - setobj(L->top+1, obj); + setclvalue(top, tm); + setobj(top+1, obj); L->top += 2; - luaD_call(L, L->top-2, 0); + luaD_call(L, top); + L->top = top; /* restore top */ L->allowhooks = oldah; /* restore hooks */ } } diff --git a/lopcodes.h b/lopcodes.h index 5819c407..bbca12d9 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.72 2001/04/06 18:25:00 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.73 2001/06/05 18:17:01 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -165,7 +165,7 @@ OP_TESTF,/* A B test := not R(B); if (test) R(A) := nil */ OP_NILJMP,/* A R(A) := nil; PC++; */ -OP_CALL,/* A B C R(A), ... ,R(A+C-1) := R(A)(R(A+1), ... ,R(B-1))*/ +OP_CALL,/* A B C R(A), ... ,R(C-1) := R(A)(R(A+1), ... ,R(B-1)) */ OP_RETURN,/* A B return R(A), ... ,R(B-1) (see (3)) */ OP_FORPREP,/* A sBc */ diff --git a/lparser.c b/lparser.c index 78b91cd6..8dff5638 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.145 2001/06/07 14:44:51 roberto Exp roberto $ +** $Id: lparser.c,v 1.146 2001/06/08 12:29:27 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -424,7 +424,7 @@ static void funcargs (LexState *ls, expdesc *f) { args.k = VVOID; else { explist1(ls, &args); - luaK_setcallreturns(fs, &args, NO_REG); + luaK_setcallreturns(fs, &args, LUA_MULTRET); } check_match(ls, l_c(')'), l_c('('), line); break; @@ -452,7 +452,7 @@ static void funcargs (LexState *ls, expdesc *f) { luaK_exp2nextreg(fs, &args); /* close last argument */ top = fs->freereg; } - init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, top, 1)); + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, top, base+1)); fs->freereg = base+1; /* call remove function and arguments and leaves (unless changed) one result */ } @@ -530,7 +530,7 @@ static int listfields (LexState *ls, expdesc *t) { n++; } if (v.k == VCALL) { - luaK_setcallreturns(fs, &v, NO_REG); + luaK_setcallreturns(fs, &v, LUA_MULTRET); luaK_codeABc(fs, OP_SETLISTO, t->u.i.info, n-1); } else { @@ -1098,7 +1098,7 @@ static void retstat (LexState *ls) { else { int n = explist1(ls, &e); /* optional return values */ if (e.k == VCALL) { - luaK_setcallreturns(fs, &e, NO_REG); + luaK_setcallreturns(fs, &e, LUA_MULTRET); first = fs->nactloc; last1 = NO_REG; /* return all values */ } diff --git a/lvm.c b/lvm.c index 29a6ea4d..c775b6c5 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.180 2001/06/05 19:27:32 roberto Exp roberto $ +** $Id: lvm.c,v 1.181 2001/06/08 12:29:27 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -106,33 +106,35 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) { } -static void callTM (lua_State *L, const l_char *fmt, ...) { +static void callTM (lua_State *L, Closure *f, const l_char *fmt, ...) { va_list argp; StkId base = L->top; - int has_result = 0; + StkId result = NULL; /* result position */ va_start(argp, fmt); + setclvalue(L->top, f); /* push function */ + incr_top; + if (*fmt == l_c('r')) { + fmt++; + result = va_arg(argp, TObject *); /* result position */ + } while (*fmt) { - switch (*fmt++) { - case l_c('c'): - setclvalue(L->top, va_arg(argp, Closure *)); - break; - case l_c('o'): + if (*fmt++ == l_c('o')) { setobj(L->top, va_arg(argp, TObject *)); - break; - case l_c('s'): - setsvalue(L->top, va_arg(argp, TString *)); - break; - case l_c('r'): - has_result = 1; - continue; + } + else { + lua_assert(*(fmt-1) == l_c('s')); + setsvalue(L->top, va_arg(argp, TString *)); } incr_top; } - luaD_call(L, base, has_result); - if (has_result) { - L->top--; - setobj(va_arg(argp, TObject *), L->top); + luaD_call(L, base); + if (result) { /* need result? */ + if (L->top == base) /* are there valid results? */ + setnilvalue(result); /* function had no results */ + else + setobj(result, base); /* get first result */ } + L->top = base; /* restore top */ va_end(argp); } @@ -162,7 +164,7 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { if (tm == NULL) /* no tag method? */ luaG_typeerror(L, t, l_s("index")); } - callTM(L, l_s("coor"), tm, t, key, res); + callTM(L, tm, l_s("roo"), res, t, key); } @@ -185,7 +187,7 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { if (tm == NULL) /* no tag method? */ luaG_typeerror(L, t, l_s("index")); } - callTM(L, l_s("cooo"), tm, t, key, val); + callTM(L, tm, l_s("ooo"), t, key, val); } @@ -196,7 +198,7 @@ void luaV_getglobal (lua_State *L, TString *name, StkId res) { (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) { setobj(res, value); /* default behavior */ } else - callTM(L, l_s("csor"), tm, name, value, res); + callTM(L, tm, l_s("rso"), res, name, value); } @@ -207,7 +209,7 @@ void luaV_setglobal (lua_State *L, TString *name, StkId val) { (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) { setobj(oldvalue, val); /* raw set */ } else - callTM(L, l_s("csoo"), tm, name, oldvalue, val); + callTM(L, tm, l_s("soo"), name, oldvalue, val); } @@ -224,7 +226,7 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, } } opname = luaS_new(L, luaT_eventname[event]); - callTM(L, l_s("coosr"), tm, p1, p2, opname, res); + callTM(L, tm, l_s("roos"), res, p1, p2, opname); return 1; } @@ -320,9 +322,12 @@ static void luaV_pack (lua_State *L, StkId firstelem) { static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { int nvararg = (L->top-base) - nfixargs; - if (nvararg < 0) - luaD_adjusttop(L, base, nfixargs); - luaV_pack(L, base+nfixargs); + StkId firstvar = base + nfixargs; /* position of first vararg */ + if (nvararg < 0) { + luaD_checkstack(L, -nvararg); + luaD_adjusttop(L, firstvar); + } + luaV_pack(L, firstvar); } @@ -368,7 +373,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { luaD_stackerror(L); while (L->top < base+tf->maxstacksize) setnilvalue(L->top++); - L->top = base+tf->maxstacksize; + L->top = base + tf->maxstacksize; pc = tf->code; L->ci->pc = &pc; linehook = L->linehook; @@ -544,16 +549,15 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { break; } case OP_CALL: { - int nres; + int c; int b = GETARG_B(i); if (b != NO_REG) L->top = base+b; - nres = GETARG_C(i); - if (nres == NO_REG) nres = LUA_MULTRET; - luaD_call(L, ra, nres); - if (nres != LUA_MULTRET) { - lua_assert(L->top == ra+nres); - L->top = base+tf->maxstacksize; + luaD_call(L, ra); + c = GETARG_C(i); + if (c != NO_REG) { + while (L->top < base+c) setnilvalue(L->top++); + L->top = base + tf->maxstacksize; } break; } @@ -637,7 +641,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { luaV_checkGC(L, ra+nup); L->top = ra+nup; luaV_Lclosure(L, p, nup); - L->top = base+tf->maxstacksize; + L->top = base + tf->maxstacksize; break; } } -- cgit v1.2.3-55-g6feb