aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c19
-rw-r--r--ldebug.c8
-rw-r--r--ldo.c52
-rw-r--r--lstate.c3
-rw-r--r--lstate.h5
-rw-r--r--ltests.c26
-rw-r--r--ltests.h3
-rw-r--r--lvm.c155
8 files changed, 133 insertions, 138 deletions
diff --git a/lapi.c b/lapi.c
index 0e3ef071..69307a3c 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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);
diff --git a/ldebug.c b/ldebug.c
index bcb7eaf3..629d040b 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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
36static int currentpc (lua_State *L, CallInfo *ci) { 36static 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);
diff --git a/ldo.c b/ldo.c
index 1a051222..040b8cdb 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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) {
151void luaD_callhook (lua_State *L, int event, int line) { 151void 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
338static void finishCcall (lua_State *L) { 337static 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);
diff --git a/lstate.c b/lstate.c
index e1bbd7bd..7df2ba2b 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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}
diff --git a/lstate.h b/lstate.h
index 0e34a54c..23d1dfb5 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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 */
diff --git a/ltests.c b/ltests.c
index 9a55f6da..5e2b6d75 100644
--- a/ltests.c
+++ b/ltests.c
@@ -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
288static 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
288static void checkstack (global_State *g, lua_State *L1) { 298static 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
355int 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
367int lua_checkmemory (lua_State *L) { 365int lua_checkmemory (lua_State *L) {
368 global_State *g = G(L); 366 global_State *g = G(L);
369 GCObject *o; 367 GCObject *o;
diff --git a/ltests.h b/ltests.h
index 180d067b..4a27d099 100644
--- a/ltests.h
+++ b/ltests.h
@@ -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);
51typedef struct CallInfo *pCallInfo; 51typedef struct CallInfo *pCallInfo;
52 52
53int lua_checkmemory (lua_State *L); 53int lua_checkmemory (lua_State *L);
54int lua_checkpc (lua_State *L, pCallInfo ci);
55 54
56 55
57/* test for lock/unlock */ 56/* test for lock/unlock */
diff --git a/lvm.c b/lvm.c
index 0c70491d..ad3a26cd 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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
60static void traceexec (lua_State *L) { 60static 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*/
359void luaV_finishOp (lua_State *L) { 360void 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
448void luaV_execute (lua_State *L) { 448void 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