CallInfo has different fields for C functions and Lua functions

This commit is contained in:
Roberto Ierusalimschy
2002-07-16 11:26:56 -03:00
parent ce6b930464
commit e5146fb01f
5 changed files with 71 additions and 62 deletions

View File

@@ -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 ** Debug Interface
** See Copyright Notice in lua.h ** 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) { static int currentpc (lua_State *L, CallInfo *ci) {
if (ci->pc == NULL) return -1; /* function is not an active Lua function */ if (!isLua(ci)) return -1; /* function is not a Lua function? */
if (ci == L->ci || ci->pc != (ci+1)->pc) /* no other function using `pc'? */ /* next function is not using the same `pc'? (not a Lua->Lua call?) */
ci->savedpc = *ci->pc; /* may not be saved; save it */ 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 */ /* function's pc is saved */
return pcRel(ci->savedpc, ci_func(ci)->l.p); 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) { 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, static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
const char **name) { const char **name) {
if (isLmark(ci)) { /* an active Lua function? */ if (isLua(ci)) { /* an active Lua function? */
Proto *p = ci_func(ci)->l.p; Proto *p = ci_func(ci)->l.p;
int pc = currentpc(L, ci); int pc = currentpc(L, ci);
Instruction i; 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) { 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 */ return (Instruction)(-1); /* not an active Lua function */
else else
return ci_func(ci)->l.p->code[currentpc(L, ci)]; 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; CallInfo *ci = L->ci;
if (!internal && ci > L->base_ci) ci--; if (!internal && ci > L->base_ci) ci--;
if (strchr(msg, '\n')) return; /* message already `formatted' */ 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 */ luaO_pushfstring(L, "%s\n", msg); /* no extra info */
} }
else { /* add file:line information */ else { /* add file:line information */

63
ldo.c
View File

@@ -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 ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** 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++) { for (ci = L->base_ci; ci <= L->ci; ci++) {
ci->base = (ci->base - oldstack) + L->stack; ci->base = (ci->base - oldstack) + L->stack;
ci->top = (ci->top - oldstack) + L->stack; ci->top = (ci->top - oldstack) + L->stack;
if (ci->pc) { /* entry is of an active Lua function? */ if (isLua(ci) && /* is a Lua function... */
if (ci->pc != (ci-1)->pc) !(isLua(ci-1) && /* and next is not a Lua function... */
*ci->pb = (*ci->pb - oldstack) + L->stack; 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.event = event;
ar.currentline = line; ar.currentline = line;
ar.i_ci = L->ci - L->base_ci; 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 */ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
L->ci->top = L->top + LUA_MINSTACK; L->ci->top = L->top + LUA_MINSTACK;
setallowhook(L, 0); /* cannot call hooks inside a hook */ 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; int i;
Table *htab; Table *htab;
TObject nname; 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) { if (actual < nfixargs) {
luaD_checkstack(L, nfixargs - actual); luaD_checkstack(L, nfixargs - actual);
for (; actual < 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) { static StkId tryfuncTM (lua_State *L, StkId func) {
const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
StkId p; StkId p;
if (ttype(tm) != LUA_TFUNCTION) { ptrdiff_t funcr = savestack(L, func);
L->ci--; /* undo increment (no function here) */ if (ttype(tm) != LUA_TFUNCTION)
luaG_typeerror(L, func, "call"); luaG_typeerror(L, func, "call");
}
/* Open a hole inside the stack at `func' */ /* Open a hole inside the stack at `func' */
for (p = L->top; p > func; p--) setobj(p, p-1); for (p = L->top; p > func; p--) setobj(p, p-1);
incr_top(L); 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 */ setobj(func, tm); /* tag method is the new function to be called */
return func; return func;
} }
StkId luaD_precall (lua_State *L, StkId func) { StkId luaD_precall (lua_State *L, StkId func) {
CallInfo *ci;
LClosure *cl; LClosure *cl;
if (++L->ci == L->end_ci) luaD_growCI(L); ptrdiff_t funcr = savestack(L, func);
ci = L->ci;
ci->base = func+1;
ci->pc = NULL;
if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */ if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */
func = tryfuncTM(L, func); /* check the `function' tag method */ func = tryfuncTM(L, func); /* check the `function' tag method */
if (L->ci + 1 == L->end_ci) luaD_growCI(L);
cl = &clvalue(func)->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 */ if (!cl->isC) { /* Lua function? prepare its call */
CallInfo *ci;
Proto *p = cl->p; Proto *p = cl->p;
ci->savedpc = p->code; /* starting point */
if (p->is_vararg) /* varargs? */ if (p->is_vararg) /* varargs? */
adjust_varargs(L, p->numparams); adjust_varargs(L, p->numparams, func+1);
luaD_checkstack(L, p->maxstacksize); 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->top = ci->base + p->maxstacksize;
ci->savedpc = p->code; /* starting point */
while (L->top < ci->top) while (L->top < ci->top)
setnilvalue(L->top++); setnilvalue(L->top++);
L->top = ci->top; L->top = ci->top;
return NULL; return NULL;
} }
else { /* if is a C function, call it */ else { /* if is a C function, call it */
CallInfo *ci;
int n; int n;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 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->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); lua_unlock(L);
#if LUA_COMPATUPVALUES #if LUA_COMPATUPVALUES
lua_pushupvalues(L); lua_pushupvalues(L);
@@ -296,9 +295,10 @@ struct ResS {
static void resume (lua_State *L, void *ud) { static void resume (lua_State *L, void *ud) {
StkId firstResult; StkId firstResult;
CallInfo *ci = L->ci; CallInfo *ci = L->ci;
if (ci->savedpc != ci_func(ci)->l.p->code) { /* not first time? */ if (!isLua(ci)) { /* not first time? */
/* finish interupted execution of `OP_CALL' */ /* finish interrupted execution of `OP_CALL' */
int nresults; int nresults;
lua_assert(isLua(ci - 1));
lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL); lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL);
nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1; nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1;
luaD_poscall(L, nresults, L->top); /* complete it */ luaD_poscall(L, nresults, L->top); /* complete it */
@@ -306,7 +306,7 @@ static void resume (lua_State *L, void *ud) {
} }
firstResult = luaV_execute(L); firstResult = luaV_execute(L);
if (firstResult == NULL) /* yield? */ 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 */ else { /* return */
cast(struct ResS *, ud)->numres = L->top - firstResult; cast(struct ResS *, ud)->numres = L->top - firstResult;
luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ 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; CallInfo *ci;
lua_lock(L); lua_lock(L);
ci = L->ci; ci = L->ci;
if (ci_func(ci-1)->c.isC) if (!isLua(ci-1))
luaG_runerror(L, "cannot yield a C function"); 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); lua_unlock(L);
return -1; return -1;
} }

View File

@@ -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 ** Global State
** See Copyright Notice in lua.h ** 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->stack_last = L->stack+(BASIC_STACK_SIZE-EXTRA_STACK)-1;
L->base_ci = luaM_newvector(OL, BASIC_CI_SIZE, CallInfo); L->base_ci = luaM_newvector(OL, BASIC_CI_SIZE, CallInfo);
L->ci = L->base_ci; L->ci = L->base_ci;
L->ci->savedpc = NULL;
L->ci->base = L->top; L->ci->base = L->top;
L->ci->top = L->top + LUA_MINSTACK; L->ci->top = L->top + LUA_MINSTACK;
L->ci->pc = NULL;
L->size_ci = BASIC_CI_SIZE; L->size_ci = BASIC_CI_SIZE;
L->end_ci = L->base_ci + L->size_ci; L->end_ci = L->base_ci + L->size_ci;
} }

View File

@@ -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 ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -87,13 +87,22 @@ typedef struct stringtable {
*/ */
typedef struct CallInfo { typedef struct CallInfo {
StkId base; /* base for called function */ StkId base; /* base for called function */
const Instruction *savedpc; StkId top; /* top for this function */
StkId top; /* top for this function (when it's a Lua function) */ const Instruction *savedpc; /* NULL means not a Lua function */
const Instruction **pc; /* points to `pc' variable in `luaV_execute' */ union {
StkId *pb; /* points to `base' variable in `luaV_execute' */ struct { /* for Lua functions */
int yield_results; 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; } CallInfo;
#define isLua(ci) ((ci)->savedpc != NULL)
#define ci_func(ci) (clvalue((ci)->base - 1)) #define ci_func(ci) (clvalue((ci)->base - 1))

23
lvm.c
View File

@@ -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 ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -80,16 +80,16 @@ static void traceexec (lua_State *L) {
if (mask & LUA_MASKLINE) { if (mask & LUA_MASKLINE) {
CallInfo *ci = L->ci; CallInfo *ci = L->ci;
Proto *p = ci_func(ci)->l.p; Proto *p = ci_func(ci)->l.p;
int newline = getline(p, pcRel(*ci->pc, p)); int newline = getline(p, pcRel(*ci->u.l.pc, p));
if (pcRel(*ci->pc, p) == 0) /* tracing may be starting now? */ if (pcRel(*ci->u.l.pc, p) == 0) /* tracing may be starting now? */
ci->savedpc = *ci->pc; /* initialize `savedpc' */ ci->savedpc = *ci->u.l.pc; /* initialize `savedpc' */
/* calls linehook when enters a new line or jumps back (loop) */ /* 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))) { newline != getline(p, pcRel(ci->savedpc, p))) {
luaD_callhook(L, LUA_HOOKLINE, newline); luaD_callhook(L, LUA_HOOKLINE, newline);
ci = L->ci; /* previous call may reallocate `ci' */ 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; TObject *k;
const Instruction *pc; const Instruction *pc;
callentry: /* entry point when calling new functions */ callentry: /* entry point when calling new functions */
L->ci->pc = &pc; L->ci->u.l.pc = &pc;
L->ci->pb = &base; L->ci->u.l.pb = &base;
pc = L->ci->savedpc; pc = L->ci->savedpc;
if (L->hookmask & LUA_MASKCALL)
luaD_callhook(L, LUA_HOOKCALL, -1);
retentry: /* entry point when returning to old functions */ retentry: /* entry point when returning to old functions */
base = L->ci->base; base = L->ci->base;
cl = &clvalue(base - 1)->l; cl = &clvalue(base - 1)->l;
@@ -619,12 +621,13 @@ StkId luaV_execute (lua_State *L) {
if (L->openupval) luaF_close(L, base); if (L->openupval) luaF_close(L, base);
b = GETARG_B(i); b = GETARG_B(i);
if (b != 0) L->top = ra+b-1; if (b != 0) L->top = ra+b-1;
lua_assert(L->ci->pc == &pc); lua_assert(L->ci->u.l.pc == &pc);
} }
ret: { ret: {
CallInfo *ci; CallInfo *ci;
ci = L->ci - 1; 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 */ return ra; /* no: return */
else { /* yes: continue its execution */ else { /* yes: continue its execution */
int nresults; int nresults;