mirror of https://github.com/lua/lua
new definition for `luaD_call' and `luaD_adjusttop'
This commit is contained in:
parent
4905fdd135
commit
cbc59592ff
16
lapi.c
16
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);
|
||||
}
|
||||
|
||||
|
|
8
lcode.c
8
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
4
ldebug.c
4
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;
|
||||
}
|
||||
|
|
55
ldo.c
55
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
6
ldo.h
6
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);
|
||||
|
|
10
lgc.c
10
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 */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
10
lparser.c
10
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 */
|
||||
}
|
||||
|
|
76
lvm.c
76
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue