static int addk (FuncState *fs, TValue *k, TValue *v) { lua_State *L = fs->L; TValue *idx = luaH_set(L, fs->h, k); Proto *f = fs->f; int oldsize = f->sizek; if (ttisnumber(idx)) { lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); return cast_int(nvalue(idx)); } else { /* constant not found; create a new entry */ setnvalue(idx, cast_num(fs->nk)); #if LUA_MEMORY_STATS luaM_setname(L, "lua.parser.constants"); #endif /* LUA_MEMORY_STATS */ luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, MAXARG_Bx, "constant table overflow"); #if LUA_MEMORY_STATS luaM_setname(L, 0); #endif /* LUA_MEMORY_STATS */ #if LUA_REFCOUNT while (oldsize < f->sizek) setnilvalue2n(L, &f->k[oldsize++]); #else while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); #endif /* LUA_REFCOUNT */ setobj(L, &f->k[fs->nk], v); luaC_barrier(L, f, v); return fs->nk++; } }
static void stack_init (lua_State *L1, lua_State *L) { #if LUA_MEMORY_STATS luaM_setname(L, "lua.callinfo"); #endif /* LUA_MEMORY_STATS */ /* initialize CallInfo array */ L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); L1->ci = L1->base_ci; L1->size_ci = BASIC_CI_SIZE; L1->end_ci = L1->base_ci + L1->size_ci - 1; /* initialize stack array */ #if LUA_MEMORY_STATS luaM_setname(L, "lua.stack"); #endif /* LUA_MEMORY_STATS */ L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; L1->top = L1->stack; L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; #if LUA_REFCOUNT luarc_newarray(L1->stack, L1->stack + L1->stacksize); #endif /* LUA_REFCOUNT */ /* initialize first ci */ L1->ci->func = L1->top; #if LUA_REFCOUNT setnilvalue2n(L1, L1->top++); /* `function' entry for this `ci' */ #else setnilvalue(L1->top++); /* `function' entry for this `ci' */ #endif /* LUA_REFCOUNT */ L1->base = L1->ci->base = L1->top; L1->ci->top = L1->top + LUA_MINSTACK; #if LUA_MEMORY_STATS luaM_setname(L, 0); #endif /* LUA_MEMORY_STATS */ }
static void preinit_state (lua_State *L, global_State *g) { G(L) = g; L->stack = NULL; L->stacksize = 0; L->errorJmp = NULL; L->hook = NULL; L->hookmask = 0; L->basehookcount = 0; #if !LUA_EXT_RESUMABLEVM L->allowhook = 1; #endif /* LUA_EXT_RESUMABLEVM */ resethookcount(L); L->openupval = NULL; L->size_ci = 0; #if LUA_EXT_RESUMABLEVM L->nCcalls = LUA_NOYIELD | LUA_NOVPCALL; #else L->nCcalls = L->baseCcalls = 0; #endif /* LUA_EXT_RESUMABLEVM */ L->status = 0; L->base_ci = L->ci = NULL; #if LUA_EXT_RESUMABLEVM L->ctx = NULL; #else L->savedpc = NULL; L->errfunc = 0; #endif /* LUA_EXT_RESUMABLEVM */ #if LUA_REFCOUNT L->ref = 0; setnilvalue2n(L, gt(L)); #else setnilvalue(gt(L)); #endif /* LUA_REFCOUNT */ }
void GCTM (lua_State *L) { #else static void GCTM (lua_State *L) { #endif /* LUA_REFCOUNT */ global_State *g = G(L); GCObject *o = g->tmudata->gch.next; /* get first element */ Udata *udata = rawgco2u(o); const TValue *tm; /* remove udata from `tmudata' */ if (o == g->tmudata) /* last element? */ g->tmudata = NULL; else g->tmudata->gch.next = udata->uv.next; #if LUA_REFCOUNT udata->uv.prev = (GCObject*)&G(L)->mainthread->next; #endif /* LUA_REFCOUNT */ udata->uv.next = g->mainthread->next; /* return it to `root' list */ #if LUA_REFCOUNT if (udata->uv.next) udata->uv.next->uv.prev = obj2gco(udata); #endif /* LUA_REFCOUNT */ g->mainthread->next = o; makewhite(g, o); tm = fasttm(L, udata->uv.metatable, TM_GC); if (tm != NULL) { lu_byte oldah = L->allowhook; lu_mem oldt = g->GCthreshold; L->allowhook = 0; /* stop debug hooks during GC tag method */ g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ #if LUA_REFCOUNT /* We could be in the middle of a stack set, so call the __gc metamethod on one stack level past the current one. */ L->top++; /* we're freeing this object, but fake ref count it, because GCTM actually uses it */ udata->uv.ref++; L->top += 2; setobj2s(L, L->top - 2, tm); setuvalue(L, L->top - 1, udata); luaD_call(L, L->top - 2, 0); udata->uv.ref--; L->top--; setnilvalue2n(L, L->top - 1); #else setobj2s(L, L->top, tm); setuvalue(L, L->top+1, udata); L->top += 2; luaD_call(L, L->top - 2, 0); #endif /* LUA_REFCOUNT */ L->allowhook = oldah; /* restore hooks */ g->GCthreshold = oldt; /* restore threshold */ } }
LuaObject LuaState::CreateThread(LuaState* parentState) { lua_State* L1 = lua_newthread(parentState->GetCState()); lua_TValue tobject; setnilvalue2n(L1, &tobject); setthvalue(parentState->GetCState(), &tobject, L1); LuaObject retObj = LuaObject((LuaState*)lua_getstateuserdata(L1), &tobject); setnilvalue(&tobject); lua_pop(parentState->GetCState(), 1); return retObj; }
void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) { TObject temp; #if LUA_REFCOUNT setnilvalue2n(&temp); #endif LUA_REFCOUNT if (luaV_tonumber(L, p1, &temp) == NULL) p2 = p1; /* first operand is wrong */ #if LUA_REFCOUNT setnilvalue(&temp); #endif LUA_REFCOUNT luaG_typeerror(L, p2, "perform arithmetic on"); }
static void stack_init (lua_State *L1, lua_State *L) { #if LUA_REFCOUNT StkId i; #endif LUA_REFCOUNT luaM_setname(L, "Lua_Stack"); L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TObject); L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; L1->top = L1->stack; L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; #if LUA_REFCOUNT for (i = L1->stack; i != L1->stack_last; ++i) setnilvalue2n(i); #endif LUA_REFCOUNT luaM_setname(L, "Lua_CallInfo"); L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); L1->ci = L1->base_ci; L1->ci->state = CI_C; /* not a Lua function */ setnilvalue2n(L1->top++); /* `function' entry for this `ci' */ L1->base = L1->ci->base = L1->top; L1->ci->top = L1->top + LUA_MINSTACK; L1->size_ci = BASIC_CI_SIZE; L1->end_ci = L1->base_ci + L1->size_ci; }
static void LoadConstants(LoadState* S, Proto* f) { int i,n; #if LUA_REFCOUNT lua_State *L = S->L; #endif /* LUA_REFCOUNT */ n=LoadInt(S); f->k=luaM_newvector(S->L,n,TValue); f->sizek=n; #if LUA_REFCOUNT for (i=0; i<n; i++) setnilvalue2n(L, &f->k[i]); #else for (i=0; i<n; i++) setnilvalue(&f->k[i]); #endif /* LUA_REFCOUNT */ for (i=0; i<n; i++) { TValue* o=&f->k[i]; int t=LoadChar(S); switch (t) { case LUA_TNIL: setnilvalue(o); break; case LUA_TBOOLEAN: setbvalue(o,LoadChar(S)!=0); break; case LUA_TNUMBER: setnvalue(o,LoadNumber(S)); break; case LUA_TSTRING: setsvalue2n(S->L,o,LoadString(S)); break; default: error(S,"bad constant"); break; } } n=LoadInt(S); f->p=luaM_newvector(S->L,n,Proto*); f->sizep=n; for (i=0; i<n; i++) f->p[i]=NULL; #if LUA_REFCOUNT for (i=0; i<n; i++) { f->p[i]=LoadFunction(S,f->source); luarc_addrefproto(f->p[i]); } #else for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source); #endif /* LUA_REFCOUNT */ }
LUA_API int lua_isnumber (lua_State *L, int idx) { #if LUA_REFCOUNT int ret; TObject n; const TObject *o = luaA_indexAcceptable(L, idx); setnilvalue2n(&n); ret = (o != NULL && tonumber(o, &n)); setnilvalue(&n); return ret; #else !LUA_REFCOUNT TObject n; const TObject *o = luaA_indexAcceptable(L, idx); return (o != NULL && tonumber(o, &n)); #endif LUA_REFCOUNT }
LuaObject LuaState::CreateThread(LuaState* parentState) { lua_State* L1 = lua_newthread(LuaState_to_lua_State(parentState)); lua_TValue tobject; #if LUA_REFCOUNT setnilvalue2n(L1, &tobject); #else setnilvalue(&tobject); #endif /* LUA_REFCOUNT */ setthvalue(parentState->GetCState(), &tobject, L1); LuaObject retObj = LuaObject(lua_State_To_LuaState(L1), &tobject); setnilvalue(&tobject); lua_pop(LuaState_to_lua_State(parentState), 1); return retObj; }
LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { TObject n; const TObject *o = luaA_indexAcceptable(L, idx); #if LUA_REFCOUNT setnilvalue2n(&n); if (o != NULL && tonumber(o, &n)) { lua_Number theNumber = nvalue(o); setnilvalue(&n); return theNumber; } #else !LUA_REFCOUNT if (o != NULL && tonumber(o, &n)) return nvalue(o); #endif LUA_REFCOUNT else return 0; }
static void preinit_state (lua_State *L) { L->stack = NULL; L->stacksize = 0; L->errorJmp = NULL; L->hook = NULL; L->hookmask = L->hookinit = 0; L->basehookcount = 0; L->allowhook = 1; resethookcount(L); L->openupval = NULL; L->size_ci = 0; L->nCcalls = 0; L->base_ci = L->ci = NULL; L->errfunc = 0; L->stateUserData = NULL; setnilvalue2n(gt(L)); }
static void setarrayvector (lua_State *L, Table *t, int size) { int i; #if LUA_MEMORY_STATS luaM_setname(L, "lua.arrayvector"); #endif /* LUA_MEMORY_STATS */ luaM_reallocvector(L, t->array, t->sizearray, size, TValue); #if LUA_REFCOUNT for (i=t->sizearray; i<size; i++) setnilvalue2n(L, &t->array[i]); #else for (i=t->sizearray; i<size; i++) setnilvalue(&t->array[i]); #endif /* LUA_REFCOUNT */ t->sizearray = size; #if LUA_MEMORY_STATS luaM_setname(L, 0); #endif /* LUA_MEMORY_STATS */ }
static int nilK (FuncState *fs) { TValue k, v; #if LUA_REFCOUNT lua_State *L = fs->L; int ret; setnilvalue2n(L, &v); luarc_newvalue(&k); /* cannot use nil as key; instead use table itself to represent nil */ sethvalue(fs->L, &k, fs->h); ret = addk(fs, &k, &v); luarc_cleanvalue(&k); luarc_cleanvalue(&v); return ret; #else setnilvalue(&v); /* cannot use nil as key; instead use table itself to represent nil */ sethvalue(fs->L, &k, fs->h); return addk(fs, &k, &v); #endif /* LUA_REFCOUNT */ }
static void traversestack (global_State *g, lua_State *l) { StkId o, lim; CallInfo *ci; markvalue(g, gt(l)); lim = l->top; for (ci = l->base_ci; ci <= l->ci; ci++) { lua_assert(ci->top <= l->stack_last); if (lim < ci->top) lim = ci->top; } for (o = l->stack; o < l->top; o++) markvalue(g, o); #if LUA_REFCOUNT for (; o <= lim; o++) { if (iscollectable(o)) o->value.gc->gch.ref--; setnilvalue2n(l, o); } #else for (; o <= lim; o++) setnilvalue(o); #endif /* LUA_REFCOUNT */ checkstacksizes(l, lim); }
static void LoadConstants (LoadState* S, Proto* f) { lua_State *L = S->L; int i,n; (void)L; n=LoadInt(S); luaM_setname(S->L, "Lua_constants"); f->k=luaM_newvector(S->L,n,TObject); f->sizek=n; for (i=0; i<n; i++) { TObject* o=&f->k[i]; int t=LoadByte(S); switch (t) { case LUA_TNUMBER: setnvalue2n(o,LoadNumber(S)); break; case LUA_TSTRING: setsvalue2n(o,LoadString(S)); break; case LUA_TWSTRING: setwsvalue2n(o,LoadWString(S)); break; case LUA_TNIL: setnilvalue2n(o); break; default: luaG_runerror(S->L,"bad constant type (%d) in %s",t,S->name); break; } } n=LoadInt(S); f->p=luaM_newvector(S->L,n,Proto*); f->sizep=n; for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source); }
static void cleartable (lua_State *L, GCObject *l) { #else static void cleartable (GCObject *l) { #endif /* LUA_REFCOUNT */ while (l) { Table *h = gco2h(l); int i = h->sizearray; lua_assert(testbit(h->marked, VALUEWEAKBIT) || testbit(h->marked, KEYWEAKBIT)); if (testbit(h->marked, VALUEWEAKBIT)) { while (i--) { TValue *o = &h->array[i]; #if LUA_REFCOUNT if (iscleared(o, 0)) { /* value was collected? */ if (iscollectable(o)) o->value.gc->gch.ref--; setnilvalue2n(l, o); /* remove value */ } #else if (iscleared(o, 0)) /* value was collected? */ setnilvalue(o); /* remove value */ #endif /* LUA_REFCOUNT */ } } i = sizenode(h); while (i--) { Node *n = gnode(h, i); if (!ttisnil(gval(n)) && /* non-empty entry? */ (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { #if LUA_REFCOUNT if (iscollectable(gval(n))) gval(n)->value.gc->gch.ref--; setnilvalue2n(L, gval(n)); /* remove value ... */ #else setnilvalue(gval(n)); /* remove value ... */ #endif /* LUA_REFCOUNT */ removeentry(n); /* remove entry from table */ } } l = h->gclist; } } static void freeobj (lua_State *L, GCObject *o) { switch (o->gch.tt) { case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; case LUA_TTABLE: luaH_free(L, gco2h(o)); break; case LUA_TTHREAD: { lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); luaE_freethread(L, gco2th(o)); break; } case LUA_TSTRING: { G(L)->strt.nuse--; luaM_freemem(L, o, sizestring(gco2ts(o))); break; } #if LUA_WIDESTRING case LUA_TWSTRING: { G(L)->strt.nuse--; luaM_freemem(L, o, sizestring(gco2ts(o))); break; } #endif /* LUA_WIDESTRING */ case LUA_TUSERDATA: { luaM_freemem(L, o, sizeudata(gco2u(o))); break; } default: lua_assert(0); } } #define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { GCObject *curr; global_State *g = G(L); int deadmask = otherwhite(g); while ((curr = *p) != NULL && count-- > 0) { if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ sweepwholelist(L, &gco2th(curr)->openupval); if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); makewhite(g, curr); /* make it white (for next cycle) */ p = &curr->gch.next; } else { /* must erase `curr' */ lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); #if LUA_REFCOUNT if (curr->gch.prev) curr->gch.prev->gch.next = curr->gch.next; if (curr->gch.next) curr->gch.next->gch.prev = (GCObject*)p; #endif /* LUA_REFCOUNT */ *p = curr->gch.next; if (curr == g->rootgc) /* is the first element of the list? */ g->rootgc = curr->gch.next; /* adjust first */ freeobj(L, curr); } } return p; }
LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { int i; lua_State *L; global_State *g; #if LUAPLUS_EXTENSIONS void *l = (*f)(ud, NULL, 0, state_size(LG), "lua_State", 0); #else void *l = (*f)(ud, NULL, 0, state_size(LG)); #endif /* LUAPLUS_EXTENSIONS */ if (l == NULL) return NULL; L = tostate(l); g = &((LG *)L)->g; L->next = NULL; #if LUA_REFCOUNT L->prev = NULL; #endif /* LUA_REFCOUNT */ L->tt = LUA_TTHREAD; g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); L->marked = luaC_white(g); set2bits(L->marked, FIXEDBIT, SFIXEDBIT); preinit_state(L, g); g->frealloc = f; g->ud = ud; g->mainthread = L; g->uvhead.u.l.prev = &g->uvhead; g->uvhead.u.l.next = &g->uvhead; g->GCthreshold = 0; /* mark it as unfinished state */ g->strt.size = 0; g->strt.nuse = 0; g->strt.hash = NULL; #if LUA_REFCOUNT setnilvalue2n(L, registry(L)); #else setnilvalue(registry(L)); #endif /* LUA_REFCOUNT */ luaZ_initbuffer(L, &g->buff); g->panic = NULL; g->gcstate = GCSpause; g->rootgc = obj2gco(L); g->sweepstrgc = 0; g->sweepgc = &g->rootgc; g->gray = NULL; g->grayagain = NULL; g->weak = NULL; g->tmudata = NULL; g->totalbytes = sizeof(LG); g->gcpause = LUAI_GCPAUSE; g->gcstepmul = LUAI_GCMUL; g->gcdept = 0; #if LUAPLUS_EXTENSIONS g->loadNotifyFunction = NULL; g->userGCFunction = NULL; g->gchead_next = &g->gctail_next; g->gchead_prev = NULL; g->gctail_next = NULL; g->gctail_prev = &g->gchead_next; #endif /* LUAPLUS_EXTENSIONS */ for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { /* memory allocation error: free partial state */ close_state(L); L = NULL; } else luai_userstateopen(L); return L; }
/* ** open parts that may cause memory-allocation errors */ static void f_luaopen (lua_State *L, void *ud) { int i; global_State globalState; lua_State luaState; global_State *g; #ifdef _DEBUG luaState.allocName = "Lua_global_State"; #endif _DEBUG luaState.l_G = &globalState; globalState.reallocFunc = luaHelper_Realloc; globalState.freeFunc = luaHelper_Free; globalState.memData = luaHelper_memData; globalState.nblocks = sizeof(lua_State) + sizeof(global_State); // Bogus. /* create a new global state */ g = luaM_new(&luaState, global_State); UNUSED(ud); if (g == NULL) luaD_throw(L, LUA_ERRMEM); L->l_G = g; g->mainthread = L; g->GCthreshold = 0; /* mark it as unfinished state */ g->strt.size = 0; g->strt.nuse = 0; g->strt.hash = NULL; setnilvalue2n(defaultmeta(L)); setnilvalue2n(registry(L)); luaZ_initbuffer(L, &g->buff); g->panic = default_panic; #if !LUA_REFCOUNT g->rootgc = NULL; g->rootudata = NULL; g->tmudata = NULL; #else LUA_REFCOUNT g->rootgc_head.next = (GCObject*)&g->rootgc_tail; g->rootgc_head.prev = NULL; g->rootgc_tail.next = NULL; g->rootgc_tail.prev = (GCObject*)&g->rootgc_head; g->rootgc_head.tt = LUA_TNIL; g->rootgc_head.marked = 0; g->rootgc_head.ref = 0; g->rootgc_tail.tt = LUA_TNIL; g->rootgc_tail.marked = 0; g->rootgc_tail.ref = 0; g->rootudata_head.next = (GCObject*)&g->rootudata_tail; g->rootudata_head.prev = NULL; g->rootudata_tail.next = NULL; g->rootudata_tail.prev = (GCObject*)&g->rootudata_head; g->rootudata_head.tt = LUA_TNIL; g->rootudata_head.marked = 0; g->rootudata_head.ref = 0; g->rootudata_tail.tt = LUA_TNIL; g->rootudata_tail.marked = 0; g->rootudata_tail.ref = 0; g->tmudata_head.next = (GCObject*)&g->tmudata_tail; g->tmudata_head.prev = NULL; g->tmudata_tail.next = NULL; g->tmudata_tail.prev = (GCObject*)&g->tmudata_head; g->tmudata_head.tt = LUA_TNIL; g->tmudata_head.marked = 0; g->tmudata_head.ref = 0; g->tmudata_tail.tt = LUA_TNIL; g->tmudata_tail.marked = 0; g->tmudata_tail.ref = 0; #endif LUA_REFCOUNT setnilvalue2n(gkey(g->dummynode)); setnilvalue2n(gval(g->dummynode)); g->dummynode->next = NULL; g->nblocks = sizeof(lua_State) + sizeof(global_State); g->reallocFunc = luaHelper_Realloc; g->freeFunc = luaHelper_Free; g->memData = luaHelper_memData; g->fatalErrorFunc = defaultFatalErrorFunc; #ifdef LUA_MTSUPPORT g->lockData = NULL; g->lockFunc = NULL; g->unlockFunc = NULL; #endif LUA_MTSUPPORT g->userGCFunction = NULL; g->globalUserData = NULL; stack_init(L, L); /* init stack */ for (i = 0; i < LUA_NTYPES; i++) { defaultmetatypes(L, i)->value.gc = NULL; } /* create default meta table with a dummy table, and then close the loop */ defaultmeta(L)->tt = LUA_TNUMBER; defaultmeta(L)->value.gc = NULL; sethvalue2n(defaultmeta(L), luaH_new(L, 0, 0)); __AddRefDirect(hvalue(defaultmeta(L))); hvalue(defaultmeta(L))->metatable = hvalue(defaultmeta(L)); __AddRefDirect(hvalue(defaultmeta(L))->metatable); /* build meta tables */ for (i = 0; i < LUA_NTYPES; i++) { luaM_setname(L, "Lua_defaultMetaTypes"); sethvalue2n(defaultmetatypes(L, i), luaH_new(L, 0, 0)); hvalue(defaultmetatypes(L, i))->metatable = hvalue(defaultmeta(L)); } luaM_setname(L, "Lua_Globals"); sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */ __AddRefDirect(hvalue(gt(L))); luaM_setname(L, "Lua_Registry"); sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */ __AddRef(registry(L)); g->minimumstrings = lua_minimumnumstrings; luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ luaT_init(L); luaX_init(L); luaS_fix(luaS_newliteral(L, MEMERRMSG)); g->GCthreshold = 4*G(L)->nblocks; luaZ_openspace(L, &g->buff, lua_minimumauxspace); }