diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-12-08 15:28:25 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-12-08 15:28:25 -0200 |
| commit | e663a24ab03a54fa221c20a793812e5c5ffdf94f (patch) | |
| tree | 8fbd40f779f0eed29d46f26c07e1234fd5df8bae /ldo.c | |
| parent | 40f823ec907fd725617e37199199b3ed424bd88c (diff) | |
| download | lua-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.c | 42 |
1 files changed, 23 insertions, 19 deletions
| @@ -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 | */ |
| 159 | static void correctstack (lua_State *L, StkId oldstack) { | 159 | static 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 | ||
| 180 | void luaD_reallocstack (lua_State *L, int newsize) { | 180 | int 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 | ||
| 194 | void luaD_growstack (lua_State *L, int n) { | 199 | int 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 | } |
