diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-04-17 19:00:01 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-04-17 19:00:01 -0300 |
| commit | d3037d97ec192e7719de485f15dacb473bf96528 (patch) | |
| tree | ea9f837cc64d9df82ae4324f2c7ea447b5c4582f | |
| parent | c6b442bd369ce05b3d4bfb95ba64451521aa1b31 (diff) | |
| download | lua-d3037d97ec192e7719de485f15dacb473bf96528.tar.gz lua-d3037d97ec192e7719de485f15dacb473bf96528.tar.bz2 lua-d3037d97ec192e7719de485f15dacb473bf96528.zip | |
several small improvements based on 'ci' being fixed now (including
erasing savedpc from lua_State)
| -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 | ||
