Proto *luaF_newproto (lua_State *L) { Proto *f; luaM_setname(L, "Lua_proto"); f = luaM_new(L, Proto); #if LUA_REFCOUNT f->ref = 0; #endif LUA_REFCOUNT luaC_link(L, valtogco(f), LUA_TPROTO); f->k = NULL; f->sizek = 0; f->p = NULL; f->sizep = 0; f->code = NULL; f->sizecode = 0; f->sizelineinfo = 0; f->sizeupvalues = 0; f->nups = 0; f->upvalues = NULL; f->numparams = 0; f->is_vararg = 0; f->maxstacksize = 0; f->lineinfo = NULL; f->sizelocvars = 0; f->locvars = NULL; f->lineDefined = 0; f->source = NULL; return f; }
static UpVal *makeupval(lua_State *L, int stackpos) { UpVal *uv = luaM_new(L, UpVal); uv->tt = LUA_TUPVAL; uv->v = &uv->value; setobj(uv->v, getobject(L, stackpos)); luaC_link(L, valtogco(uv), LUA_TUPVAL); return uv; }
lua_State *luaE_newthread (lua_State *L) { lua_State *L1 = mallocstate(L); luaC_link(L, valtogco(L1), LUA_TTHREAD); preinit_state(L1); L1->l_G = L->l_G; stack_init(L1, L); /* init stack */ setobj2n(gt(L1), gt(L)); /* share table of globals */ return L1; }
void luaF_close (lua_State *L, StkId level) { UpVal *p; while ((p = ngcotouv(L->openupval)) != NULL && p->v >= level) { setobj2n(&p->value, p->v); /* save current value (write barrier) */ p->v = &p->value; /* now current value lives here */ L->openupval = p->next; /* remove from `open' list */ luaC_link(L, valtogco(p), LUA_TUPVAL); } }
Closure *luaF_newCclosure (lua_State *L, int nelems) { Closure *c; luaM_setname(L, "Lua_closure"); c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); #if LUA_REFCOUNT c->c.ref = 0; #endif LUA_REFCOUNT luaC_link(L, valtogco(c), LUA_TFUNCTION); c->c.isC = 1; c->c.nupvalues = cast(lu_byte, nelems); return c; }
Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e) { Closure *c; luaM_setname(L, "Lua_closure"); c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); #if LUA_REFCOUNT c->l.ref = 0; #endif LUA_REFCOUNT luaC_link(L, valtogco(c), LUA_TFUNCTION); c->l.isC = 0; c->l.g = *e; #if LUA_REFCOUNT __AddRef(&c->l.g); #endif LUA_REFCOUNT c->l.nupvalues = cast(lu_byte, nelems); return c; }
UpVal *luaF_findupval (lua_State *L, StkId level) { GCObject **pp = &L->openupval; UpVal *p; UpVal *v; while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { if (p->v == level) return p; pp = &p->next; } v = luaM_new(L, UpVal); /* not found: create a new one */ v->tt = LUA_TUPVAL; v->marked = 1; /* open upvalues should not be collected */ v->v = level; /* current value lives in the stack */ v->next = *pp; /* chain it in the proper position */ #if LUA_REFCOUNT v->prev = NULL; v->ref = 0; #endif LUA_REFCOUNT *pp = valtogco(v); return v; }
lua_State *luaE_newthread (lua_State *L) { lua_State *L1 = mallocstate(L); luaC_link(L, valtogco(L1), LUA_TTHREAD); preinit_state(L1); L1->l_G = L->l_G; #if LUA_REFCOUNT L1->gclist_head.next = (GCObject*)&L->gclist_tail; L1->gclist_head.prev = NULL; L1->gclist_tail.next = NULL; L1->gclist_tail.prev = (GCObject*)&L->gclist_head; L1->gclist_head.tt = LUA_TNIL; L1->gclist_head.marked = 0; L1->gclist_head.ref = 0; L1->gclist_tail.tt = LUA_TNIL; L1->gclist_tail.marked = 0; L1->gclist_tail.ref = 0; L1->ref = 0; #endif LUA_REFCOUNT stack_init(L1, L); /* init stack */ setobj2n(gt(L1), gt(L)); /* share table of globals */ return L1; }
static void traversetable (GCState *st, Table *h) { int i; int weakkey = 0; int weakvalue = 0; const TObject *mode; markvalue(st, h->metatable); lua_assert(h->lsizenode || h->node == st->g->dummynode); mode = gfasttm(st->g, h->metatable, TM_MODE); if (mode && ttisstring(mode)) { /* is there a weak mode? */ weakkey = (strchr(svalue(mode), 'k') != NULL); weakvalue = (strchr(svalue(mode), 'v') != NULL); if (weakkey || weakvalue) { /* is really weak? */ GCObject **weaklist; h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT)); weaklist = (weakkey && weakvalue) ? &st->wkv : (weakkey) ? &st->wk : &st->wv; h->gclist = *weaklist; /* must be cleared after GC, ... */ *weaklist = valtogco(h); /* ... so put in the appropriate list */ } } if (!weakvalue) { i = h->sizearray; while (i--) markobject(st, &h->array[i]); } i = sizenode(h); while (i--) { Node *n = gnode(h, i); if (!ttisnil(gval(n))) { lua_assert(!ttisnil(gkey(n))); condmarkobject(st, gkey(n), !weakkey); condmarkobject(st, gval(n), !weakvalue); } } }
static void pushclosure(lua_State *L, Closure *closure) { TObject o; o.tt = LUA_TFUNCTION; o.value.gc = valtogco(closure); luaA_pushobject(L, &o); }
static void pushupval(lua_State *L, UpVal *upval) { TObject o; o.tt = LUA_TUPVAL; o.value.gc = valtogco(upval); luaA_pushobject(L, &o); }
static void pushproto(lua_State *L, Proto *proto) { TObject o; o.tt = LUA_TPROTO; o.value.gc = valtogco(proto); luaA_pushobject(L, &o); }
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; } }