static void checkstacksizes (lua_State *L, StkId max) { int used = L->ci - L->base_ci; /* number of `ci' in use */ if (4*used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ else condhardstacktests(luaD_reallocCI(L, L->size_ci)); used = max - L->stack; /* part of stack in use */ if (4*used < L->stacksize && 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ else condhardstacktests(luaD_reallocstack(L, L->stacksize)); }
static void checkstacksizes (lua_State *L, StkId max) { int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ int s_used = cast_int(max - L->stack); /* part of stack in use */ if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ return; /* do not touch the stacks */ if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ condhardstacktests(luaD_reallocCI(L, ci_used + 1)); if (4*s_used < L->stacksize && 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ condhardstacktests(luaD_reallocstack(L, s_used)); }
static void restore_stack_limit (lua_State *L) { lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ int inuse = cast_int(L->ci - L->base_ci); if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ luaD_reallocCI(L, LUAI_MAXCALLS); } }
static void unpersistthread(int ref, UnpersistInfo *upi) { /* perms reftbl ... */ lua_State *L2; L2 = lua_newthread(upi->L); /* L1: perms reftbl ... thr */ /* L2: (empty) */ registerobject(ref, upi); /* First, deserialize the object stack. */ { int i, stacksize; verify(luaZ_read(&upi->zio, &stacksize, sizeof(int)) == 0); luaD_growstack(L2, stacksize); /* Make sure that the first stack element (a nil, representing * the imaginary top-level C function) is written to the very, * very bottom of the stack */ L2->top--; for(i=0; i<stacksize; i++) { unpersist(upi); /* L1: perms reftbl ... thr obj* */ } lua_xmove(upi->L, L2, stacksize); /* L1: perms reftbl ... thr */ /* L2: obj* */ } /* Now, deserialize the CallInfo stack. */ { int i, numframes; verify(luaZ_read(&upi->zio, &numframes, sizeof(int)) == 0); luaD_reallocCI(L2,numframes*2); for(i=0; i<numframes; i++) { CallInfo *ci = L2->base_ci + i; int stackbase, stacktop, pc; verify(luaZ_read(&upi->zio, &stackbase, sizeof(int)) == 0); verify(luaZ_read(&upi->zio, &stacktop, sizeof(int)) == 0); verify(luaZ_read(&upi->zio, &pc, sizeof(int)) == 0); verify(luaZ_read(&upi->zio, &(ci->state), sizeof(int)) == 0); ci->base = L2->stack+stackbase; ci->top = L2->stack+stacktop; if(!(ci->state & CI_C)) { ci->u.l.savedpc = ci_func(ci)->l.p->code + pc; } ci->u.l.tailcalls = 0; /* Update the pointer each time, to keep the GC * happy*/ L2->ci = ci; } } /* L1: perms reftbl ... thr */ { int stackbase, stacktop; verify(luaZ_read(&upi->zio, &stackbase, sizeof(int)) == 0); verify(luaZ_read(&upi->zio, &stacktop, sizeof(int)) == 0); L2->base = L2->stack + stackbase; L2->top = L2->stack + stacktop; } /* Finally, "reopen" upvalues (see persistupval() for why) */ { UpVal* uv; GCObject **nextslot = &L2->openupval; while(1) { int stackpos; unpersist(upi); /* perms reftbl ... thr uv/nil */ if(lua_isnil(upi->L, -1)) { /* perms reftbl ... thr nil */ lua_pop(upi->L, 1); /* perms reftbl ... thr */ break; } /* perms reftbl ... thr boxeduv */ unboxupval(upi->L); /* perms reftbl ... thr uv */ uv = toupval(upi->L, -1); lua_pop(upi->L, 1); /* perms reftbl ... thr */ verify(luaZ_read(&upi->zio, &stackpos, sizeof(int)) == 0); uv->v = L2->stack + stackpos; gcunlink(upi->L, valtogco(uv)); uv->marked = 1; *nextslot = valtogco(uv); nextslot = &uv->next; } *nextslot = NULL; } }