diff options
-rw-r--r-- | lapi.c | 19 | ||||
-rw-r--r-- | ldebug.c | 8 | ||||
-rw-r--r-- | ldo.c | 52 | ||||
-rw-r--r-- | lstate.c | 3 | ||||
-rw-r--r-- | lstate.h | 5 | ||||
-rw-r--r-- | ltests.c | 26 | ||||
-rw-r--r-- | ltests.h | 3 | ||||
-rw-r--r-- | lvm.c | 155 |
8 files changed, 133 insertions, 138 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.74 2009/04/08 18:04:33 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.75 2009/04/17 14:28:06 roberto Exp roberto $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -829,18 +829,19 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, | |||
829 | status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); | 829 | status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); |
830 | } | 830 | } |
831 | else { /* prepare continuation (call is already protected by 'resume') */ | 831 | else { /* prepare continuation (call is already protected by 'resume') */ |
832 | L->ci->u.c.k = k; /* save continuation */ | 832 | CallInfo *ci = L->ci; |
833 | L->ci->u.c.ctx = ctx; /* save context */ | 833 | ci->u.c.k = k; /* save continuation */ |
834 | ci->u.c.ctx = ctx; /* save context */ | ||
834 | /* save information for error recovery */ | 835 | /* save information for error recovery */ |
835 | L->ci->u.c.oldtop = savestack(L, c.func); | 836 | ci->u.c.oldtop = savestack(L, c.func); |
836 | L->ci->u.c.old_allowhook = L->allowhook; | 837 | ci->u.c.old_allowhook = L->allowhook; |
837 | L->ci->u.c.old_errfunc = L->errfunc; | 838 | ci->u.c.old_errfunc = L->errfunc; |
838 | L->errfunc = func; | 839 | L->errfunc = func; |
839 | /* mark that function may do error recovery */ | 840 | /* mark that function may do error recovery */ |
840 | L->ci->callstatus |= CIST_YPCALL; | 841 | ci->callstatus |= CIST_YPCALL; |
841 | luaD_call(L, c.func, nresults, 1); /* do the call */ | 842 | luaD_call(L, c.func, nresults, 1); /* do the call */ |
842 | L->ci->callstatus &= ~CIST_YPCALL; | 843 | ci->callstatus &= ~CIST_YPCALL; |
843 | L->errfunc = L->ci->u.c.old_errfunc; | 844 | L->errfunc = ci->u.c.old_errfunc; |
844 | status = LUA_OK; /* if it is here, there were no errors */ | 845 | status = LUA_OK; /* if it is here, there were no errors */ |
845 | } | 846 | } |
846 | adjustresults(L, nresults); | 847 | adjustresults(L, nresults); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 2.45 2009/03/26 12:56:38 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.46 2009/04/17 14:28:06 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -35,9 +35,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); | |||
35 | 35 | ||
36 | static int currentpc (lua_State *L, CallInfo *ci) { | 36 | static int currentpc (lua_State *L, CallInfo *ci) { |
37 | if (!isLua(ci)) return -1; /* function is not a Lua function? */ | 37 | if (!isLua(ci)) return -1; /* function is not a Lua function? */ |
38 | if (ci == L->ci) | 38 | return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); |
39 | ci->savedpc = L->savedpc; | ||
40 | return pcRel(ci->savedpc, ci_func(ci)->l.p); | ||
41 | } | 39 | } |
42 | 40 | ||
43 | 41 | ||
@@ -58,7 +56,7 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { | |||
58 | mask = 0; | 56 | mask = 0; |
59 | func = NULL; | 57 | func = NULL; |
60 | } | 58 | } |
61 | L->oldpc = L->savedpc; | 59 | L->oldpc = NULL; |
62 | L->hook = func; | 60 | L->hook = func; |
63 | L->basehookcount = count; | 61 | L->basehookcount = count; |
64 | resethookcount(L); | 62 | resethookcount(L); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.59 2009/04/15 16:53:39 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.60 2009/04/17 14:28:06 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 | */ |
@@ -151,28 +151,29 @@ void luaD_growstack (lua_State *L, int n) { | |||
151 | void luaD_callhook (lua_State *L, int event, int line) { | 151 | void luaD_callhook (lua_State *L, int event, int line) { |
152 | lua_Hook hook = L->hook; | 152 | lua_Hook hook = L->hook; |
153 | if (hook && L->allowhook) { | 153 | if (hook && L->allowhook) { |
154 | CallInfo *ci = L->ci; | ||
154 | ptrdiff_t top = savestack(L, L->top); | 155 | ptrdiff_t top = savestack(L, L->top); |
155 | ptrdiff_t ci_top = savestack(L, L->ci->top); | 156 | ptrdiff_t ci_top = savestack(L, ci->top); |
156 | lua_Debug ar; | 157 | lua_Debug ar; |
157 | ar.event = event; | 158 | ar.event = event; |
158 | ar.currentline = line; | 159 | ar.currentline = line; |
159 | if (event == LUA_HOOKTAILRET) | 160 | if (event == LUA_HOOKTAILRET) |
160 | ar.i_ci = NULL; /* tail call; no debug information about it */ | 161 | ar.i_ci = NULL; /* tail call; no debug information about it */ |
161 | else | 162 | else |
162 | ar.i_ci = L->ci; | 163 | ar.i_ci = ci; |
163 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 164 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
164 | L->ci->top = L->top + LUA_MINSTACK; | 165 | ci->top = L->top + LUA_MINSTACK; |
165 | lua_assert(L->ci->top <= L->stack_last); | 166 | lua_assert(ci->top <= L->stack_last); |
166 | L->allowhook = 0; /* cannot call hooks inside a hook */ | 167 | L->allowhook = 0; /* cannot call hooks inside a hook */ |
167 | L->ci->callstatus |= CIST_HOOKED; | 168 | ci->callstatus |= CIST_HOOKED; |
168 | lua_unlock(L); | 169 | lua_unlock(L); |
169 | (*hook)(L, &ar); | 170 | (*hook)(L, &ar); |
170 | lua_lock(L); | 171 | lua_lock(L); |
171 | lua_assert(!L->allowhook); | 172 | lua_assert(!L->allowhook); |
172 | L->allowhook = 1; | 173 | L->allowhook = 1; |
173 | L->ci->top = restorestack(L, ci_top); | 174 | ci->top = restorestack(L, ci_top); |
174 | L->top = restorestack(L, top); | 175 | L->top = restorestack(L, top); |
175 | L->ci->callstatus &= ~CIST_HOOKED; | 176 | ci->callstatus &= ~CIST_HOOKED; |
176 | } | 177 | } |
177 | } | 178 | } |
178 | 179 | ||
@@ -223,7 +224,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
223 | func = tryfuncTM(L, func); /* check the `function' tag method */ | 224 | func = tryfuncTM(L, func); /* check the `function' tag method */ |
224 | funcr = savestack(L, func); | 225 | funcr = savestack(L, func); |
225 | cl = &clvalue(func)->l; | 226 | cl = &clvalue(func)->l; |
226 | L->ci->savedpc = L->savedpc; | ||
227 | L->ci->nresults = nresults; | 227 | L->ci->nresults = nresults; |
228 | if (!cl->isC) { /* Lua function? prepare its call */ | 228 | if (!cl->isC) { /* Lua function? prepare its call */ |
229 | CallInfo *ci; | 229 | CallInfo *ci; |
@@ -243,16 +243,16 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
243 | L->base = ci->base = base; | 243 | L->base = ci->base = base; |
244 | ci->top = L->base + p->maxstacksize; | 244 | ci->top = L->base + p->maxstacksize; |
245 | lua_assert(ci->top <= L->stack_last); | 245 | lua_assert(ci->top <= L->stack_last); |
246 | L->savedpc = p->code; /* starting point */ | 246 | ci->u.l.savedpc = p->code; /* starting point */ |
247 | ci->u.l.tailcalls = 0; | 247 | ci->u.l.tailcalls = 0; |
248 | ci->callstatus = CIST_LUA; | 248 | ci->callstatus = CIST_LUA; |
249 | for (st = L->top; st < ci->top; st++) | 249 | for (st = L->top; st < ci->top; st++) |
250 | setnilvalue(st); | 250 | setnilvalue(st); |
251 | L->top = ci->top; | 251 | L->top = ci->top; |
252 | if (L->hookmask & LUA_MASKCALL) { | 252 | if (L->hookmask & LUA_MASKCALL) { |
253 | L->savedpc++; /* hooks assume 'pc' is already incremented */ | 253 | ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ |
254 | luaD_callhook(L, LUA_HOOKCALL, -1); | 254 | luaD_callhook(L, LUA_HOOKCALL, -1); |
255 | L->savedpc--; /* correct 'pc' */ | 255 | ci->u.l.savedpc--; /* correct 'pc' */ |
256 | } | 256 | } |
257 | return 0; | 257 | return 0; |
258 | } | 258 | } |
@@ -295,13 +295,12 @@ int luaD_poscall (lua_State *L, StkId firstResult) { | |||
295 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { | 295 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { |
296 | if (L->hookmask & LUA_MASKRET) | 296 | if (L->hookmask & LUA_MASKRET) |
297 | firstResult = callrethooks(L, firstResult); | 297 | firstResult = callrethooks(L, firstResult); |
298 | L->oldpc = L->ci->previous->savedpc; /* 'oldpc' for returning function */ | 298 | L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for returning function */ |
299 | } | 299 | } |
300 | res = ci->func; /* res == final position of 1st result */ | 300 | res = ci->func; /* res == final position of 1st result */ |
301 | L->ci = ci = L->ci->previous; /* back to caller */ | 301 | L->ci = ci = ci->previous; /* back to caller */ |
302 | wanted = ci->nresults; | 302 | wanted = ci->nresults; |
303 | L->base = ci->base; /* restore base */ | 303 | L->base = ci->base; /* restore base */ |
304 | L->savedpc = ci->savedpc; /* restore savedpc */ | ||
305 | /* move results to correct place */ | 304 | /* move results to correct place */ |
306 | for (i = wanted; i != 0 && firstResult < L->top; i--) | 305 | for (i = wanted; i != 0 && firstResult < L->top; i--) |
307 | setobjs2s(L, res++, firstResult++); | 306 | setobjs2s(L, res++, firstResult++); |
@@ -336,21 +335,21 @@ void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) { | |||
336 | 335 | ||
337 | 336 | ||
338 | static void finishCcall (lua_State *L) { | 337 | static void finishCcall (lua_State *L) { |
338 | CallInfo *ci = L->ci; | ||
339 | int n; | 339 | int n; |
340 | lua_assert(L->ci->u.c.k != NULL); /* must have a continuation */ | 340 | lua_assert(ci->u.c.k != NULL); /* must have a continuation */ |
341 | lua_assert(L->nny == 0); | 341 | lua_assert(L->nny == 0); |
342 | /* finish 'luaD_call' */ | 342 | /* finish 'luaD_call' */ |
343 | G(L)->nCcalls--; | 343 | G(L)->nCcalls--; |
344 | /* finish 'lua_callk' */ | 344 | /* finish 'lua_callk' */ |
345 | adjustresults(L, L->ci->nresults); | 345 | adjustresults(L, ci->nresults); |
346 | /* call continuation function */ | 346 | /* call continuation function */ |
347 | if (!(L->ci->callstatus & CIST_STAT)) /* no call status? */ | 347 | if (!(ci->callstatus & CIST_STAT)) /* no call status? */ |
348 | L->ci->u.c.status = LUA_YIELD; /* 'default' status */ | 348 | ci->u.c.status = LUA_YIELD; /* 'default' status */ |
349 | lua_assert(L->ci->u.c.status != LUA_OK); | 349 | lua_assert(ci->u.c.status != LUA_OK); |
350 | L->ci->callstatus = (L->ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | 350 | ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED; |
351 | | CIST_YIELDED; | ||
352 | lua_unlock(L); | 351 | lua_unlock(L); |
353 | n = (*L->ci->u.c.k)(L); | 352 | n = (*ci->u.c.k)(L); |
354 | lua_lock(L); | 353 | lua_lock(L); |
355 | /* finish 'luaD_precall' */ | 354 | /* finish 'luaD_precall' */ |
356 | luaD_poscall(L, L->top - n); | 355 | luaD_poscall(L, L->top - n); |
@@ -384,7 +383,7 @@ static void resume (lua_State *L, void *ud) { | |||
384 | lua_assert(L->status == LUA_YIELD); | 383 | lua_assert(L->status == LUA_YIELD); |
385 | L->status = LUA_OK; | 384 | L->status = LUA_OK; |
386 | if (isLua(ci)) { /* yielded inside a hook? */ | 385 | if (isLua(ci)) { /* yielded inside a hook? */ |
387 | L->base = L->ci->base; /* just continue its execution */ | 386 | L->base = ci->base; /* just continue its execution */ |
388 | luaV_execute(L); | 387 | luaV_execute(L); |
389 | } | 388 | } |
390 | else { /* 'common' yield */ | 389 | else { /* 'common' yield */ |
@@ -427,7 +426,7 @@ static int recover (lua_State *L, int status) { | |||
427 | luaF_close(L, oldtop); | 426 | luaF_close(L, oldtop); |
428 | luaD_seterrorobj(L, status, oldtop); | 427 | luaD_seterrorobj(L, status, oldtop); |
429 | L->ci = ci; | 428 | L->ci = ci; |
430 | L->base = L->ci->base; | 429 | L->base = ci->base; |
431 | L->allowhook = ci->u.c.old_allowhook; | 430 | L->allowhook = ci->u.c.old_allowhook; |
432 | L->nny = 0; /* should be zero to be yieldable */ | 431 | L->nny = 0; /* should be zero to be yieldable */ |
433 | restore_stack_limit(L); | 432 | restore_stack_limit(L); |
@@ -499,8 +498,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
499 | luaF_close(L, oldtop); /* close possible pending closures */ | 498 | luaF_close(L, oldtop); /* close possible pending closures */ |
500 | luaD_seterrorobj(L, status, oldtop); | 499 | luaD_seterrorobj(L, status, oldtop); |
501 | L->ci = old_ci; | 500 | L->ci = old_ci; |
502 | L->base = L->ci->base; | 501 | L->base = old_ci->base; |
503 | L->savedpc = L->ci->savedpc; | ||
504 | L->allowhook = old_allowhooks; | 502 | L->allowhook = old_allowhooks; |
505 | L->nny = old_nny; | 503 | L->nny = old_nny; |
506 | restore_stack_limit(L); | 504 | restore_stack_limit(L); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 2.51 2009/04/17 14:28:06 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.52 2009/04/17 14:40:13 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -130,7 +130,6 @@ static void preinit_state (lua_State *L, global_State *g) { | |||
130 | L->base_ci.next = L->base_ci.previous = NULL; | 130 | L->base_ci.next = L->base_ci.previous = NULL; |
131 | L->ci = &L->base_ci; | 131 | L->ci = &L->base_ci; |
132 | L->nci = 0; | 132 | L->nci = 0; |
133 | L->savedpc = NULL; | ||
134 | L->errfunc = 0; | 133 | L->errfunc = 0; |
135 | setnilvalue(gt(L)); | 134 | setnilvalue(gt(L)); |
136 | } | 135 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.41 2009/04/08 18:04:33 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.42 2009/04/17 14:28:06 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -81,11 +81,11 @@ typedef struct CallInfo { | |||
81 | StkId func; /* function index in the stack */ | 81 | StkId func; /* function index in the stack */ |
82 | StkId top; /* top for this function */ | 82 | StkId top; /* top for this function */ |
83 | struct CallInfo *previous, *next; /* dynamic call link */ | 83 | struct CallInfo *previous, *next; /* dynamic call link */ |
84 | const Instruction *savedpc; | ||
85 | short nresults; /* expected number of results from a call */ | 84 | short nresults; /* expected number of results from a call */ |
86 | lu_byte callstatus; | 85 | lu_byte callstatus; |
87 | union { | 86 | union { |
88 | struct { /* only for Lua functions */ | 87 | struct { /* only for Lua functions */ |
88 | const Instruction *savedpc; | ||
89 | int tailcalls; /* number of tail calls lost under this entry */ | 89 | int tailcalls; /* number of tail calls lost under this entry */ |
90 | } l; | 90 | } l; |
91 | struct { /* only for C functions */ | 91 | struct { /* only for C functions */ |
@@ -165,7 +165,6 @@ struct lua_State { | |||
165 | global_State *l_G; | 165 | global_State *l_G; |
166 | CallInfo *ci; /* call info for current function */ | 166 | CallInfo *ci; /* call info for current function */ |
167 | int nci; /* number of total CallInfo structures linked */ | 167 | int nci; /* number of total CallInfo structures linked */ |
168 | const Instruction *savedpc; /* `savedpc' of current function */ | ||
169 | const Instruction *oldpc; /* last pc traced */ | 168 | const Instruction *oldpc; /* last pc traced */ |
170 | StkId stack_last; /* last free slot in the stack */ | 169 | StkId stack_last; /* last free slot in the stack */ |
171 | StkId stack; /* stack base */ | 170 | StkId stack; /* stack base */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 2.60 2009/04/14 19:10:17 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.61 2009/04/17 14:28:06 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -285,6 +285,16 @@ static void checkclosure (global_State *g, Closure *cl) { | |||
285 | } | 285 | } |
286 | 286 | ||
287 | 287 | ||
288 | static int lua_checkpc (pCallInfo ci) { | ||
289 | if (!isLua(ci)) return 1; | ||
290 | else { | ||
291 | Proto *p = ci_func(ci)->l.p; | ||
292 | return p->code <= ci->u.l.savedpc && | ||
293 | ci->u.l.savedpc <= p->code + p->sizecode; | ||
294 | } | ||
295 | } | ||
296 | |||
297 | |||
288 | static void checkstack (global_State *g, lua_State *L1) { | 298 | static void checkstack (global_State *g, lua_State *L1) { |
289 | StkId o; | 299 | StkId o; |
290 | CallInfo *ci; | 300 | CallInfo *ci; |
@@ -298,7 +308,7 @@ static void checkstack (global_State *g, lua_State *L1) { | |||
298 | checkliveness(g, gt(L1)); | 308 | checkliveness(g, gt(L1)); |
299 | for (ci = L1->ci; ci != NULL; ci = ci->previous) { | 309 | for (ci = L1->ci; ci != NULL; ci = ci->previous) { |
300 | lua_assert(ci->top <= L1->stack_last); | 310 | lua_assert(ci->top <= L1->stack_last); |
301 | lua_assert(lua_checkpc(L1, ci)); | 311 | lua_assert(lua_checkpc(ci)); |
302 | } | 312 | } |
303 | if (L1->stack) { | 313 | if (L1->stack) { |
304 | for (o = L1->stack; o < L1->top; o++) | 314 | for (o = L1->stack; o < L1->top; o++) |
@@ -352,18 +362,6 @@ printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[gch(o)->tt], gch(o)->mar | |||
352 | } | 362 | } |
353 | 363 | ||
354 | 364 | ||
355 | int lua_checkpc (lua_State *L, pCallInfo ci) { | ||
356 | if (!isLua(ci)) return 1; | ||
357 | else { | ||
358 | Proto *p = ci_func(ci)->l.p; | ||
359 | if (ci != L->ci) | ||
360 | return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode; | ||
361 | else | ||
362 | return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | |||
367 | int lua_checkmemory (lua_State *L) { | 365 | int lua_checkmemory (lua_State *L) { |
368 | global_State *g = G(L); | 366 | global_State *g = G(L); |
369 | GCObject *o; | 367 | GCObject *o; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.h,v 2.23 2008/07/18 19:58:10 roberto Exp roberto $ | 2 | ** $Id: ltests.h,v 2.24 2008/08/05 19:24:46 roberto Exp roberto $ |
3 | ** Internal Header for Debugging of the Lua Implementation | 3 | ** Internal Header for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -51,7 +51,6 @@ void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize); | |||
51 | typedef struct CallInfo *pCallInfo; | 51 | typedef struct CallInfo *pCallInfo; |
52 | 52 | ||
53 | int lua_checkmemory (lua_State *L); | 53 | int lua_checkmemory (lua_State *L); |
54 | int lua_checkpc (lua_State *L, pCallInfo ci); | ||
55 | 54 | ||
56 | 55 | ||
57 | /* test for lock/unlock */ | 56 | /* test for lock/unlock */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.84 2009/03/10 17:14:37 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.85 2009/04/17 14:28:06 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -58,21 +58,22 @@ int luaV_tostring (lua_State *L, StkId obj) { | |||
58 | 58 | ||
59 | 59 | ||
60 | static void traceexec (lua_State *L) { | 60 | static void traceexec (lua_State *L) { |
61 | CallInfo *ci = L->ci; | ||
61 | lu_byte mask = L->hookmask; | 62 | lu_byte mask = L->hookmask; |
62 | if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { | 63 | if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { |
63 | resethookcount(L); | 64 | resethookcount(L); |
64 | luaD_callhook(L, LUA_HOOKCOUNT, -1); | 65 | luaD_callhook(L, LUA_HOOKCOUNT, -1); |
65 | } | 66 | } |
66 | if (mask & LUA_MASKLINE) { | 67 | if (mask & LUA_MASKLINE) { |
67 | Proto *p = ci_func(L->ci)->l.p; | 68 | Proto *p = ci_func(ci)->l.p; |
68 | int npc = pcRel(L->savedpc, p); | 69 | int npc = pcRel(ci->u.l.savedpc, p); |
69 | int newline = getline(p, npc); | 70 | int newline = getline(p, npc); |
70 | if (npc == 0 || /* call linehook when enter a new function, */ | 71 | if (npc == 0 || /* call linehook when enter a new function, */ |
71 | L->savedpc <= L->oldpc || /* when jump back (loop), or when */ | 72 | ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ |
72 | newline != getline(p, pcRel(L->oldpc, p))) /* enter a new line */ | 73 | newline != getline(p, pcRel(L->oldpc, p))) /* enter a new line */ |
73 | luaD_callhook(L, LUA_HOOKLINE, newline); | 74 | luaD_callhook(L, LUA_HOOKLINE, newline); |
74 | } | 75 | } |
75 | L->oldpc = L->savedpc; | 76 | L->oldpc = ci->u.l.savedpc; |
76 | } | 77 | } |
77 | 78 | ||
78 | 79 | ||
@@ -357,7 +358,8 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, | |||
357 | ** finish execution of an opcode interrupted by an yield | 358 | ** finish execution of an opcode interrupted by an yield |
358 | */ | 359 | */ |
359 | void luaV_finishOp (lua_State *L) { | 360 | void luaV_finishOp (lua_State *L) { |
360 | Instruction inst = *(L->savedpc - 1); /* interrupted instruction */ | 361 | CallInfo *ci = L->ci; |
362 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | ||
361 | switch (GET_OPCODE(inst)) { /* finish its execution */ | 363 | switch (GET_OPCODE(inst)) { /* finish its execution */ |
362 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: | 364 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: |
363 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | 365 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: |
@@ -373,9 +375,9 @@ void luaV_finishOp (lua_State *L) { | |||
373 | if (GET_OPCODE(inst) == OP_LE && /* "<=" using "<" instead? */ | 375 | if (GET_OPCODE(inst) == OP_LE && /* "<=" using "<" instead? */ |
374 | ttisnil(luaT_gettmbyobj(L, L->base + GETARG_B(inst), TM_LE))) | 376 | ttisnil(luaT_gettmbyobj(L, L->base + GETARG_B(inst), TM_LE))) |
375 | res = !res; /* invert result */ | 377 | res = !res; /* invert result */ |
376 | lua_assert(GET_OPCODE(*L->savedpc) == OP_JMP); | 378 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); |
377 | if (res != GETARG_A(inst)) /* condition failed? */ | 379 | if (res != GETARG_A(inst)) /* condition failed? */ |
378 | L->savedpc++; /* skip jump instruction */ | 380 | ci->u.l.savedpc++; /* skip jump instruction */ |
379 | break; | 381 | break; |
380 | } | 382 | } |
381 | case OP_CONCAT: { | 383 | case OP_CONCAT: { |
@@ -384,7 +386,7 @@ void luaV_finishOp (lua_State *L) { | |||
384 | int b = GETARG_B(inst); /* ... first element to concatenate */ | 386 | int b = GETARG_B(inst); /* ... first element to concatenate */ |
385 | int total = last - b + 1; /* number of elements to concatenate */ | 387 | int total = last - b + 1; /* number of elements to concatenate */ |
386 | setobj2s(L, top - 2, top); /* put TM result in proper position */ | 388 | setobj2s(L, top - 2, top); /* put TM result in proper position */ |
387 | L->top = L->ci->top; /* correct top */ | 389 | L->top = ci->top; /* correct top */ |
388 | if (total > 1) /* are there elements to concat? */ | 390 | if (total > 1) /* are there elements to concat? */ |
389 | luaV_concat(L, total, last); /* concat them (may yield again) */ | 391 | luaV_concat(L, total, last); /* concat them (may yield again) */ |
390 | /* move final result to final position */ | 392 | /* move final result to final position */ |
@@ -392,13 +394,13 @@ void luaV_finishOp (lua_State *L) { | |||
392 | break; | 394 | break; |
393 | } | 395 | } |
394 | case OP_TFORCALL: { | 396 | case OP_TFORCALL: { |
395 | lua_assert(GET_OPCODE(*L->savedpc) == OP_TFORLOOP); | 397 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); |
396 | L->top = L->ci->top; /* correct top */ | 398 | L->top = ci->top; /* correct top */ |
397 | break; | 399 | break; |
398 | } | 400 | } |
399 | case OP_CALL: { | 401 | case OP_CALL: { |
400 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ | 402 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ |
401 | L->top = L->ci->top; /* adjust results */ | 403 | L->top = ci->top; /* adjust results */ |
402 | break; | 404 | break; |
403 | } | 405 | } |
404 | case OP_TAILCALL: case OP_SETGLOBAL: case OP_SETTABLE: | 406 | case OP_TAILCALL: case OP_SETGLOBAL: case OP_SETTABLE: |
@@ -413,8 +415,6 @@ void luaV_finishOp (lua_State *L) { | |||
413 | ** some macros for common tasks in `luaV_execute' | 415 | ** some macros for common tasks in `luaV_execute' |
414 | */ | 416 | */ |
415 | 417 | ||
416 | #define runtime_check(L, c) { if (!(c)) break; } | ||
417 | |||
418 | #define RA(i) (base+GETARG_A(i)) | 418 | #define RA(i) (base+GETARG_A(i)) |
419 | /* to be used after possible stack reallocation */ | 419 | /* to be used after possible stack reallocation */ |
420 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) | 420 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) |
@@ -426,10 +426,10 @@ void luaV_finishOp (lua_State *L) { | |||
426 | #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) | 426 | #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) |
427 | 427 | ||
428 | 428 | ||
429 | #define dojump(L,i) { L->savedpc += (i); luai_threadyield(L);} | 429 | #define dojump(i) { ci->u.l.savedpc += (i); luai_threadyield(L);} |
430 | 430 | ||
431 | 431 | ||
432 | #define Protect(x) { {x;}; base = L->base; } | 432 | #define Protect(x) { {x;}; base = ci->base; } |
433 | 433 | ||
434 | 434 | ||
435 | #define arith_op(op,tm) { \ | 435 | #define arith_op(op,tm) { \ |
@@ -446,32 +446,29 @@ void luaV_finishOp (lua_State *L) { | |||
446 | 446 | ||
447 | 447 | ||
448 | void luaV_execute (lua_State *L) { | 448 | void luaV_execute (lua_State *L) { |
449 | LClosure *cl; | 449 | CallInfo *ci = L->ci; |
450 | StkId base; | 450 | LClosure *cl = &clvalue(ci->func)->l; |
451 | TValue *k; | 451 | TValue *k = cl->p->k; |
452 | reentry: /* entry point */ | 452 | StkId base = ci->base; |
453 | lua_assert(isLua(L->ci)); | 453 | lua_assert(isLua(ci)); |
454 | cl = &curr_func(L)->l; | ||
455 | base = L->base; | ||
456 | k = cl->p->k; | ||
457 | /* main loop of interpreter */ | 454 | /* main loop of interpreter */ |
458 | for (;;) { | 455 | for (;;) { |
459 | Instruction i = *(L->savedpc++); | 456 | Instruction i = *(ci->u.l.savedpc++); |
460 | StkId ra; | 457 | StkId ra; |
461 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && | 458 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && |
462 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { | 459 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { |
463 | traceexec(L); | 460 | traceexec(L); |
464 | if (L->status == LUA_YIELD) { /* did hook yield? */ | 461 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
465 | L->savedpc--; /* undo increment */ | 462 | ci->u.l.savedpc--; /* undo increment */ |
466 | luaD_throw(L, LUA_YIELD); | 463 | luaD_throw(L, LUA_YIELD); |
467 | } | 464 | } |
468 | base = L->base; | 465 | base = ci->base; |
469 | } | 466 | } |
470 | /* warning!! several calls may realloc the stack and invalidate `ra' */ | 467 | /* warning!! several calls may realloc the stack and invalidate `ra' */ |
471 | ra = RA(i); | 468 | ra = RA(i); |
472 | lua_assert(base == L->base && L->base == L->ci->base); | 469 | lua_assert(base == ci->base && base == L->base); |
473 | lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); | 470 | lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); |
474 | lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); | 471 | lua_assert(L->top == ci->top || luaG_checkopenop(i)); |
475 | switch (GET_OPCODE(i)) { | 472 | switch (GET_OPCODE(i)) { |
476 | case OP_MOVE: { | 473 | case OP_MOVE: { |
477 | setobjs2s(L, ra, RB(i)); | 474 | setobjs2s(L, ra, RB(i)); |
@@ -483,7 +480,7 @@ void luaV_execute (lua_State *L) { | |||
483 | } | 480 | } |
484 | case OP_LOADBOOL: { | 481 | case OP_LOADBOOL: { |
485 | setbvalue(ra, GETARG_B(i)); | 482 | setbvalue(ra, GETARG_B(i)); |
486 | if (GETARG_C(i)) L->savedpc++; /* skip next instruction (if C) */ | 483 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ |
487 | continue; | 484 | continue; |
488 | } | 485 | } |
489 | case OP_LOADNIL: { | 486 | case OP_LOADNIL: { |
@@ -595,7 +592,7 @@ void luaV_execute (lua_State *L) { | |||
595 | continue; | 592 | continue; |
596 | } | 593 | } |
597 | case OP_JMP: { | 594 | case OP_JMP: { |
598 | dojump(L, GETARG_sBx(i)); | 595 | dojump(GETARG_sBx(i)); |
599 | continue; | 596 | continue; |
600 | } | 597 | } |
601 | case OP_EQ: { | 598 | case OP_EQ: { |
@@ -603,40 +600,40 @@ void luaV_execute (lua_State *L) { | |||
603 | TValue *rc = RKC(i); | 600 | TValue *rc = RKC(i); |
604 | Protect( | 601 | Protect( |
605 | if (equalobj(L, rb, rc) == GETARG_A(i)) | 602 | if (equalobj(L, rb, rc) == GETARG_A(i)) |
606 | dojump(L, GETARG_sBx(*L->savedpc)); | 603 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
607 | ) | 604 | ) |
608 | L->savedpc++; | 605 | ci->u.l.savedpc++; |
609 | continue; | 606 | continue; |
610 | } | 607 | } |
611 | case OP_LT: { | 608 | case OP_LT: { |
612 | Protect( | 609 | Protect( |
613 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) | 610 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) |
614 | dojump(L, GETARG_sBx(*L->savedpc)); | 611 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
615 | ) | 612 | ) |
616 | L->savedpc++; | 613 | ci->u.l.savedpc++; |
617 | continue; | 614 | continue; |
618 | } | 615 | } |
619 | case OP_LE: { | 616 | case OP_LE: { |
620 | Protect( | 617 | Protect( |
621 | if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) | 618 | if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) |
622 | dojump(L, GETARG_sBx(*L->savedpc)); | 619 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
623 | ) | 620 | ) |
624 | L->savedpc++; | 621 | ci->u.l.savedpc++; |
625 | continue; | 622 | continue; |
626 | } | 623 | } |
627 | case OP_TEST: { | 624 | case OP_TEST: { |
628 | if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) | 625 | if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) |
629 | dojump(L, GETARG_sBx(*L->savedpc)); | 626 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
630 | L->savedpc++; | 627 | ci->u.l.savedpc++; |
631 | continue; | 628 | continue; |
632 | } | 629 | } |
633 | case OP_TESTSET: { | 630 | case OP_TESTSET: { |
634 | TValue *rb = RB(i); | 631 | TValue *rb = RB(i); |
635 | if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) { | 632 | if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) { |
636 | setobjs2s(L, ra, rb); | 633 | setobjs2s(L, ra, rb); |
637 | dojump(L, GETARG_sBx(*L->savedpc)); | 634 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
638 | } | 635 | } |
639 | L->savedpc++; | 636 | ci->u.l.savedpc++; |
640 | continue; | 637 | continue; |
641 | } | 638 | } |
642 | case OP_CALL: { | 639 | case OP_CALL: { |
@@ -644,13 +641,14 @@ void luaV_execute (lua_State *L) { | |||
644 | int nresults = GETARG_C(i) - 1; | 641 | int nresults = GETARG_C(i) - 1; |
645 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 642 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
646 | if (luaD_precall(L, ra, nresults)) { /* C function? */ | 643 | if (luaD_precall(L, ra, nresults)) { /* C function? */ |
647 | if (nresults >= 0) L->top = L->ci->top; /* adjust results */ | 644 | if (nresults >= 0) L->top = ci->top; /* adjust results */ |
648 | base = L->base; | 645 | base = ci->base; |
649 | continue; | 646 | continue; |
650 | } | 647 | } |
651 | else { /* Lua function */ | 648 | else { /* Lua function */ |
652 | L->ci->callstatus |= CIST_REENTRY; | 649 | ci = L->ci; |
653 | goto reentry; /* restart luaV_execute over new Lua function */ | 650 | ci->callstatus |= CIST_REENTRY; |
651 | break; /* restart luaV_execute over new Lua function */ | ||
654 | } | 652 | } |
655 | } | 653 | } |
656 | case OP_TAILCALL: { | 654 | case OP_TAILCALL: { |
@@ -658,25 +656,26 @@ void luaV_execute (lua_State *L) { | |||
658 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 656 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
659 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | 657 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); |
660 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ | 658 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ |
661 | base = L->base; | 659 | base = ci->base; |
662 | continue; | 660 | continue; |
663 | } | 661 | } |
664 | else { | 662 | else { |
665 | /* tail call: put new frame in place of previous one */ | 663 | /* tail call: put called frame (n) in place of caller one (o) */ |
666 | StkId pfunc = L->ci->func; /* called function index */ | 664 | CallInfo *nci = L->ci; /* called frame */ |
667 | CallInfo *ci = L->ci->previous; /* caller frame */ | 665 | CallInfo *oci = nci->previous; /* caller frame */ |
668 | StkId func = ci->func; | 666 | StkId nfunc = nci->func; /* called function index */ |
667 | StkId ofunc = oci->func; | ||
669 | int aux; | 668 | int aux; |
670 | if (cl->p->sizep > 0) luaF_close(L, ci->base); | 669 | if (cl->p->sizep > 0) luaF_close(L, oci->base); |
671 | L->base = ci->base = ci->func + (L->ci->base - pfunc); | 670 | L->base = oci->base = ofunc + (nci->base - nfunc); |
672 | for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ | 671 | for (aux = 0; nfunc+aux < L->top; aux++) /* move frame down */ |
673 | setobjs2s(L, func+aux, pfunc+aux); | 672 | setobjs2s(L, ofunc + aux, nfunc + aux); |
674 | ci->top = L->top = func+aux; /* correct top */ | 673 | oci->top = L->top = ofunc + aux; /* correct top */ |
675 | lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); | 674 | lua_assert(L->top == L->base + clvalue(ofunc)->l.p->maxstacksize); |
676 | ci->savedpc = L->savedpc; | 675 | oci->u.l.savedpc = nci->u.l.savedpc; |
677 | ci->u.l.tailcalls++; /* one more call lost */ | 676 | oci->u.l.tailcalls++; /* one more call lost */ |
678 | L->ci = ci; /* remove new frame */ | 677 | ci = L->ci = oci; /* remove new frame */ |
679 | goto reentry; | 678 | break; /* restart luaV_execute over new Lua function */ |
680 | } | 679 | } |
681 | } | 680 | } |
682 | case OP_RETURN: { | 681 | case OP_RETURN: { |
@@ -684,13 +683,14 @@ void luaV_execute (lua_State *L) { | |||
684 | if (b != 0) L->top = ra+b-1; | 683 | if (b != 0) L->top = ra+b-1; |
685 | if (cl->p->sizep > 0) luaF_close(L, base); | 684 | if (cl->p->sizep > 0) luaF_close(L, base); |
686 | b = luaD_poscall(L, ra); | 685 | b = luaD_poscall(L, ra); |
687 | if (!(L->ci->next->callstatus & CIST_REENTRY)) | 686 | if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ |
688 | return; /* external invocation: return */ | 687 | return; /* external invocation: return */ |
689 | else { /* invocation via reentry: continue execution */ | 688 | else { /* invocation via reentry: continue execution */ |
690 | if (b) L->top = L->ci->top; | 689 | ci = L->ci; |
691 | lua_assert(isLua(L->ci)); | 690 | if (b) L->top = ci->top; |
692 | lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); | 691 | lua_assert(isLua(ci)); |
693 | goto reentry; | 692 | lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); |
693 | break; /* restart luaV_execute over new Lua function */ | ||
694 | } | 694 | } |
695 | } | 695 | } |
696 | case OP_FORLOOP: { | 696 | case OP_FORLOOP: { |
@@ -699,7 +699,7 @@ void luaV_execute (lua_State *L) { | |||
699 | lua_Number limit = nvalue(ra+1); | 699 | lua_Number limit = nvalue(ra+1); |
700 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) | 700 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) |
701 | : luai_numle(L, limit, idx)) { | 701 | : luai_numle(L, limit, idx)) { |
702 | dojump(L, GETARG_sBx(i)); /* jump back */ | 702 | dojump(GETARG_sBx(i)); /* jump back */ |
703 | setnvalue(ra, idx); /* update internal index... */ | 703 | setnvalue(ra, idx); /* update internal index... */ |
704 | setnvalue(ra+3, idx); /* ...and external index */ | 704 | setnvalue(ra+3, idx); /* ...and external index */ |
705 | } | 705 | } |
@@ -716,7 +716,7 @@ void luaV_execute (lua_State *L) { | |||
716 | else if (!tonumber(pstep, ra+2)) | 716 | else if (!tonumber(pstep, ra+2)) |
717 | luaG_runerror(L, LUA_QL("for") " step must be a number"); | 717 | luaG_runerror(L, LUA_QL("for") " step must be a number"); |
718 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); | 718 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); |
719 | dojump(L, GETARG_sBx(i)); | 719 | dojump(GETARG_sBx(i)); |
720 | continue; | 720 | continue; |
721 | } | 721 | } |
722 | case OP_TFORCALL: { | 722 | case OP_TFORCALL: { |
@@ -726,8 +726,8 @@ void luaV_execute (lua_State *L) { | |||
726 | setobjs2s(L, cb, ra); | 726 | setobjs2s(L, cb, ra); |
727 | L->top = cb + 3; /* func. + 2 args (state and index) */ | 727 | L->top = cb + 3; /* func. + 2 args (state and index) */ |
728 | Protect(luaD_call(L, cb, GETARG_C(i), 1)); | 728 | Protect(luaD_call(L, cb, GETARG_C(i), 1)); |
729 | L->top = L->ci->top; | 729 | L->top = ci->top; |
730 | i = *(L->savedpc++); /* go to next instruction */ | 730 | i = *(ci->u.l.savedpc++); /* go to next instruction */ |
731 | ra = RA(i); | 731 | ra = RA(i); |
732 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); | 732 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); |
733 | /* go through */ | 733 | /* go through */ |
@@ -735,7 +735,7 @@ void luaV_execute (lua_State *L) { | |||
735 | case OP_TFORLOOP: { | 735 | case OP_TFORLOOP: { |
736 | if (!ttisnil(ra + 1)) { /* continue loop? */ | 736 | if (!ttisnil(ra + 1)) { /* continue loop? */ |
737 | setobjs2s(L, ra, ra + 1); /* save control variable */ | 737 | setobjs2s(L, ra, ra + 1); /* save control variable */ |
738 | dojump(L, GETARG_sBx(i)); /* jump back */ | 738 | dojump(GETARG_sBx(i)); /* jump back */ |
739 | } | 739 | } |
740 | continue; | 740 | continue; |
741 | } | 741 | } |
@@ -746,10 +746,9 @@ void luaV_execute (lua_State *L) { | |||
746 | Table *h; | 746 | Table *h; |
747 | if (n == 0) n = cast_int(L->top - ra) - 1; | 747 | if (n == 0) n = cast_int(L->top - ra) - 1; |
748 | if (c == 0) { | 748 | if (c == 0) { |
749 | lua_assert(GET_OPCODE(*L->savedpc) == OP_EXTRAARG); | 749 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); |
750 | c = GETARG_Ax(*L->savedpc++); | 750 | c = GETARG_Ax(*ci->u.l.savedpc++); |
751 | } | 751 | } |
752 | runtime_check(L, ttistable(ra)); | ||
753 | h = hvalue(ra); | 752 | h = hvalue(ra); |
754 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; | 753 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; |
755 | if (last > h->sizearray) /* needs more space? */ | 754 | if (last > h->sizearray) /* needs more space? */ |
@@ -759,7 +758,7 @@ void luaV_execute (lua_State *L) { | |||
759 | setobj2t(L, luaH_setnum(L, h, last--), val); | 758 | setobj2t(L, luaH_setnum(L, h, last--), val); |
760 | luaC_barriert(L, h, val); | 759 | luaC_barriert(L, h, val); |
761 | } | 760 | } |
762 | L->top = L->ci->top; /* correct top (in case of previous open call) */ | 761 | L->top = ci->top; /* correct top (in case of previous open call) */ |
763 | continue; | 762 | continue; |
764 | } | 763 | } |
765 | case OP_CLOSE: { | 764 | case OP_CLOSE: { |
@@ -776,7 +775,7 @@ void luaV_execute (lua_State *L) { | |||
776 | ncl->l.p = p; | 775 | ncl->l.p = p; |
777 | setclvalue(L, ra, ncl); | 776 | setclvalue(L, ra, ncl); |
778 | for (j=0; j<nup; j++) { | 777 | for (j=0; j<nup; j++) { |
779 | Instruction u = *L->savedpc++; | 778 | Instruction u = *ci->u.l.savedpc++; |
780 | if (GET_OPCODE(u) == OP_GETUPVAL) | 779 | if (GET_OPCODE(u) == OP_GETUPVAL) |
781 | ncl->l.upvals[j] = cl->upvals[GETARG_B(u)]; | 780 | ncl->l.upvals[j] = cl->upvals[GETARG_B(u)]; |
782 | else { | 781 | else { |
@@ -790,7 +789,6 @@ void luaV_execute (lua_State *L) { | |||
790 | case OP_VARARG: { | 789 | case OP_VARARG: { |
791 | int b = GETARG_B(i) - 1; | 790 | int b = GETARG_B(i) - 1; |
792 | int j; | 791 | int j; |
793 | CallInfo *ci = L->ci; | ||
794 | int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; | 792 | int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; |
795 | if (b == LUA_MULTRET) { | 793 | if (b == LUA_MULTRET) { |
796 | Protect(luaD_checkstack(L, n)); | 794 | Protect(luaD_checkstack(L, n)); |
@@ -813,6 +811,11 @@ void luaV_execute (lua_State *L) { | |||
813 | return; | 811 | return; |
814 | } | 812 | } |
815 | } | 813 | } |
814 | /* function changed (call/return): update pointers */ | ||
815 | lua_assert(ci == L->ci); | ||
816 | cl = &clvalue(ci->func)->l; | ||
817 | k = cl->p->k; | ||
818 | base = ci->base; | ||
816 | } | 819 | } |
817 | } | 820 | } |
818 | 821 | ||