mirror of
https://github.com/lua/lua.git
synced 2025-01-14 05:43:00 +08:00
CallInfo has different fields for C functions and Lua functions
This commit is contained in:
parent
ce6b930464
commit
e5146fb01f
22
ldebug.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
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
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
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
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…
x
Reference in New Issue
Block a user