commit e5146fb01f1ccb40c2663e745feffbf642cbf862
parent ce6b930464edd621ec95ddab2ce9ccb7ddae605a
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Tue, 16 Jul 2002 11:26:34 -0300
CallInfo has different fields for C functions and Lua functions
Diffstat:
M | ldebug.c | | | 22 | +++++++++------------- |
M | ldo.c | | | 63 | ++++++++++++++++++++++++++++++++------------------------------- |
M | lstate.c | | | 4 | ++-- |
M | lstate.h | | | 21 | +++++++++++++++------ |
M | lvm.c | | | 23 | +++++++++++++---------- |
5 files changed, 71 insertions(+), 62 deletions(-)
diff --git a/ldebug.c b/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 1.123 2002/06/24 15:07:21 roberto Exp roberto $
+** $Id: ldebug.c,v 1.124 2002/07/08 18:21:33 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -30,15 +30,11 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
-static int isLmark (CallInfo *ci) {
- return (ttype(ci->base - 1) == LUA_TFUNCTION && !ci_func(ci)->c.isC);
-}
-
-
static int currentpc (lua_State *L, CallInfo *ci) {
- if (ci->pc == NULL) return -1; /* function is not an active Lua function */
- if (ci == L->ci || ci->pc != (ci+1)->pc) /* no other function using `pc'? */
- ci->savedpc = *ci->pc; /* may not be saved; save it */
+ if (!isLua(ci)) return -1; /* function is not a Lua function? */
+ /* next function is not using the same `pc'? (not a Lua->Lua call?) */
+ if (ci == L->ci || !isLua(ci+1) || ci->u.l.pc != (ci+1)->u.l.pc)
+ ci->savedpc = *ci->u.l.pc; /* may not be saved; save it */
/* function's pc is saved */
return pcRel(ci->savedpc, ci_func(ci)->l.p);
}
@@ -95,7 +91,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
static Proto *getluaproto (CallInfo *ci) {
- return (isLmark(ci) ? ci_func(ci)->l.p : NULL);
+ return (isLua(ci) ? ci_func(ci)->l.p : NULL);
}
@@ -424,7 +420,7 @@ static const char *kname (Proto *p, int c) {
static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
const char **name) {
- if (isLmark(ci)) { /* an active Lua function? */
+ if (isLua(ci)) { /* an active Lua function? */
Proto *p = ci_func(ci)->l.p;
int pc = currentpc(L, ci);
Instruction i;
@@ -462,7 +458,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
static Instruction getcurrentinstr (lua_State *L, CallInfo *ci) {
- if (ci == L->base_ci || !isLmark(ci))
+ if (ci == L->base_ci || !isLua(ci))
return (Instruction)(-1); /* not an active Lua function */
else
return ci_func(ci)->l.p->code[currentpc(L, ci)];
@@ -531,7 +527,7 @@ static void addinfo (lua_State *L, int internal) {
CallInfo *ci = L->ci;
if (!internal && ci > L->base_ci) ci--;
if (strchr(msg, '\n')) return; /* message already `formatted' */
- if (!isLmark(ci)) { /* no Lua code? */
+ if (!isLua(ci)) { /* no Lua code? */
luaO_pushfstring(L, "%s\n", msg); /* no extra info */
}
else { /* add file:line information */
diff --git a/ldo.c b/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 1.186 2002/07/08 18:21:33 roberto Exp roberto $
+** $Id: ldo.c,v 1.187 2002/07/09 18:19:19 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -60,10 +60,10 @@ static void correctstack (lua_State *L, TObject *oldstack) {
for (ci = L->base_ci; ci <= L->ci; ci++) {
ci->base = (ci->base - oldstack) + L->stack;
ci->top = (ci->top - oldstack) + L->stack;
- if (ci->pc) { /* entry is of an active Lua function? */
- if (ci->pc != (ci-1)->pc)
- *ci->pb = (*ci->pb - oldstack) + L->stack;
- }
+ if (isLua(ci) && /* is a Lua function... */
+ !(isLua(ci-1) && /* and next is not a Lua function... */
+ ci->u.l.pc == (ci-1)->u.l.pc)) /* sharing the same C frame? */
+ *ci->u.l.pb = (*ci->u.l.pb - oldstack) + L->stack; /* correct frame */
}
}
@@ -134,10 +134,6 @@ void luaD_callhook (lua_State *L, lua_Hookevent event, int line) {
ar.event = event;
ar.currentline = line;
ar.i_ci = L->ci - L->base_ci;
- if (event <= LUA_HOOKRET) { /* `call' or `return' event? */
- L->ci->pc = NULL; /* function is not active */
- L->ci->top = L->ci->base; /* `top' may not have a valid value yet */
- }
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
L->ci->top = L->top + LUA_MINSTACK;
setallowhook(L, 0); /* cannot call hooks inside a hook */
@@ -152,11 +148,11 @@ void luaD_callhook (lua_State *L, lua_Hookevent event, int line) {
}
-static void adjust_varargs (lua_State *L, int nfixargs) {
+static void adjust_varargs (lua_State *L, int nfixargs, StkId base) {
int i;
Table *htab;
TObject nname;
- int actual = L->top - L->ci->base; /* actual number of arguments */
+ int actual = L->top - base; /* actual number of arguments */
if (actual < nfixargs) {
luaD_checkstack(L, nfixargs - actual);
for (; actual < nfixargs; ++actual)
@@ -178,49 +174,52 @@ static void adjust_varargs (lua_State *L, int nfixargs) {
static StkId tryfuncTM (lua_State *L, StkId func) {
const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
StkId p;
- if (ttype(tm) != LUA_TFUNCTION) {
- L->ci--; /* undo increment (no function here) */
+ ptrdiff_t funcr = savestack(L, func);
+ if (ttype(tm) != LUA_TFUNCTION)
luaG_typeerror(L, func, "call");
- }
/* Open a hole inside the stack at `func' */
for (p = L->top; p > func; p--) setobj(p, p-1);
incr_top(L);
- func = L->ci->base - 1; /* previous call may change stack */
+ func = restorestack(L, funcr); /* previous call may change stack */
setobj(func, tm); /* tag method is the new function to be called */
return func;
}
StkId luaD_precall (lua_State *L, StkId func) {
- CallInfo *ci;
LClosure *cl;
- if (++L->ci == L->end_ci) luaD_growCI(L);
- ci = L->ci;
- ci->base = func+1;
- ci->pc = NULL;
+ ptrdiff_t funcr = savestack(L, func);
if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */
func = tryfuncTM(L, func); /* check the `function' tag method */
+ if (L->ci + 1 == L->end_ci) luaD_growCI(L);
cl = &clvalue(func)->l;
- if (L->hookmask & LUA_MASKCALL) {
- luaD_callhook(L, LUA_HOOKCALL, -1);
- ci = L->ci; /* previous call may realocate `ci' */
- }
if (!cl->isC) { /* Lua function? prepare its call */
+ CallInfo *ci;
Proto *p = cl->p;
- ci->savedpc = p->code; /* starting point */
if (p->is_vararg) /* varargs? */
- adjust_varargs(L, p->numparams);
+ adjust_varargs(L, p->numparams, func+1);
luaD_checkstack(L, p->maxstacksize);
+ ci = ++L->ci; /* now `enter' new function */
+ ci->base = restorestack(L, funcr) + 1;
ci->top = ci->base + p->maxstacksize;
+ ci->savedpc = p->code; /* starting point */
while (L->top < ci->top)
setnilvalue(L->top++);
L->top = ci->top;
return NULL;
}
else { /* if is a C function, call it */
+ CallInfo *ci;
int n;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
+ ci = ++L->ci; /* now `enter' new function */
+ ci->base = restorestack(L, funcr) + 1;
ci->top = L->top + LUA_MINSTACK;
+ ci->savedpc = NULL; /* not a Lua function */
+ if (L->hookmask & LUA_MASKCALL) {
+ luaD_callhook(L, LUA_HOOKCALL, -1);
+ ci = L->ci; /* previous call may realocate `ci' */
+ }
lua_unlock(L);
#if LUA_COMPATUPVALUES
lua_pushupvalues(L);
@@ -296,9 +295,10 @@ struct ResS {
static void resume (lua_State *L, void *ud) {
StkId firstResult;
CallInfo *ci = L->ci;
- if (ci->savedpc != ci_func(ci)->l.p->code) { /* not first time? */
- /* finish interupted execution of `OP_CALL' */
+ if (!isLua(ci)) { /* not first time? */
+ /* finish interrupted execution of `OP_CALL' */
int nresults;
+ lua_assert(isLua(ci - 1));
lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL);
nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1;
luaD_poscall(L, nresults, L->top); /* complete it */
@@ -306,7 +306,7 @@ static void resume (lua_State *L, void *ud) {
}
firstResult = luaV_execute(L);
if (firstResult == NULL) /* yield? */
- cast(struct ResS *, ud)->numres = L->ci->yield_results;
+ cast(struct ResS *, ud)->numres = L->ci->u.c.yield_results;
else { /* return */
cast(struct ResS *, ud)->numres = L->top - firstResult;
luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */
@@ -338,9 +338,10 @@ LUA_API int lua_yield (lua_State *L, int nresults) {
CallInfo *ci;
lua_lock(L);
ci = L->ci;
- if (ci_func(ci-1)->c.isC)
+ if (!isLua(ci-1))
luaG_runerror(L, "cannot yield a C function");
- ci->yield_results = nresults;
+ lua_assert(!isLua(ci));
+ ci->u.c.yield_results = nresults;
lua_unlock(L);
return -1;
}
diff --git a/lstate.c b/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 1.97 2002/06/18 15:19:27 roberto Exp roberto $
+** $Id: lstate.c,v 1.98 2002/07/08 18:21:33 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -41,9 +41,9 @@ static void stack_init (lua_State *L, lua_State *OL) {
L->stack_last = L->stack+(BASIC_STACK_SIZE-EXTRA_STACK)-1;
L->base_ci = luaM_newvector(OL, BASIC_CI_SIZE, CallInfo);
L->ci = L->base_ci;
+ L->ci->savedpc = NULL;
L->ci->base = L->top;
L->ci->top = L->top + LUA_MINSTACK;
- L->ci->pc = NULL;
L->size_ci = BASIC_CI_SIZE;
L->end_ci = L->base_ci + L->size_ci;
}
diff --git a/lstate.h b/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 1.87 2002/07/08 18:21:33 roberto Exp roberto $
+** $Id: lstate.h,v 1.88 2002/07/08 20:22:08 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -87,13 +87,22 @@ typedef struct stringtable {
*/
typedef struct CallInfo {
StkId base; /* base for called function */
- const Instruction *savedpc;
- StkId top; /* top for this function (when it's a Lua function) */
- const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
- StkId *pb; /* points to `base' variable in `luaV_execute' */
- int yield_results;
+ StkId top; /* top for this function */
+ const Instruction *savedpc; /* NULL means not a Lua function */
+ union {
+ struct { /* for Lua functions */
+ const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
+ StkId *pb; /* points to `base' variable in `luaV_execute' */
+ } l;
+ struct { /* for C functions */
+ int yield_results;
+ } c;
+ } u;
} CallInfo;
+
+#define isLua(ci) ((ci)->savedpc != NULL)
+
#define ci_func(ci) (clvalue((ci)->base - 1))
diff --git a/lvm.c b/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 1.245 2002/07/08 18:21:33 roberto Exp roberto $
+** $Id: lvm.c,v 1.246 2002/07/08 20:22:08 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -80,16 +80,16 @@ static void traceexec (lua_State *L) {
if (mask & LUA_MASKLINE) {
CallInfo *ci = L->ci;
Proto *p = ci_func(ci)->l.p;
- int newline = getline(p, pcRel(*ci->pc, p));
- if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */
- ci->savedpc = *ci->pc; /* initialize `savedpc' */
+ int newline = getline(p, pcRel(*ci->u.l.pc, p));
+ if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */
+ ci->savedpc = *ci->u.l.pc; /* initialize `savedpc' */
/* calls linehook when enters a new line or jumps back (loop) */
- if (*ci->pc <= ci->savedpc ||
+ if (*ci->u.l.pc <= ci->savedpc ||
newline != getline(p, pcRel(ci->savedpc, p))) {
luaD_callhook(L, LUA_HOOKLINE, newline);
ci = L->ci; /* previous call may reallocate `ci' */
}
- ci->savedpc = *ci->pc;
+ ci->savedpc = *ci->u.l.pc;
}
}
@@ -370,9 +370,11 @@ StkId luaV_execute (lua_State *L) {
TObject *k;
const Instruction *pc;
callentry: /* entry point when calling new functions */
- L->ci->pc = &pc;
- L->ci->pb = &base;
+ L->ci->u.l.pc = &pc;
+ L->ci->u.l.pb = &base;
pc = L->ci->savedpc;
+ if (L->hookmask & LUA_MASKCALL)
+ luaD_callhook(L, LUA_HOOKCALL, -1);
retentry: /* entry point when returning to old functions */
base = L->ci->base;
cl = &clvalue(base - 1)->l;
@@ -619,12 +621,13 @@ StkId luaV_execute (lua_State *L) {
if (L->openupval) luaF_close(L, base);
b = GETARG_B(i);
if (b != 0) L->top = ra+b-1;
- lua_assert(L->ci->pc == &pc);
+ lua_assert(L->ci->u.l.pc == &pc);
}
ret: {
CallInfo *ci;
ci = L->ci - 1;
- if (ci->pc != &pc) /* previous function was running `here'? */
+ /* previous function was running `here'? */
+ if (!isLua(ci) || ci->u.l.pc != &pc)
return ra; /* no: return */
else { /* yes: continue its execution */
int nresults;