aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldo.c19
-rw-r--r--lgc.c5
-rw-r--r--lstate.c8
-rw-r--r--lstate.h13
-rw-r--r--ltests.c8
-rw-r--r--lvm.c2
6 files changed, 29 insertions, 26 deletions
diff --git a/ldo.c b/ldo.c
index 755db693..3202490e 100644
--- a/ldo.c
+++ b/ldo.c
@@ -182,10 +182,10 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
182 182
183 183
184int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { 184int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
185 int lim = L->stacksize; 185 int lim = stacksize(L);
186 StkId newstack = luaM_reallocvector(L, L->stack, lim, newsize, StackValue); 186 StkId newstack = luaM_reallocvector(L, L->stack,
187 lim + EXTRA_STACK, newsize + EXTRA_STACK, StackValue);
187 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); 188 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
188 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
189 if (unlikely(newstack == NULL)) { /* reallocation failed? */ 189 if (unlikely(newstack == NULL)) { /* reallocation failed? */
190 if (raiseerror) 190 if (raiseerror)
191 luaM_error(L); 191 luaM_error(L);
@@ -195,8 +195,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
195 setnilvalue(s2v(newstack + lim)); /* erase new segment */ 195 setnilvalue(s2v(newstack + lim)); /* erase new segment */
196 correctstack(L, L->stack, newstack); 196 correctstack(L, L->stack, newstack);
197 L->stack = newstack; 197 L->stack = newstack;
198 L->stacksize = newsize; 198 L->stack_last = L->stack + newsize;
199 L->stack_last = L->stack + newsize - EXTRA_STACK;
200 return 1; 199 return 1;
201} 200}
202 201
@@ -206,19 +205,19 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
206** is true, raises any error; otherwise, return 0 in case of errors. 205** is true, raises any error; otherwise, return 0 in case of errors.
207*/ 206*/
208int luaD_growstack (lua_State *L, int n, int raiseerror) { 207int luaD_growstack (lua_State *L, int n, int raiseerror) {
209 int size = L->stacksize; 208 int size = stacksize(L);
210 if (unlikely(size > LUAI_MAXSTACK)) { 209 if (unlikely(size > LUAI_MAXSTACK)) {
211 /* if stack is larger than maximum, thread is already using the 210 /* if stack is larger than maximum, thread is already using the
212 extra space reserved for errors, that is, thread is handling 211 extra space reserved for errors, that is, thread is handling
213 a stack error; cannot grow further than that. */ 212 a stack error; cannot grow further than that. */
214 lua_assert(L->stacksize == ERRORSTACKSIZE); 213 lua_assert(stacksize(L) == ERRORSTACKSIZE);
215 if (raiseerror) 214 if (raiseerror)
216 luaD_throw(L, LUA_ERRERR); /* error inside message handler */ 215 luaD_throw(L, LUA_ERRERR); /* error inside message handler */
217 return 0; /* if not 'raiseerror', just signal it */ 216 return 0; /* if not 'raiseerror', just signal it */
218 } 217 }
219 else { 218 else {
220 int newsize = 2 * size; /* tentative new size */ 219 int newsize = 2 * size; /* tentative new size */
221 int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; 220 int needed = cast_int(L->top - L->stack) + n;
222 if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ 221 if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */
223 newsize = LUAI_MAXSTACK; 222 newsize = LUAI_MAXSTACK;
224 if (newsize < needed) /* but must respect what was asked for */ 223 if (newsize < needed) /* but must respect what was asked for */
@@ -257,7 +256,7 @@ static int stackinuse (lua_State *L) {
257** previous size, and half of its entries are empty.) 256** previous size, and half of its entries are empty.)
258** As a particular case, if stack was handling a stack overflow and now 257** As a particular case, if stack was handling a stack overflow and now
259** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than 258** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than
260** 'stacksize' (equal to ERRORSTACKSIZE in this case), and so the stack 259** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack
261** will be reduced to a "regular" size. 260** will be reduced to a "regular" size.
262*/ 261*/
263void luaD_shrinkstack (lua_State *L) { 262void luaD_shrinkstack (lua_State *L) {
@@ -271,7 +270,7 @@ void luaD_shrinkstack (lua_State *L) {
271 } 270 }
272 /* if thread is currently not handling a stack overflow and its 271 /* if thread is currently not handling a stack overflow and its
273 size is larger than maximum "reasonable" size, shrink it */ 272 size is larger than maximum "reasonable" size, shrink it */
274 if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && L->stacksize > max) 273 if (inuse <= LUAI_MAXSTACK && stacksize(L) > max)
275 luaD_reallocstack(L, nsize, 0); /* ok if that fails */ 274 luaD_reallocstack(L, nsize, 0); /* ok if that fails */
276 else /* don't change stack */ 275 else /* don't change stack */
277 condmovestack(L,{},{}); /* (change only for debugging) */ 276 condmovestack(L,{},{}); /* (change only for debugging) */
diff --git a/lgc.c b/lgc.c
index 4a7bcaed..3b8d0ed6 100644
--- a/lgc.c
+++ b/lgc.c
@@ -633,8 +633,7 @@ static int traversethread (global_State *g, lua_State *th) {
633 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) 633 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
634 markobject(g, uv); /* open upvalues cannot be collected */ 634 markobject(g, uv); /* open upvalues cannot be collected */
635 if (g->gcstate == GCSatomic) { /* final traversal? */ 635 if (g->gcstate == GCSatomic) { /* final traversal? */
636 StkId lim = th->stack + th->stacksize; /* real end of stack */ 636 for (; o < th->stack_last; o++) /* clear not-marked stack slice */
637 for (; o < lim; o++) /* clear not-marked stack slice */
638 setnilvalue(s2v(o)); 637 setnilvalue(s2v(o));
639 /* 'remarkupvals' may have removed thread from 'twups' list */ 638 /* 'remarkupvals' may have removed thread from 'twups' list */
640 if (!isintwups(th) && th->openupval != NULL) { 639 if (!isintwups(th) && th->openupval != NULL) {
@@ -644,7 +643,7 @@ static int traversethread (global_State *g, lua_State *th) {
644 } 643 }
645 else if (!g->gcemergency) 644 else if (!g->gcemergency)
646 luaD_shrinkstack(th); /* do not change stack in emergency cycle */ 645 luaD_shrinkstack(th); /* do not change stack in emergency cycle */
647 return 1 + th->stacksize; 646 return 1 + stacksize(th);
648} 647}
649 648
650 649
diff --git a/lstate.c b/lstate.c
index 13c1ff0f..76df6a20 100644
--- a/lstate.c
+++ b/lstate.c
@@ -180,12 +180,11 @@ LUAI_FUNC void luaE_incCstack (lua_State *L) {
180static void stack_init (lua_State *L1, lua_State *L) { 180static void stack_init (lua_State *L1, lua_State *L) {
181 int i; CallInfo *ci; 181 int i; CallInfo *ci;
182 /* initialize stack array */ 182 /* initialize stack array */
183 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, StackValue); 183 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
184 L1->stacksize = BASIC_STACK_SIZE;
185 for (i = 0; i < BASIC_STACK_SIZE; i++) 184 for (i = 0; i < BASIC_STACK_SIZE; i++)
186 setnilvalue(s2v(L1->stack + i)); /* erase new stack */ 185 setnilvalue(s2v(L1->stack + i)); /* erase new stack */
187 L1->top = L1->stack; 186 L1->top = L1->stack;
188 L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; 187 L1->stack_last = L1->stack + BASIC_STACK_SIZE;
189 /* initialize first ci */ 188 /* initialize first ci */
190 ci = &L1->base_ci; 189 ci = &L1->base_ci;
191 ci->next = ci->previous = NULL; 190 ci->next = ci->previous = NULL;
@@ -206,7 +205,7 @@ static void freestack (lua_State *L) {
206 L->ci = &L->base_ci; /* free the entire 'ci' list */ 205 L->ci = &L->base_ci; /* free the entire 'ci' list */
207 luaE_freeCI(L); 206 luaE_freeCI(L);
208 lua_assert(L->nci == 0); 207 lua_assert(L->nci == 0);
209 luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ 208 luaM_freearray(L, L->stack, stacksize(L) + EXTRA_STACK); /* free stack */
210} 209}
211 210
212 211
@@ -256,7 +255,6 @@ static void preinit_thread (lua_State *L, global_State *g) {
256 L->stack = NULL; 255 L->stack = NULL;
257 L->ci = NULL; 256 L->ci = NULL;
258 L->nci = 0; 257 L->nci = 0;
259 L->stacksize = 0;
260 L->twups = L; /* thread has no upvalues */ 258 L->twups = L; /* thread has no upvalues */
261 L->errorJmp = NULL; 259 L->errorJmp = NULL;
262 L->hook = NULL; 260 L->hook = NULL;
diff --git a/lstate.h b/lstate.h
index 5573898c..cbcf07e2 100644
--- a/lstate.h
+++ b/lstate.h
@@ -127,12 +127,20 @@ struct lua_longjmp; /* defined in ldo.c */
127#endif 127#endif
128 128
129 129
130/* extra stack space to handle TM calls and some other extras */ 130/*
131** Extra stack space to handle TM calls and some other extras. This
132** space is not included in 'stack_last'. It is used only to avoid stack
133** checks, either because the element will be promptly popped or because
134** there will be a stack check soon after the push. Function frames
135** never use this extra space, so it does not need to be kept clean.
136*/
131#define EXTRA_STACK 5 137#define EXTRA_STACK 5
132 138
133 139
134#define BASIC_STACK_SIZE (2*LUA_MINSTACK) 140#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
135 141
142#define stacksize(th) cast_int((th)->stack_last - (th)->stack)
143
136 144
137/* kinds of Garbage Collection */ 145/* kinds of Garbage Collection */
138#define KGC_INC 0 /* incremental gc */ 146#define KGC_INC 0 /* incremental gc */
@@ -270,7 +278,7 @@ struct lua_State {
270 StkId top; /* first free slot in the stack */ 278 StkId top; /* first free slot in the stack */
271 global_State *l_G; 279 global_State *l_G;
272 CallInfo *ci; /* call info for current function */ 280 CallInfo *ci; /* call info for current function */
273 StkId stack_last; /* last free slot in the stack */ 281 StkId stack_last; /* end of stack (last element + 1) */
274 StkId stack; /* stack base */ 282 StkId stack; /* stack base */
275 UpVal *openupval; /* list of open upvalues in this stack */ 283 UpVal *openupval; /* list of open upvalues in this stack */
276 GCObject *gclist; 284 GCObject *gclist;
@@ -281,7 +289,6 @@ struct lua_State {
281 ptrdiff_t errfunc; /* current error handling function (stack index) */ 289 ptrdiff_t errfunc; /* current error handling function (stack index) */
282 l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ 290 l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */
283 int oldpc; /* last pc traced */ 291 int oldpc; /* last pc traced */
284 int stacksize;
285 int basehookcount; 292 int basehookcount;
286 int hookcount; 293 int hookcount;
287 volatile l_signalT hookmask; 294 volatile l_signalT hookmask;
diff --git a/ltests.c b/ltests.c
index 04e8a00a..99456159 100644
--- a/ltests.c
+++ b/ltests.c
@@ -430,17 +430,17 @@ static void checkstack (global_State *g, lua_State *L1) {
430 UpVal *uv; 430 UpVal *uv;
431 lua_assert(!isdead(g, L1)); 431 lua_assert(!isdead(g, L1));
432 if (L1->stack == NULL) { /* incomplete thread? */ 432 if (L1->stack == NULL) { /* incomplete thread? */
433 lua_assert(L1->stacksize == 0 && L1->openupval == NULL && 433 lua_assert(L1->openupval == NULL && L1->ci == NULL);
434 L1->ci == NULL);
435 return; 434 return;
436 } 435 }
437 for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next) 436 for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
438 lua_assert(upisopen(uv)); /* must be open */ 437 lua_assert(upisopen(uv)); /* must be open */
438 lua_assert(L1->top <= L1->stack_last);
439 for (ci = L1->ci; ci != NULL; ci = ci->previous) { 439 for (ci = L1->ci; ci != NULL; ci = ci->previous) {
440 lua_assert(ci->top <= L1->stack_last); 440 lua_assert(ci->top <= L1->stack_last);
441 lua_assert(lua_checkpc(ci)); 441 lua_assert(lua_checkpc(ci));
442 } 442 }
443 for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++) 443 for (o = L1->stack; o < L1->stack_last; o++)
444 checkliveness(L1, s2v(o)); /* entire stack must have valid values */ 444 checkliveness(L1, s2v(o)); /* entire stack must have valid values */
445} 445}
446 446
@@ -969,7 +969,7 @@ static int hash_query (lua_State *L) {
969static int stacklevel (lua_State *L) { 969static int stacklevel (lua_State *L) {
970 unsigned long a = 0; 970 unsigned long a = 0;
971 lua_pushinteger(L, (L->top - L->stack)); 971 lua_pushinteger(L, (L->top - L->stack));
972 lua_pushinteger(L, (L->stack_last - L->stack)); 972 lua_pushinteger(L, stacksize(L));
973 lua_pushinteger(L, L->nCcalls); 973 lua_pushinteger(L, L->nCcalls);
974 lua_pushinteger(L, L->nci); 974 lua_pushinteger(L, L->nci);
975 lua_pushinteger(L, (unsigned long)&a); 975 lua_pushinteger(L, (unsigned long)&a);
diff --git a/lvm.c b/lvm.c
index 51b22d81..72d3e695 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1151,7 +1151,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1151 StkId ra; /* instruction's A register */ 1151 StkId ra; /* instruction's A register */
1152 vmfetch(); 1152 vmfetch();
1153 lua_assert(base == ci->func + 1); 1153 lua_assert(base == ci->func + 1);
1154 lua_assert(base <= L->top && L->top < L->stack + L->stacksize); 1154 lua_assert(base <= L->top && L->top < L->stack_last);
1155 /* invalidate top for instructions not expecting it */ 1155 /* invalidate top for instructions not expecting it */
1156 lua_assert(isIT(i) || (cast_void(L->top = base), 1)); 1156 lua_assert(isIT(i) || (cast_void(L->top = base), 1));
1157 vmdispatch (GET_OPCODE(i)) { 1157 vmdispatch (GET_OPCODE(i)) {