aboutsummaryrefslogtreecommitdiff
path: root/lstate.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-02-09 14:00:05 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-02-09 14:00:05 -0300
commit4e47f81188d37e29027158b76271d02a781242e2 (patch)
treec360912d1901acf8371390cc1f716278e5d91bb4 /lstate.c
parentc63e5d212bc5dec1b1c749e3f07b42cd83081826 (diff)
downloadlua-4e47f81188d37e29027158b76271d02a781242e2.tar.gz
lua-4e47f81188d37e29027158b76271d02a781242e2.tar.bz2
lua-4e47f81188d37e29027158b76271d02a781242e2.zip
New implementation for to-be-closed variables
To-be-closed variables are linked in their own list, embedded into the stack elements. (Due to alignment, this information does not change the size of the stack elements in most architectures.) This new list does not produce garbage and avoids memory errors when creating tbc variables.
Diffstat (limited to 'lstate.c')
-rw-r--r--lstate.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/lstate.c b/lstate.c
index 52336f44..38078521 100644
--- a/lstate.c
+++ b/lstate.c
@@ -181,6 +181,7 @@ static 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 + EXTRA_STACK, StackValue); 183 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
184 L1->tbclist = L1->stack;
184 for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++) 185 for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++)
185 setnilvalue(s2v(L1->stack + i)); /* erase new stack */ 186 setnilvalue(s2v(L1->stack + i)); /* erase new stack */
186 L1->top = L1->stack; 187 L1->top = L1->stack;
@@ -262,16 +263,18 @@ static void preinit_thread (lua_State *L, global_State *g) {
262 L->status = LUA_OK; 263 L->status = LUA_OK;
263 L->errfunc = 0; 264 L->errfunc = 0;
264 L->oldpc = 0; 265 L->oldpc = 0;
265 L->ptbc = NULL;
266} 266}
267 267
268 268
269static void close_state (lua_State *L) { 269static void close_state (lua_State *L) {
270 global_State *g = G(L); 270 global_State *g = G(L);
271 luaD_closeprotected(L, 0, LUA_OK); /* close all upvalues */ 271 if (!completestate(g)) /* closing a partially built state? */
272 luaC_freeallobjects(L); /* collect all objects */ 272 luaC_freeallobjects(L); /* jucst collect its objects */
273 if (completestate(g)) /* closing a fully built state? */ 273 else { /* closing a fully built state */
274 luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */
275 luaC_freeallobjects(L); /* collect all objects */
274 luai_userstateclose(L); 276 luai_userstateclose(L);
277 }
275 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); 278 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
276 freestack(L); 279 freestack(L);
277 lua_assert(gettotalbytes(g) == sizeof(LG)); 280 lua_assert(gettotalbytes(g) == sizeof(LG));
@@ -312,7 +315,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
312 315
313void luaE_freethread (lua_State *L, lua_State *L1) { 316void luaE_freethread (lua_State *L, lua_State *L1) {
314 LX *l = fromstate(L1); 317 LX *l = fromstate(L1);
315 luaF_close(L1, L1->stack, NOCLOSINGMETH, 0); /* close all upvalues */ 318 luaF_closeupval(L1, L1->stack); /* close all upvalues */
316 lua_assert(L1->openupval == NULL); 319 lua_assert(L1->openupval == NULL);
317 luai_userstatefree(L, L1); 320 luai_userstatefree(L, L1);
318 freestack(L1); 321 freestack(L1);
@@ -327,7 +330,7 @@ int luaE_resetthread (lua_State *L, int status) {
327 ci->callstatus = CIST_C; 330 ci->callstatus = CIST_C;
328 if (status == LUA_YIELD) 331 if (status == LUA_YIELD)
329 status = LUA_OK; 332 status = LUA_OK;
330 status = luaD_closeprotected(L, 0, status); 333 status = luaD_closeprotected(L, 1, status);
331 if (status != LUA_OK) /* errors? */ 334 if (status != LUA_OK) /* errors? */
332 luaD_seterrorobj(L, status, L->stack + 1); 335 luaD_seterrorobj(L, status, L->stack + 1);
333 else 336 else