aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c18
-rw-r--r--ldebug.c18
-rw-r--r--ldo.c54
-rw-r--r--lobject.h18
-rw-r--r--lstate.h16
-rw-r--r--ltests.c20
-rw-r--r--lvm.c47
7 files changed, 100 insertions, 91 deletions
diff --git a/lapi.c b/lapi.c
index 6b6bc565..8750cefa 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.273 2017/11/02 11:28:56 roberto Exp roberto $ 2** $Id: lapi.c,v 2.274 2017/11/03 12:12:30 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*/
@@ -948,8 +948,8 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
948 checkresults(L, nargs, nresults); 948 checkresults(L, nargs, nresults);
949 func = L->top - (nargs+1); 949 func = L->top - (nargs+1);
950 if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ 950 if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
951 L->ci->u.c.k = k; /* save continuation */ 951 L->func->stkci.u.c.k = k; /* save continuation */
952 L->ci->u.c.ctx = ctx; /* save context */ 952 L->func->stkci.u.c.ctx = ctx; /* save context */
953 luaD_call(L, func, nresults); /* do the call */ 953 luaD_call(L, func, nresults); /* do the call */
954 } 954 }
955 else /* no continuation or no yieldable */ 955 else /* no continuation or no yieldable */
@@ -999,19 +999,19 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
999 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), efunc); 999 status = luaD_pcall(L, f_call, &c, savestack(L, c.func), efunc);
1000 } 1000 }
1001 else { /* prepare continuation (call is already protected by 'resume') */ 1001 else { /* prepare continuation (call is already protected by 'resume') */
1002 CallInfo *ci = L->ci;
1003 StkId func = L->func; 1002 StkId func = L->func;
1004 ci->u.c.k = k; /* save continuation */ 1003 func->stkci.u.c.k = k; /* save continuation */
1005 ci->u.c.ctx = ctx; /* save context */ 1004 func->stkci.u.c.ctx = ctx; /* save context */
1006 /* save information for error recovery */ 1005 /* save information for error recovery */
1007 ci->u2.funcidx = savestack(L, c.func); 1006 func->stkci.u2.funcidx = c.func - func;
1008 ci->u.c.old_errfunc = L->errfunc; 1007 func->stkci.u.c.old_errfunc = L->errfunc;
1009 L->errfunc = efunc; 1008 L->errfunc = efunc;
1010 setoah(callstatus(func), L->allowhook); /* save value of 'allowhook' */ 1009 setoah(callstatus(func), L->allowhook); /* save value of 'allowhook' */
1011 callstatus(func) |= CIST_YPCALL; /* function can do error recovery */ 1010 callstatus(func) |= CIST_YPCALL; /* function can do error recovery */
1012 luaD_call(L, c.func, nresults); /* do the call */ 1011 luaD_call(L, c.func, nresults); /* do the call */
1012 func = L->func; /* previous call can reallocate stack */
1013 callstatus(func) &= ~CIST_YPCALL; 1013 callstatus(func) &= ~CIST_YPCALL;
1014 L->errfunc = ci->u.c.old_errfunc; 1014 L->errfunc = func->stkci.u.c.old_errfunc;
1015 status = LUA_OK; /* if it is here, there were no errors */ 1015 status = LUA_OK; /* if it is here, there were no errors */
1016 } 1016 }
1017 adjustresults(L, nresults); 1017 adjustresults(L, nresults);
diff --git a/ldebug.c b/ldebug.c
index 2db0910c..b212d875 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.135 2017/11/02 11:28:56 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.136 2017/11/03 12:12:30 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*/
@@ -44,7 +44,7 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
44 44
45static int currentpc (CallInfo *ci) { 45static int currentpc (CallInfo *ci) {
46 lua_assert(isLua(ci->func)); 46 lua_assert(isLua(ci->func));
47 return pcRel(ci->u.l.savedpc, ci_func(ci)->p); 47 return pcRel(ci->func->stkci.u.l.savedpc, ci_func(ci)->p);
48} 48}
49 49
50 50
@@ -121,7 +121,7 @@ LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
121 func = NULL; 121 func = NULL;
122 } 122 }
123 if (isLua(L->func)) 123 if (isLua(L->func))
124 L->oldpc = L->ci->u.l.savedpc; 124 L->oldpc = L->func->stkci.u.l.savedpc;
125 L->hook = func; 125 L->hook = func;
126 L->basehookcount = count; 126 L->basehookcount = count;
127 resethookcount(L); 127 resethookcount(L);
@@ -755,19 +755,21 @@ void luaG_traceexec (lua_State *L) {
755 luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ 755 luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
756 if (mask & LUA_MASKLINE) { 756 if (mask & LUA_MASKLINE) {
757 Proto *p = ci_func(ci)->p; 757 Proto *p = ci_func(ci)->p;
758 int npc = pcRel(ci->u.l.savedpc, p); 758 int npc = pcRel(func->stkci.u.l.savedpc, p);
759 if (npc == 0 || /* call linehook when enter a new function, */ 759 if (npc == 0 || /* call linehook when enter a new function, */
760 ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ 760 func->stkci.u.l.savedpc <= L->oldpc || /* when jump back (loop), */
761 changedline(p, pcRel(L->oldpc, p), npc)) { /* enter new line */ 761 changedline(p, pcRel(L->oldpc, p), npc)) { /* when enter new line */
762 int newline = luaG_getfuncline(p, npc); /* new line */ 762 int newline = luaG_getfuncline(p, npc); /* new line */
763 luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ 763 luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
764 } 764 }
765 } 765 }
766 L->oldpc = ci->u.l.savedpc; 766 func = L->func; /* previous calls can reallocate stack */
767 L->oldpc = func->stkci.u.l.savedpc;
767 if (L->status == LUA_YIELD) { /* did hook yield? */ 768 if (L->status == LUA_YIELD) { /* did hook yield? */
768 if (counthook) 769 if (counthook)
769 L->hookcount = 1; /* undo decrement to zero */ 770 L->hookcount = 1; /* undo decrement to zero */
770 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ 771 /* undo increment (resume will increment it again) */
772 func->stkci.u.l.savedpc--;
771 callstatus(func) |= CIST_HOOKYIELD; /* mark that it yielded */ 773 callstatus(func) |= CIST_HOOKYIELD; /* mark that it yielded */
772 luaD_throw(L, LUA_YIELD); 774 luaD_throw(L, LUA_YIELD);
773 } 775 }
diff --git a/ldo.c b/ldo.c
index cbb1e0f3..3b01c8fb 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.165 2017/11/02 11:28:56 roberto Exp roberto $ 2** $Id: ldo.c,v 2.166 2017/11/03 12:12:30 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*/
@@ -280,17 +280,19 @@ void luaD_hook (lua_State *L, int event, int line) {
280} 280}
281 281
282 282
283static void callhook (lua_State *L, CallInfo *ci) { 283static void callhook (lua_State *L) {
284 int hook = LUA_HOOKCALL; 284 int hook = LUA_HOOKCALL;
285 StkId previous = L->func - L->func->stkci.previous; 285 StkId func = L->func;
286 ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ 286 StkId previous = func - L->func->stkci.previous;
287 func->stkci.u.l.savedpc++; /* hooks assume 'pc' is already incremented */
287 if (isLua(previous) && 288 if (isLua(previous) &&
288 GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { 289 GET_OPCODE(*(previous->stkci.u.l.savedpc - 1)) == OP_TAILCALL) {
289 callstatus(L->func) |= CIST_TAIL; 290 callstatus(L->func) |= CIST_TAIL;
290 hook = LUA_HOOKTAILCALL; 291 hook = LUA_HOOKTAILCALL;
291 } 292 }
292 luaD_hook(L, hook, -1); 293 luaD_hook(L, hook, -1);
293 ci->u.l.savedpc--; /* correct 'pc' */ 294 func = L->func; /* previous call can change stack */
295 func->stkci.u.l.savedpc--; /* correct 'pc' */
294} 296}
295 297
296 298
@@ -369,11 +371,13 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
369 ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ 371 ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
370 luaD_hook(L, LUA_HOOKRET, -1); 372 luaD_hook(L, LUA_HOOKRET, -1);
371 firstResult = restorestack(L, fr); 373 firstResult = restorestack(L, fr);
374 res = L->func;
372 } 375 }
373 L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ 376 /* 'oldpc' for caller function */
377 L->oldpc = (res - res->stkci.previous)->stkci.u.l.savedpc;
374 } 378 }
375 L->ci = ci->previous; /* back to caller */ 379 L->ci = ci->previous; /* back to caller */
376 L->func -= L->func->stkci.previous; 380 L->func = res - res->stkci.previous;
377 lua_assert(L->func == L->ci->func); 381 lua_assert(L->func == L->ci->func);
378 /* move results to proper place */ 382 /* move results to proper place */
379 return moveresults(L, firstResult, res, nres, wanted); 383 return moveresults(L, firstResult, res, nres, wanted);
@@ -436,10 +440,10 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
436 L->func = ci->func = func; 440 L->func = ci->func = func;
437 L->top = func + 1 + fsize; 441 L->top = func + 1 + fsize;
438 lua_assert(functop(func) <= L->stack_last); 442 lua_assert(functop(func) <= L->stack_last);
439 ci->u.l.savedpc = p->code; /* starting point */ 443 func->stkci.u.l.savedpc = p->code; /* starting point */
440 callstatus(func) = 0; 444 callstatus(func) = 0;
441 if (L->hookmask & LUA_MASKCALL) 445 if (L->hookmask & LUA_MASKCALL)
442 callhook(L, ci); 446 callhook(L);
443 return 0; 447 return 0;
444 } 448 }
445 default: { /* not a function */ 449 default: { /* not a function */
@@ -500,18 +504,19 @@ static void finishCcall (lua_State *L, int status) {
500 StkId func = L->func; 504 StkId func = L->func;
501 int n; 505 int n;
502 /* must have a continuation and must be able to call it */ 506 /* must have a continuation and must be able to call it */
503 lua_assert(ci->u.c.k != NULL && L->nny == 0); 507 lua_assert(func->stkci.u.c.k != NULL && L->nny == 0);
504 /* error status can only happen in a protected call */ 508 /* error status can only happen in a protected call */
505 lua_assert((callstatus(func) & CIST_YPCALL) || status == LUA_YIELD); 509 lua_assert((callstatus(func) & CIST_YPCALL) || status == LUA_YIELD);
506 if (callstatus(func) & CIST_YPCALL) { /* was inside a pcall? */ 510 if (callstatus(func) & CIST_YPCALL) { /* was inside a pcall? */
507 callstatus(func) &= ~CIST_YPCALL; /* continuation is also inside it */ 511 callstatus(func) &= ~CIST_YPCALL; /* continuation is also inside it */
508 L->errfunc = ci->u.c.old_errfunc; /* with the same error function */ 512 L->errfunc = func->stkci.u.c.old_errfunc; /* with same error function */
509 } 513 }
510 /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already 514 /* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
511 handled */ 515 handled */
512 adjustresults(L, func->stkci.nresults); 516 adjustresults(L, func->stkci.nresults);
513 lua_unlock(L); 517 lua_unlock(L);
514 n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */ 518 /* call continuation function */
519 n = (*func->stkci.u.c.k)(L, status, func->stkci.u.c.ctx);
515 lua_lock(L); 520 lua_lock(L);
516 api_checknelems(L, n); 521 api_checknelems(L, n);
517 luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */ 522 luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */
@@ -564,7 +569,7 @@ static int recover (lua_State *L, int status) {
564 CallInfo *ci = findpcall(L); 569 CallInfo *ci = findpcall(L);
565 if (ci == NULL) return 0; /* no recovery point */ 570 if (ci == NULL) return 0; /* no recovery point */
566 /* "finish" luaD_pcall */ 571 /* "finish" luaD_pcall */
567 oldtop = restorestack(L, ci->u2.funcidx); 572 oldtop = ci->func + ci->func->stkci.u2.funcidx;
568 luaF_close(L, oldtop); 573 luaF_close(L, oldtop);
569 seterrorobj(L, status, oldtop); 574 seterrorobj(L, status, oldtop);
570 L->ci = ci; 575 L->ci = ci;
@@ -572,7 +577,7 @@ static int recover (lua_State *L, int status) {
572 L->allowhook = getoah(callstatus(L->func)); /* restore original 'allowhook' */ 577 L->allowhook = getoah(callstatus(L->func)); /* restore original 'allowhook' */
573 L->nny = 0; /* should be zero to be yieldable */ 578 L->nny = 0; /* should be zero to be yieldable */
574 luaD_shrinkstack(L); 579 luaD_shrinkstack(L);
575 L->errfunc = ci->u.c.old_errfunc; 580 L->errfunc = ci->func->stkci.u.c.old_errfunc;
576 return 1; /* continue running the coroutine */ 581 return 1; /* continue running the coroutine */
577} 582}
578 583
@@ -602,6 +607,7 @@ static void resume (lua_State *L, void *ud) {
602 int n = *(cast(int*, ud)); /* number of arguments */ 607 int n = *(cast(int*, ud)); /* number of arguments */
603 StkId firstArg = L->top - n; /* first argument */ 608 StkId firstArg = L->top - n; /* first argument */
604 CallInfo *ci = L->ci; 609 CallInfo *ci = L->ci;
610 StkId func = L->func;
605 if (L->status == LUA_OK) { /* starting a coroutine? */ 611 if (L->status == LUA_OK) { /* starting a coroutine? */
606 if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ 612 if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
607 luaV_execute(L); /* call it */ 613 luaV_execute(L); /* call it */
@@ -609,12 +615,13 @@ static void resume (lua_State *L, void *ud) {
609 else { /* resuming from previous yield */ 615 else { /* resuming from previous yield */
610 lua_assert(L->status == LUA_YIELD); 616 lua_assert(L->status == LUA_YIELD);
611 L->status = LUA_OK; /* mark that it is running (again) */ 617 L->status = LUA_OK; /* mark that it is running (again) */
612 if (isLua(L->func)) /* yielded inside a hook? */ 618 if (isLua(func)) /* yielded inside a hook? */
613 luaV_execute(L); /* just continue running Lua code */ 619 luaV_execute(L); /* just continue running Lua code */
614 else { /* 'common' yield */ 620 else { /* 'common' yield */
615 if (ci->u.c.k != NULL) { /* does it have a continuation function? */ 621 if (func->stkci.u.c.k != NULL) { /* does it have a continuation? */
616 lua_unlock(L); 622 lua_unlock(L);
617 n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ 623 /* call continuation */
624 n = (*func->stkci.u.c.k)(L, LUA_YIELD, func->stkci.u.c.ctx);
618 lua_lock(L); 625 lua_lock(L);
619 api_checknelems(L, n); 626 api_checknelems(L, n);
620 firstArg = L->top - n; /* yield results come from continuation */ 627 firstArg = L->top - n; /* yield results come from continuation */
@@ -658,7 +665,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
658 } 665 }
659 else lua_assert(status == L->status); /* normal end or yield */ 666 else lua_assert(status == L->status); /* normal end or yield */
660 } 667 }
661 *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield 668 *nresults = (status == LUA_YIELD) ? L->func->stkci.u2.nyield
662 : L->top - (L->func + 1); 669 : L->top - (L->func + 1);
663 L->nny = oldnny; /* restore 'nny' */ 670 L->nny = oldnny; /* restore 'nny' */
664 L->nCcalls--; 671 L->nCcalls--;
@@ -675,7 +682,6 @@ LUA_API int lua_isyieldable (lua_State *L) {
675 682
676LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, 683LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
677 lua_KFunction k) { 684 lua_KFunction k) {
678 CallInfo *ci = L->ci;
679 StkId func = L->func; 685 StkId func = L->func;
680 luai_userstateyield(L, nresults); 686 luai_userstateyield(L, nresults);
681 lua_lock(L); 687 lua_lock(L);
@@ -689,12 +695,12 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
689 L->status = LUA_YIELD; 695 L->status = LUA_YIELD;
690 if (isLua(func)) { /* inside a hook? */ 696 if (isLua(func)) { /* inside a hook? */
691 api_check(L, k == NULL, "hooks cannot continue after yielding"); 697 api_check(L, k == NULL, "hooks cannot continue after yielding");
692 ci->u2.nyield = 0; /* no results */ 698 func->stkci.u2.nyield = 0; /* no results */
693 } 699 }
694 else { 700 else {
695 if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ 701 if ((func->stkci.u.c.k = k) != NULL) /* is there a continuation? */
696 ci->u.c.ctx = ctx; /* save context */ 702 func->stkci.u.c.ctx = ctx; /* save context */
697 ci->u2.nyield = nresults; /* save number of results */ 703 func->stkci.u2.nyield = nresults; /* save number of results */
698 luaD_throw(L, LUA_YIELD); 704 luaD_throw(L, LUA_YIELD);
699 } 705 }
700 lua_assert(callstatus(func) & CIST_HOOKED); /* must be inside a hook */ 706 lua_assert(callstatus(func) & CIST_HOOKED); /* must be inside a hook */
diff --git a/lobject.h b/lobject.h
index 66c41e6f..925f958c 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.126 2017/10/31 17:54:35 roberto Exp roberto $ 2** $Id: lobject.h,v 2.127 2017/11/03 12:12:30 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -314,9 +314,23 @@ typedef union StackValue {
314 struct { 314 struct {
315 TValuefields; 315 TValuefields;
316 lu_byte callstatus_; 316 lu_byte callstatus_;
317 unsigned short previous; /* difference to previous 'func' */
318 short nresults; /* expected number of results from this function */ 317 short nresults; /* expected number of results from this function */
318 unsigned short previous; /* difference to previous 'func' */
319 unsigned short framesize; /* stack space available for this function */ 319 unsigned short framesize; /* stack space available for this function */
320 union {
321 unsigned short funcidx; /* called-function index */
322 unsigned short nyield; /* number of values yielded */
323 } u2;
324 union {
325 struct { /* only for Lua functions */
326 const Instruction *savedpc;
327 } l;
328 struct { /* only for C functions */
329 lua_KFunction k; /* continuation in case of yields */
330 ptrdiff_t old_errfunc;
331 lua_KContext ctx; /* context info. in case of yields */
332 } c;
333 } u;
320 } stkci; 334 } stkci;
321} StackValue; 335} StackValue;
322 336
diff --git a/lstate.h b/lstate.h
index 3d76e9b9..df1630ea 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.146 2017/11/02 11:28:56 roberto Exp roberto $ 2** $Id: lstate.h,v 2.147 2017/11/03 12:12:30 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*/
@@ -87,20 +87,6 @@ typedef struct stringtable {
87typedef struct CallInfo { 87typedef struct CallInfo {
88 StkId func; /* function index in the stack */ 88 StkId func; /* function index in the stack */
89 struct CallInfo *previous, *next; /* dynamic call link */ 89 struct CallInfo *previous, *next; /* dynamic call link */
90 union {
91 struct { /* only for Lua functions */
92 const Instruction *savedpc;
93 } l;
94 struct { /* only for C functions */
95 lua_KFunction k; /* continuation in case of yields */
96 ptrdiff_t old_errfunc;
97 lua_KContext ctx; /* context info. in case of yields */
98 } c;
99 } u;
100 union {
101 ptrdiff_t funcidx; /* called-function index */
102 int nyield; /* number of values yielded */
103 } u2;
104} CallInfo; 90} CallInfo;
105 91
106 92
diff --git a/ltests.c b/ltests.c
index 71ad09ea..ebf73840 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.227 2017/11/02 11:28:56 roberto Exp roberto $ 2** $Id: ltests.c,v 2.228 2017/11/03 12:12:30 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*/
@@ -309,28 +309,26 @@ static void checkLclosure (global_State *g, LClosure *cl) {
309} 309}
310 310
311 311
312static int lua_checkpc (CallInfo *ci) { 312static int lua_checkpc (StkId func) {
313 if (!isLua(ci->func)) return 1; 313 if (!isLua(func)) return 1;
314 else { 314 else {
315 StkId f = ci->func; 315 Proto *p = clLvalue(s2v(func))->p;
316 Proto *p = clLvalue(s2v(f))->p; 316 return p->code <= func->stkci.u.l.savedpc &&
317 return p->code <= ci->u.l.savedpc && 317 func->stkci.u.l.savedpc <= p->code + p->sizecode;
318 ci->u.l.savedpc <= p->code + p->sizecode;
319 } 318 }
320} 319}
321 320
322 321
323static void checkstack (global_State *g, lua_State *L1) { 322static void checkstack (global_State *g, lua_State *L1) {
324 StkId o; 323 StkId o;
325 CallInfo *ci;
326 UpVal *uv; 324 UpVal *uv;
327 lua_assert(!isdead(g, L1)); 325 lua_assert(!isdead(g, L1));
328 for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next) 326 for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
329 lua_assert(upisopen(uv)); /* must be open */ 327 lua_assert(upisopen(uv)); /* must be open */
330 for (ci = L1->ci; ci != NULL; ci = ci->previous) 328 for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous) {
331 lua_assert(lua_checkpc(ci));
332 for (o = L1->func; o->stkci.previous != 0; o -= o->stkci.previous)
333 lua_assert(functop(o) <= L1->stack_last); 329 lua_assert(functop(o) <= L1->stack_last);
330 lua_assert(lua_checkpc(o));
331 }
334 lua_assert(o == L1->stack); 332 lua_assert(o == L1->stack);
335 if (L1->stack) { /* complete thread? */ 333 if (L1->stack) { /* complete thread? */
336 for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++) 334 for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)
diff --git a/lvm.c b/lvm.c
index 7acb387f..ce15d61b 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.301 2017/11/01 18:20:48 roberto Exp roberto $ 2** $Id: lvm.c,v 2.302 2017/11/03 12:12:30 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*/
@@ -654,13 +654,14 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
654} 654}
655 655
656 656
657#define basepc(base) ((base - 1)->stkci.u.l.savedpc)
658
657/* 659/*
658** finish execution of an opcode interrupted by an yield 660** finish execution of an opcode interrupted by an yield
659*/ 661*/
660void luaV_finishOp (lua_State *L) { 662void luaV_finishOp (lua_State *L) {
661 CallInfo *ci = L->ci;
662 StkId base = L->func + 1; 663 StkId base = L->func + 1;
663 Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ 664 Instruction inst = *(basepc(base) - 1); /* interrupted instruction */
664 OpCode op = GET_OPCODE(inst); 665 OpCode op = GET_OPCODE(inst);
665 switch (op) { /* finish its execution */ 666 switch (op) { /* finish its execution */
666 case OP_ADDI: case OP_SUBI: 667 case OP_ADDI: case OP_SUBI:
@@ -684,9 +685,9 @@ void luaV_finishOp (lua_State *L) {
684 callstatus(base - 1) ^= CIST_LEQ; /* clear mark */ 685 callstatus(base - 1) ^= CIST_LEQ; /* clear mark */
685 res = !res; /* negate result */ 686 res = !res; /* negate result */
686 } 687 }
687 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); 688 lua_assert(GET_OPCODE(*basepc(base)) == OP_JMP);
688 if (res != GETARG_A(inst)) /* condition failed? */ 689 if (res != GETARG_A(inst)) /* condition failed? */
689 ci->u.l.savedpc++; /* skip jump instruction */ 690 basepc(base)++; /* skip jump instruction */
690 break; 691 break;
691 } 692 }
692 case OP_CONCAT: { 693 case OP_CONCAT: {
@@ -704,7 +705,7 @@ void luaV_finishOp (lua_State *L) {
704 break; 705 break;
705 } 706 }
706 case OP_TFORCALL: { 707 case OP_TFORCALL: {
707 lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); 708 lua_assert(GET_OPCODE(*basepc(base)) == OP_TFORLOOP);
708 L->top = functop(base - 1); /* correct top */ 709 L->top = functop(base - 1); /* correct top */
709 break; 710 break;
710 } 711 }
@@ -763,20 +764,22 @@ void luaV_finishOp (lua_State *L) {
763** Whenever code can raise errors (including memory errors), the global 764** Whenever code can raise errors (including memory errors), the global
764** 'pc' must be correct to report occasional errors. 765** 'pc' must be correct to report occasional errors.
765*/ 766*/
766#define savepc(L) (ci->u.l.savedpc = pc) 767#define savepc(base) (basepc(base) = pc)
768
767 769
770/* update internal copies to its correct values */
771#define updatestate() (base = L->func + 1, updatemask(L))
768 772
769/* 773/*
770** Protect code that, in general, can raise errors, reallocate the 774** Protect code that, in general, can raise errors, reallocate the
771** stack, and change the hooks. 775** stack, and change the hooks.
772*/ 776*/
773#define Protect(code) \ 777#define Protect(code) { savepc(base); {code;}; updatestate(); }
774 { savepc(L); {code;}; base = L->func + 1; updatemask(L); }
775 778
776 779
777#define checkGC(L,c) \ 780#define checkGC(L,c) \
778 { luaC_condGC(L, L->top = (c), /* limit of live values */ \ 781 { luaC_condGC(L, L->top = (c), /* limit of live values */ \
779 {Protect((void)0); L->top = functop(base - 1);}); /* restore top */ \ 782 {updatestate(); L->top = functop(base - 1);}); /* restore top */ \
780 luai_threadyield(L); } 783 luai_threadyield(L); }
781 784
782 785
@@ -798,14 +801,14 @@ void luaV_execute (lua_State *L) {
798 TValue *k; 801 TValue *k;
799 StkId base = L->func + 1; /* local copy of 'L->func + 1' */ 802 StkId base = L->func + 1; /* local copy of 'L->func + 1' */
800 int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */ 803 int mask; /* local copy of 'L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)' */
801 const Instruction *pc; /* local copy of 'ci->u.l.savedpc' */ 804 const Instruction *pc; /* local copy of 'basepc(base)' */
802 callstatus(base - 1) |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */ 805 callstatus(base - 1) |= CIST_FRESH; /* fresh invocation of 'luaV_execute" */
803 newframe: /* reentry point when frame changes (call/return) */ 806 newframe: /* reentry point when frame changes (call/return) */
804 lua_assert(ci == L->ci); 807 lua_assert(ci == L->ci);
805 cl = clLvalue(s2v(L->func)); /* local reference to function's closure */ 808 cl = clLvalue(s2v(L->func)); /* local reference to function's closure */
806 k = cl->p->k; /* local reference to function's constant table */ 809 k = cl->p->k; /* local reference to function's constant table */
807 updatemask(L); 810 updatemask(L);
808 pc = ci->u.l.savedpc; 811 pc = basepc(base);
809 /* main loop of interpreter */ 812 /* main loop of interpreter */
810 for (;;) { 813 for (;;) {
811 Instruction i; 814 Instruction i;
@@ -969,7 +972,7 @@ void luaV_execute (lua_State *L) {
969 int b = GETARG_B(i); 972 int b = GETARG_B(i);
970 int c = GETARG_C(i); 973 int c = GETARG_C(i);
971 Table *t; 974 Table *t;
972 savepc(L); /* in case of allocation errors */ 975 savepc(base); /* in case of allocation errors */
973 t = luaH_new(L); 976 t = luaH_new(L);
974 sethvalue2s(L, ra, t); 977 sethvalue2s(L, ra, t);
975 if (b != 0 || c != 0) 978 if (b != 0 || c != 0)
@@ -1368,9 +1371,9 @@ void luaV_execute (lua_State *L) {
1368 int b = GETARG_B(i); 1371 int b = GETARG_B(i);
1369 if (b != 0) L->top = ra+b; /* else previous instruction set top */ 1372 if (b != 0) L->top = ra+b; /* else previous instruction set top */
1370 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); 1373 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
1371 savepc(L); 1374 savepc(base);
1372 if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ 1375 if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */
1373 Protect((void)0); /* update 'base' */ 1376 updatestate(); /* update 'base' */
1374 } 1377 }
1375 else { 1378 else {
1376 /* tail call: put called frame (n) in place of caller one (o) */ 1379 /* tail call: put called frame (n) in place of caller one (o) */
@@ -1388,7 +1391,7 @@ void luaV_execute (lua_State *L) {
1388 setobjs2s(L, ofunc + aux, nfunc + aux); 1391 setobjs2s(L, ofunc + aux, nfunc + aux);
1389 ofunc->stkci.framesize = L->top - nfunc; 1392 ofunc->stkci.framesize = L->top - nfunc;
1390 L->top = functop(ofunc); /* correct top */ 1393 L->top = functop(ofunc); /* correct top */
1391 oci->u.l.savedpc = nci->u.l.savedpc; 1394 ofunc->stkci.u.l.savedpc = nfunc->stkci.u.l.savedpc;
1392 callstatus(ofunc) |= CIST_TAIL; /* function was tail called */ 1395 callstatus(ofunc) |= CIST_TAIL; /* function was tail called */
1393 ci = L->ci = oci; /* remove new frame */ 1396 ci = L->ci = oci; /* remove new frame */
1394 base = ofunc + 1; 1397 base = ofunc + 1;
@@ -1401,7 +1404,7 @@ void luaV_execute (lua_State *L) {
1401 vmcase(OP_RETURN) { 1404 vmcase(OP_RETURN) {
1402 int b = GETARG_B(i); 1405 int b = GETARG_B(i);
1403 if (cl->p->sizep > 0) luaF_close(L, base); 1406 if (cl->p->sizep > 0) luaF_close(L, base);
1404 savepc(L); 1407 savepc(base);
1405 b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra))); 1408 b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
1406 if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */ 1409 if (callstatus(base - 1) & CIST_FRESH) /* local 'base' still from callee */
1407 return; /* external invocation: return */ 1410 return; /* external invocation: return */
@@ -1409,8 +1412,8 @@ void luaV_execute (lua_State *L) {
1409 ci = L->ci; 1412 ci = L->ci;
1410 base = L->func + 1; 1413 base = L->func + 1;
1411 if (b) L->top = functop(base - 1); 1414 if (b) L->top = functop(base - 1);
1412 lua_assert(isLua(L->func)); 1415 lua_assert(isLua(base - 1));
1413 lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); 1416 lua_assert(GET_OPCODE(*(basepc(base) - 1)) == OP_CALL);
1414 goto newframe; /* restart luaV_execute over previous Lua function */ 1417 goto newframe; /* restart luaV_execute over previous Lua function */
1415 } 1418 }
1416 } 1419 }
@@ -1455,7 +1458,7 @@ void luaV_execute (lua_State *L) {
1455 } 1458 }
1456 else { /* try making all values floats */ 1459 else { /* try making all values floats */
1457 lua_Number ninit; lua_Number nlimit; lua_Number nstep; 1460 lua_Number ninit; lua_Number nlimit; lua_Number nstep;
1458 savepc(L); /* in case of errors */ 1461 savepc(base); /* in case of errors */
1459 if (!tonumber(plimit, &nlimit)) 1462 if (!tonumber(plimit, &nlimit))
1460 luaG_runerror(L, "'for' limit must be a number"); 1463 luaG_runerror(L, "'for' limit must be a number");
1461 setfltvalue(plimit, nlimit); 1464 setfltvalue(plimit, nlimit);
@@ -1501,7 +1504,7 @@ void luaV_execute (lua_State *L) {
1501 } 1504 }
1502 h = hvalue(s2v(ra)); 1505 h = hvalue(s2v(ra));
1503 last = ((c-1)*LFIELDS_PER_FLUSH) + n; 1506 last = ((c-1)*LFIELDS_PER_FLUSH) + n;
1504 savepc(L); /* in case of allocation errors */ 1507 savepc(base); /* in case of allocation errors */
1505 if (last > h->sizearray) /* needs more space? */ 1508 if (last > h->sizearray) /* needs more space? */
1506 luaH_resizearray(L, h, last); /* preallocate it at once */ 1509 luaH_resizearray(L, h, last); /* preallocate it at once */
1507 for (; n > 0; n--) { 1510 for (; n > 0; n--) {
@@ -1518,7 +1521,7 @@ void luaV_execute (lua_State *L) {
1518 Proto *p = cl->p->p[GETARG_Bx(i)]; 1521 Proto *p = cl->p->p[GETARG_Bx(i)];
1519 LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */ 1522 LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */
1520 if (ncl == NULL) { /* no match? */ 1523 if (ncl == NULL) { /* no match? */
1521 savepc(L); /* in case of allocation errors */ 1524 savepc(base); /* in case of allocation errors */
1522 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ 1525 pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
1523 } 1526 }
1524 else 1527 else