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