aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-12-08 15:28:25 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-12-08 15:28:25 -0200
commite663a24ab03a54fa221c20a793812e5c5ffdf94f (patch)
tree8fbd40f779f0eed29d46f26c07e1234fd5df8bae /ldo.c
parent40f823ec907fd725617e37199199b3ed424bd88c (diff)
downloadlua-e663a24ab03a54fa221c20a793812e5c5ffdf94f.tar.gz
lua-e663a24ab03a54fa221c20a793812e5c5ffdf94f.tar.bz2
lua-e663a24ab03a54fa221c20a793812e5c5ffdf94f.zip
more freedom in handling memory-allocation errors (not all allocations
automatically raise an error), which allows fixing a bug when resizing a table.
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/ldo.c b/ldo.c
index fe1fcb25..136aef55 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.176 2017/11/29 13:02:17 roberto Exp roberto $ 2** $Id: ldo.c,v 2.177 2017/12/01 15:44:51 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*/
@@ -156,17 +156,17 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
156** Stack reallocation 156** Stack reallocation
157** =================================================================== 157** ===================================================================
158*/ 158*/
159static void correctstack (lua_State *L, StkId oldstack) { 159static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
160 CallInfo *ci; 160 CallInfo *ci;
161 UpVal *up; 161 UpVal *up;
162 if (L->stack == oldstack) 162 if (oldstack == newstack)
163 return; /* stack address did not change */ 163 return; /* stack address did not change */
164 L->top = (L->top - oldstack) + L->stack; 164 L->top = (L->top - oldstack) + newstack;
165 for (up = L->openupval; up != NULL; up = up->u.open.next) 165 for (up = L->openupval; up != NULL; up = up->u.open.next)
166 up->v = s2v((uplevel(up) - oldstack) + L->stack); 166 up->v = s2v((uplevel(up) - oldstack) + newstack);
167 for (ci = L->ci; ci != NULL; ci = ci->previous) { 167 for (ci = L->ci; ci != NULL; ci = ci->previous) {
168 ci->top = (ci->top - oldstack) + L->stack; 168 ci->top = (ci->top - oldstack) + newstack;
169 ci->func = (ci->func - oldstack) + L->stack; 169 ci->func = (ci->func - oldstack) + newstack;
170 if (isLua(ci)) 170 if (isLua(ci))
171 ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */ 171 ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */
172 } 172 }
@@ -177,36 +177,40 @@ static void correctstack (lua_State *L, StkId oldstack) {
177#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) 177#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
178 178
179 179
180void luaD_reallocstack (lua_State *L, int newsize) { 180int luaD_reallocstack (lua_State *L, int newsize, int safe) {
181 StkId oldstack = L->stack;
182 int lim = L->stacksize; 181 int lim = L->stacksize;
182 StkId newstack = luaM_reallocvector(L, L->stack, lim, newsize, StackValue);
183 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); 183 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
184 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); 184 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
185 luaM_reallocvector(L, L->stack, L->stacksize, newsize, StackValue); 185 if (newstack == NULL) { /* reallocation failed? */
186 if (safe) luaM_error(L);
187 else return 0; /* no-safe mode: signal the error */
188 }
186 for (; lim < newsize; lim++) 189 for (; lim < newsize; lim++)
187 setnilvalue(s2v(L->stack + lim)); /* erase new segment */ 190 setnilvalue(s2v(newstack + lim)); /* erase new segment */
191 correctstack(L, L->stack, newstack);
192 L->stack = newstack;
188 L->stacksize = newsize; 193 L->stacksize = newsize;
189 L->stack_last = L->stack + newsize - EXTRA_STACK; 194 L->stack_last = L->stack + newsize - EXTRA_STACK;
190 correctstack(L, oldstack); 195 return 1;
191} 196}
192 197
193 198
194void luaD_growstack (lua_State *L, int n) { 199int luaD_growstack (lua_State *L, int n, int safe) {
195 int size = L->stacksize; 200 int size = L->stacksize;
201 int newsize = 2 * size;
196 if (size > LUAI_MAXSTACK) /* error after extra size? */ 202 if (size > LUAI_MAXSTACK) /* error after extra size? */
197 luaD_throw(L, LUA_ERRERR); 203 luaD_throw(L, LUA_ERRERR);
198 else { 204 else {
199 int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; 205 int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
200 int newsize = 2 * size;
201 if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; 206 if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
202 if (newsize < needed) newsize = needed; 207 if (newsize < needed) newsize = needed;
203 if (newsize > LUAI_MAXSTACK) { /* stack overflow? */ 208 if (newsize > LUAI_MAXSTACK) { /* stack overflow? */
204 luaD_reallocstack(L, ERRORSTACKSIZE); 209 luaD_reallocstack(L, ERRORSTACKSIZE, 1);
205 luaG_runerror(L, "stack overflow"); 210 luaG_runerror(L, "stack overflow");
206 } 211 }
207 else 212 } /* else */
208 luaD_reallocstack(L, newsize); 213 return luaD_reallocstack(L, newsize, safe);
209 }
210} 214}
211 215
212 216
@@ -234,7 +238,7 @@ void luaD_shrinkstack (lua_State *L) {
234 good size is smaller than current size, shrink its stack */ 238 good size is smaller than current size, shrink its stack */
235 if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && 239 if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
236 goodsize < L->stacksize) 240 goodsize < L->stacksize)
237 luaD_reallocstack(L, goodsize); 241 luaD_reallocstack(L, goodsize, 0); /* ok if that fails */
238 else /* don't change stack */ 242 else /* don't change stack */
239 condmovestack(L,{},{}); /* (change only for debugging) */ 243 condmovestack(L,{},{}); /* (change only for debugging) */
240} 244}