/* ** load precompiled chunk */ Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) { LoadState S; Closure* cl; if (*name=='@' || *name=='=') S.name=name+1; else if (*name==LUA_SIGNATURE[0]) S.name="binary string"; else S.name=name; S.L=L; S.Z=Z; S.b=buff; LoadHeader(&S); cl=luaF_newLclosure(L,1); setclLvalue(L,L->top,cl); incr_top(L); cl->l.p=luaF_newproto(L); LoadFunction(&S,cl->l.p); if (cl->l.p->sizeupvalues != 1) { Proto* p=cl->l.p; cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); cl->l.p=p; setclLvalue(L,L->top-1,cl); } luai_verifycode(L,buff,cl->l.p); return cl; }
static void lll_closure(lua_State* L, LClosure* cl, TValue* base, TValue* ra, int bx) { Proto *p = cl->p->p[bx]; LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */ if (ncl == NULL) /* no match? */ pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ else setclLvalue(L, ra, ncl); /* push cashed closure */ }
/* ** create a new Lua closure, push it in the stack, and initialize ** its upvalues. Note that the call to 'luaC_barrierproto' must come ** before the assignment to 'p->cache', as the function needs the ** original value of that field. */ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, StkId ra) { int nup = p->sizeupvalues; Upvaldesc *uv = p->upvalues; int i; Closure *ncl = luaF_newLclosure(L, p); setclLvalue(L, ra, ncl); /* anchor new closure in stack */ for (i = 0; i < nup; i++) { /* fill in its upvalues */ if (uv[i].instack) /* upvalue refers to local variable? */ ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); else /* get upvalue from enclosing function */ ncl->l.upvals[i] = encup[uv[i].idx]; } luaC_barrierproto(L, p, ncl); p->cache = ncl; /* save it on cache for reuse */ }
static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, StkId ra) { int nup = p->sizeupvalues; Upvaldesc *uv = p->upvalues; int i; LClosure *ncl = luaF_newLclosure(L, nup); ncl->p = p; setclLvalue(L, ra, ncl); /* anchor new closure in stack */ for (i = 0; i < nup; i++) { /* fill in its upvalues */ if (uv[i].instack) /* upvalue refers to local variable? */ ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx); else /* get upvalue from enclosing function */ ncl->upvals[i] = encup[uv[i].idx]; ncl->upvals[i]->refcount++; /* new closure is white, so we do not need a barrier here */ } if (!isblack(p)) /* cache will not break GC invariant? */ p->cache = ncl; /* save it on cache for reuse */ }
/* ** load precompiled chunk */ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { LoadState S; LClosure *cl; if (*name == '@' || *name == '=') S.name = name + 1; else if (*name == LUA_SIGNATURE[0]) S.name = "binary string"; else S.name = name; S.L = L; S.Z = Z; checkHeader(&S); cl = luaF_newLclosure(L, LoadByte(&S)); setclLvalue(L, L->top, cl); luaD_inctop(L); cl->p = luaF_newproto(L); LoadFunction(&S, cl->p, NULL); lua_assert(cl->nupvalues == cl->p->sizeupvalues); luai_verifycode(L, buff, cl->p); return cl; }
LUA_API void lua_pushlclosure (lua_State *L, LClosure *c) { lua_lock(L); setclLvalue(L, L->top, c); api_incr_top(L); lua_unlock(L); }