diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-07-16 11:26:56 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-07-16 11:26:56 -0300 |
| commit | e5146fb01f1ccb40c2663e745feffbf642cbf862 (patch) | |
| tree | 7015808b9b2bcd6c45f2042074459ce766fa0bd8 /ldo.c | |
| parent | ce6b930464edd621ec95ddab2ce9ccb7ddae605a (diff) | |
| download | lua-e5146fb01f1ccb40c2663e745feffbf642cbf862.tar.gz lua-e5146fb01f1ccb40c2663e745feffbf642cbf862.tar.bz2 lua-e5146fb01f1ccb40c2663e745feffbf642cbf862.zip | |
CallInfo has different fields for C functions and Lua functions
Diffstat (limited to 'ldo.c')
| -rw-r--r-- | ldo.c | 63 |
1 files changed, 32 insertions, 31 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 1.186 2002/07/08 18:21:33 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.187 2002/07/09 18:19:19 roberto Exp roberto $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -60,10 +60,10 @@ static void correctstack (lua_State *L, TObject *oldstack) { | |||
| 60 | for (ci = L->base_ci; ci <= L->ci; ci++) { | 60 | for (ci = L->base_ci; ci <= L->ci; ci++) { |
| 61 | ci->base = (ci->base - oldstack) + L->stack; | 61 | ci->base = (ci->base - oldstack) + L->stack; |
| 62 | ci->top = (ci->top - oldstack) + L->stack; | 62 | ci->top = (ci->top - oldstack) + L->stack; |
| 63 | if (ci->pc) { /* entry is of an active Lua function? */ | 63 | if (isLua(ci) && /* is a Lua function... */ |
| 64 | if (ci->pc != (ci-1)->pc) | 64 | !(isLua(ci-1) && /* and next is not a Lua function... */ |
| 65 | *ci->pb = (*ci->pb - oldstack) + L->stack; | 65 | ci->u.l.pc == (ci-1)->u.l.pc)) /* sharing the same C frame? */ |
| 66 | } | 66 | *ci->u.l.pb = (*ci->u.l.pb - oldstack) + L->stack; /* correct frame */ |
| 67 | } | 67 | } |
| 68 | } | 68 | } |
| 69 | 69 | ||
| @@ -134,10 +134,6 @@ void luaD_callhook (lua_State *L, lua_Hookevent event, int line) { | |||
| 134 | ar.event = event; | 134 | ar.event = event; |
| 135 | ar.currentline = line; | 135 | ar.currentline = line; |
| 136 | ar.i_ci = L->ci - L->base_ci; | 136 | ar.i_ci = L->ci - L->base_ci; |
| 137 | if (event <= LUA_HOOKRET) { /* `call' or `return' event? */ | ||
| 138 | L->ci->pc = NULL; /* function is not active */ | ||
| 139 | L->ci->top = L->ci->base; /* `top' may not have a valid value yet */ | ||
| 140 | } | ||
| 141 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 137 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 142 | L->ci->top = L->top + LUA_MINSTACK; | 138 | L->ci->top = L->top + LUA_MINSTACK; |
| 143 | setallowhook(L, 0); /* cannot call hooks inside a hook */ | 139 | setallowhook(L, 0); /* cannot call hooks inside a hook */ |
| @@ -152,11 +148,11 @@ void luaD_callhook (lua_State *L, lua_Hookevent event, int line) { | |||
| 152 | } | 148 | } |
| 153 | 149 | ||
| 154 | 150 | ||
| 155 | static void adjust_varargs (lua_State *L, int nfixargs) { | 151 | static void adjust_varargs (lua_State *L, int nfixargs, StkId base) { |
| 156 | int i; | 152 | int i; |
| 157 | Table *htab; | 153 | Table *htab; |
| 158 | TObject nname; | 154 | TObject nname; |
| 159 | int actual = L->top - L->ci->base; /* actual number of arguments */ | 155 | int actual = L->top - base; /* actual number of arguments */ |
| 160 | if (actual < nfixargs) { | 156 | if (actual < nfixargs) { |
| 161 | luaD_checkstack(L, nfixargs - actual); | 157 | luaD_checkstack(L, nfixargs - actual); |
| 162 | for (; actual < nfixargs; ++actual) | 158 | for (; actual < nfixargs; ++actual) |
| @@ -178,49 +174,52 @@ static void adjust_varargs (lua_State *L, int nfixargs) { | |||
| 178 | static StkId tryfuncTM (lua_State *L, StkId func) { | 174 | static StkId tryfuncTM (lua_State *L, StkId func) { |
| 179 | const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); | 175 | const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); |
| 180 | StkId p; | 176 | StkId p; |
| 181 | if (ttype(tm) != LUA_TFUNCTION) { | 177 | ptrdiff_t funcr = savestack(L, func); |
| 182 | L->ci--; /* undo increment (no function here) */ | 178 | if (ttype(tm) != LUA_TFUNCTION) |
| 183 | luaG_typeerror(L, func, "call"); | 179 | luaG_typeerror(L, func, "call"); |
| 184 | } | ||
| 185 | /* Open a hole inside the stack at `func' */ | 180 | /* Open a hole inside the stack at `func' */ |
| 186 | for (p = L->top; p > func; p--) setobj(p, p-1); | 181 | for (p = L->top; p > func; p--) setobj(p, p-1); |
| 187 | incr_top(L); | 182 | incr_top(L); |
| 188 | func = L->ci->base - 1; /* previous call may change stack */ | 183 | func = restorestack(L, funcr); /* previous call may change stack */ |
| 189 | setobj(func, tm); /* tag method is the new function to be called */ | 184 | setobj(func, tm); /* tag method is the new function to be called */ |
| 190 | return func; | 185 | return func; |
| 191 | } | 186 | } |
| 192 | 187 | ||
| 193 | 188 | ||
| 194 | StkId luaD_precall (lua_State *L, StkId func) { | 189 | StkId luaD_precall (lua_State *L, StkId func) { |
| 195 | CallInfo *ci; | ||
| 196 | LClosure *cl; | 190 | LClosure *cl; |
| 197 | if (++L->ci == L->end_ci) luaD_growCI(L); | 191 | ptrdiff_t funcr = savestack(L, func); |
| 198 | ci = L->ci; | ||
| 199 | ci->base = func+1; | ||
| 200 | ci->pc = NULL; | ||
| 201 | if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */ | 192 | if (ttype(func) != LUA_TFUNCTION) /* `func' is not a function? */ |
| 202 | func = tryfuncTM(L, func); /* check the `function' tag method */ | 193 | func = tryfuncTM(L, func); /* check the `function' tag method */ |
| 194 | if (L->ci + 1 == L->end_ci) luaD_growCI(L); | ||
| 203 | cl = &clvalue(func)->l; | 195 | cl = &clvalue(func)->l; |
| 204 | if (L->hookmask & LUA_MASKCALL) { | ||
| 205 | luaD_callhook(L, LUA_HOOKCALL, -1); | ||
| 206 | ci = L->ci; /* previous call may realocate `ci' */ | ||
| 207 | } | ||
| 208 | if (!cl->isC) { /* Lua function? prepare its call */ | 196 | if (!cl->isC) { /* Lua function? prepare its call */ |
| 197 | CallInfo *ci; | ||
| 209 | Proto *p = cl->p; | 198 | Proto *p = cl->p; |
| 210 | ci->savedpc = p->code; /* starting point */ | ||
| 211 | if (p->is_vararg) /* varargs? */ | 199 | if (p->is_vararg) /* varargs? */ |
| 212 | adjust_varargs(L, p->numparams); | 200 | adjust_varargs(L, p->numparams, func+1); |
| 213 | luaD_checkstack(L, p->maxstacksize); | 201 | luaD_checkstack(L, p->maxstacksize); |
| 202 | ci = ++L->ci; /* now `enter' new function */ | ||
| 203 | ci->base = restorestack(L, funcr) + 1; | ||
| 214 | ci->top = ci->base + p->maxstacksize; | 204 | ci->top = ci->base + p->maxstacksize; |
| 205 | ci->savedpc = p->code; /* starting point */ | ||
| 215 | while (L->top < ci->top) | 206 | while (L->top < ci->top) |
| 216 | setnilvalue(L->top++); | 207 | setnilvalue(L->top++); |
| 217 | L->top = ci->top; | 208 | L->top = ci->top; |
| 218 | return NULL; | 209 | return NULL; |
| 219 | } | 210 | } |
| 220 | else { /* if is a C function, call it */ | 211 | else { /* if is a C function, call it */ |
| 212 | CallInfo *ci; | ||
| 221 | int n; | 213 | int n; |
| 222 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 214 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 215 | ci = ++L->ci; /* now `enter' new function */ | ||
| 216 | ci->base = restorestack(L, funcr) + 1; | ||
| 223 | ci->top = L->top + LUA_MINSTACK; | 217 | ci->top = L->top + LUA_MINSTACK; |
| 218 | ci->savedpc = NULL; /* not a Lua function */ | ||
| 219 | if (L->hookmask & LUA_MASKCALL) { | ||
| 220 | luaD_callhook(L, LUA_HOOKCALL, -1); | ||
| 221 | ci = L->ci; /* previous call may realocate `ci' */ | ||
| 222 | } | ||
| 224 | lua_unlock(L); | 223 | lua_unlock(L); |
| 225 | #if LUA_COMPATUPVALUES | 224 | #if LUA_COMPATUPVALUES |
| 226 | lua_pushupvalues(L); | 225 | lua_pushupvalues(L); |
| @@ -296,9 +295,10 @@ struct ResS { | |||
| 296 | static void resume (lua_State *L, void *ud) { | 295 | static void resume (lua_State *L, void *ud) { |
| 297 | StkId firstResult; | 296 | StkId firstResult; |
| 298 | CallInfo *ci = L->ci; | 297 | CallInfo *ci = L->ci; |
| 299 | if (ci->savedpc != ci_func(ci)->l.p->code) { /* not first time? */ | 298 | if (!isLua(ci)) { /* not first time? */ |
| 300 | /* finish interupted execution of `OP_CALL' */ | 299 | /* finish interrupted execution of `OP_CALL' */ |
| 301 | int nresults; | 300 | int nresults; |
| 301 | lua_assert(isLua(ci - 1)); | ||
| 302 | lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL); | 302 | lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL); |
| 303 | nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1; | 303 | nresults = GETARG_C(*((ci-1)->savedpc - 1)) - 1; |
| 304 | luaD_poscall(L, nresults, L->top); /* complete it */ | 304 | luaD_poscall(L, nresults, L->top); /* complete it */ |
| @@ -306,7 +306,7 @@ static void resume (lua_State *L, void *ud) { | |||
| 306 | } | 306 | } |
| 307 | firstResult = luaV_execute(L); | 307 | firstResult = luaV_execute(L); |
| 308 | if (firstResult == NULL) /* yield? */ | 308 | if (firstResult == NULL) /* yield? */ |
| 309 | cast(struct ResS *, ud)->numres = L->ci->yield_results; | 309 | cast(struct ResS *, ud)->numres = L->ci->u.c.yield_results; |
| 310 | else { /* return */ | 310 | else { /* return */ |
| 311 | cast(struct ResS *, ud)->numres = L->top - firstResult; | 311 | cast(struct ResS *, ud)->numres = L->top - firstResult; |
| 312 | luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ | 312 | luaD_poscall(L, LUA_MULTRET, firstResult); /* finalize this coroutine */ |
| @@ -338,9 +338,10 @@ LUA_API int lua_yield (lua_State *L, int nresults) { | |||
| 338 | CallInfo *ci; | 338 | CallInfo *ci; |
| 339 | lua_lock(L); | 339 | lua_lock(L); |
| 340 | ci = L->ci; | 340 | ci = L->ci; |
| 341 | if (ci_func(ci-1)->c.isC) | 341 | if (!isLua(ci-1)) |
| 342 | luaG_runerror(L, "cannot yield a C function"); | 342 | luaG_runerror(L, "cannot yield a C function"); |
| 343 | ci->yield_results = nresults; | 343 | lua_assert(!isLua(ci)); |
| 344 | ci->u.c.yield_results = nresults; | ||
| 344 | lua_unlock(L); | 345 | lua_unlock(L); |
| 345 | return -1; | 346 | return -1; |
| 346 | } | 347 | } |
