diff options
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 28 |
1 files changed, 21 insertions, 7 deletions
@@ -160,8 +160,6 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | |||
160 | static void correctstack (lua_State *L, StkId oldstack, StkId newstack) { | 160 | static 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 | */ | ||
182 | int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { | 191 | int 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; |