diff options
-rw-r--r-- | lapi.h | 10 | ||||
-rw-r--r-- | lparser.c | 3 | ||||
-rw-r--r-- | lvm.c | 7 | ||||
-rw-r--r-- | testes/nextvar.lua | 3 |
4 files changed, 17 insertions, 6 deletions
@@ -11,12 +11,22 @@ | |||
11 | #include "llimits.h" | 11 | #include "llimits.h" |
12 | #include "lstate.h" | 12 | #include "lstate.h" |
13 | 13 | ||
14 | |||
15 | /* Increments 'L->top', checking for stack overflows */ | ||
14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ | 16 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ |
15 | "stack overflow");} | 17 | "stack overflow");} |
16 | 18 | ||
19 | |||
20 | /* | ||
21 | ** If a call returns too many multiple returns, the callee may not have | ||
22 | ** stack space to accomodate all results. In this case, this macro | ||
23 | ** increases its stack space ('L->ci->top'). | ||
24 | */ | ||
17 | #define adjustresults(L,nres) \ | 25 | #define adjustresults(L,nres) \ |
18 | { if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } | 26 | { if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } |
19 | 27 | ||
28 | |||
29 | /* Ensure the stack has at least 'n' elements */ | ||
20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ | 30 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ |
21 | "not enough elements in the stack") | 31 | "not enough elements in the stack") |
22 | 32 | ||
@@ -694,9 +694,10 @@ static Proto *addprototype (LexState *ls) { | |||
694 | 694 | ||
695 | /* | 695 | /* |
696 | ** codes instruction to create new closure in parent function. | 696 | ** codes instruction to create new closure in parent function. |
697 | ** The OP_CLOSURE instruction must use the last available register, | 697 | ** The OP_CLOSURE instruction uses the last available register, |
698 | ** so that, if it invokes the GC, the GC knows which registers | 698 | ** so that, if it invokes the GC, the GC knows which registers |
699 | ** are in use at that time. | 699 | ** are in use at that time. |
700 | |||
700 | */ | 701 | */ |
701 | static void codeclosure (LexState *ls, expdesc *v) { | 702 | static void codeclosure (LexState *ls, expdesc *v) { |
702 | FuncState *fs = ls->fs->prev; | 703 | FuncState *fs = ls->fs->prev; |
@@ -1258,7 +1258,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1258 | if (TESTARG_k(i)) | 1258 | if (TESTARG_k(i)) |
1259 | c += GETARG_Ax(*pc) * (MAXARG_C + 1); | 1259 | c += GETARG_Ax(*pc) * (MAXARG_C + 1); |
1260 | pc++; /* skip extra argument */ | 1260 | pc++; /* skip extra argument */ |
1261 | L->top = ci->top; /* correct top in case of GC */ | 1261 | L->top = ra + 1; /* correct top in case of emergency GC */ |
1262 | t = luaH_new(L); /* memory allocation */ | 1262 | t = luaH_new(L); /* memory allocation */ |
1263 | sethvalue2s(L, ra, t); | 1263 | sethvalue2s(L, ra, t); |
1264 | if (b != 0 || c != 0) | 1264 | if (b != 0 || c != 0) |
@@ -1478,7 +1478,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1478 | vmbreak; | 1478 | vmbreak; |
1479 | } | 1479 | } |
1480 | vmcase(OP_CLOSE) { | 1480 | vmcase(OP_CLOSE) { |
1481 | L->top = ra + 1; /* everything is free after this slot */ | ||
1482 | Protect(luaF_close(L, ra, LUA_OK)); | 1481 | Protect(luaF_close(L, ra, LUA_OK)); |
1483 | vmbreak; | 1482 | vmbreak; |
1484 | } | 1483 | } |
@@ -1755,7 +1754,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1755 | /* push function, state, and control variable */ | 1754 | /* push function, state, and control variable */ |
1756 | memcpy(ra + 4, ra, 3 * sizeof(*ra)); | 1755 | memcpy(ra + 4, ra, 3 * sizeof(*ra)); |
1757 | L->top = ra + 4 + 3; | 1756 | L->top = ra + 4 + 3; |
1758 | Protect(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ | 1757 | ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ |
1759 | updatestack(ci); /* stack may have changed */ | 1758 | updatestack(ci); /* stack may have changed */ |
1760 | i = *(pc++); /* go to next instruction */ | 1759 | i = *(pc++); /* go to next instruction */ |
1761 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); | 1760 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); |
@@ -1776,7 +1775,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1776 | if (n == 0) | 1775 | if (n == 0) |
1777 | n = cast_int(L->top - ra) - 1; /* get up to the top */ | 1776 | n = cast_int(L->top - ra) - 1; /* get up to the top */ |
1778 | else | 1777 | else |
1779 | L->top = ci->top; /* correct top in case of GC */ | 1778 | L->top = ci->top; /* correct top in case of emergency GC */ |
1780 | last += n; | 1779 | last += n; |
1781 | if (TESTARG_k(i)) { | 1780 | if (TESTARG_k(i)) { |
1782 | last += GETARG_Ax(*pc) * (MAXARG_C + 1); | 1781 | last += GETARG_Ax(*pc) * (MAXARG_C + 1); |
diff --git a/testes/nextvar.lua b/testes/nextvar.lua index a7fe625e..9d919631 100644 --- a/testes/nextvar.lua +++ b/testes/nextvar.lua | |||
@@ -671,7 +671,8 @@ collectgarbage() | |||
671 | 671 | ||
672 | local function f (n, p) | 672 | local function f (n, p) |
673 | local t = {}; for i=1,p do t[i] = i*10 end | 673 | local t = {}; for i=1,p do t[i] = i*10 end |
674 | return function (_,n) | 674 | return function (_, n, ...) |
675 | assert(select("#", ...) == 0) -- no extra arguments | ||
675 | if n > 0 then | 676 | if n > 0 then |
676 | n = n-1 | 677 | n = n-1 |
677 | return n, table.unpack(t) | 678 | return n, table.unpack(t) |