Browse Source

CallInfo has different fields for C functions and Lua functions

v5-2
Roberto Ierusalimschy 23 years ago
parent
commit
e5146fb01f
  1. 22
      ldebug.c
  2. 63
      ldo.c
  3. 4
      lstate.c
  4. 21
      lstate.h
  5. 23
      lvm.c

22
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 */

63
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;
}

4
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;
}

21
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))

23
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;

Loading…
Cancel
Save