aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/ldo.c b/ldo.c
index 7c9ce06e..7135079b 100644
--- a/ldo.c
+++ b/ldo.c
@@ -160,8 +160,6 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
160static void correctstack (lua_State *L, StkId oldstack, StkId newstack) { 160static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
161 CallInfo *ci; 161 CallInfo *ci;
162 UpVal *up; 162 UpVal *up;
163 if (oldstack == newstack)
164 return; /* stack address did not change */
165 L->top = (L->top - oldstack) + newstack; 163 L->top = (L->top - oldstack) + newstack;
166 L->tbclist = (L->tbclist - oldstack) + newstack; 164 L->tbclist = (L->tbclist - oldstack) + newstack;
167 for (up = L->openupval; up != NULL; up = up->u.open.next) 165 for (up = L->openupval; up != NULL; up = up->u.open.next)
@@ -179,19 +177,35 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
179#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) 177#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
180 178
181 179
180/*
181** Reallocate the stack to a new size, correcting all pointers into
182** it. (There are pointers to a stack from its upvalues, from its list
183** of call infos, plus a few individual pointers.) The reallocation is
184** done in two steps (allocation + free) because the correction must be
185** done while both addresses (the old stack and the new one) are valid.
186** (In ISO C, any pointer use after the pointer has been deallocated is
187** undefined behavior.)
188** In case of allocation error, raise an error or return false according
189** to 'raiseerror'.
190*/
182int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { 191int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
183 int lim = stacksize(L); 192 int oldsize = stacksize(L);
184 StkId newstack = luaM_reallocvector(L, L->stack, 193 int i;
185 lim + EXTRA_STACK, newsize + EXTRA_STACK, StackValue); 194 StkId newstack = luaM_reallocvector(L, NULL, 0,
195 newsize + EXTRA_STACK, StackValue);
186 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); 196 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
187 if (l_unlikely(newstack == NULL)) { /* reallocation failed? */ 197 if (l_unlikely(newstack == NULL)) { /* reallocation failed? */
188 if (raiseerror) 198 if (raiseerror)
189 luaM_error(L); 199 luaM_error(L);
190 else return 0; /* do not raise an error */ 200 else return 0; /* do not raise an error */
191 } 201 }
192 for (; lim < newsize; lim++) 202 /* number of elements to be copied to the new stack */
193 setnilvalue(s2v(newstack + lim + EXTRA_STACK)); /* erase new segment */ 203 i = ((oldsize <= newsize) ? oldsize : newsize) + EXTRA_STACK;
204 memcpy(newstack, L->stack, i * sizeof(StackValue));
205 for (; i < newsize + EXTRA_STACK; i++)
206 setnilvalue(s2v(newstack + i)); /* erase new segment */
194 correctstack(L, L->stack, newstack); 207 correctstack(L, L->stack, newstack);
208 luaM_freearray(L, L->stack, oldsize + EXTRA_STACK);
195 L->stack = newstack; 209 L->stack = newstack;
196 L->stack_last = L->stack + newsize; 210 L->stack_last = L->stack + newsize;
197 return 1; 211 return 1;