public static lua_State lua_newthread(lua_State L) { global_State g = imp.G(L); lua_lock(L); imp.luaC_checkGC(L); /* create new thread */ lua_State L1 = imp.luaM_newobject <LX> (L).l; L1.marked = imp.luaC_white(g); L1.tt = cc.LUA_TTHREAD; /* link it on list 'allgc' */ L1.next = g.allgc; g.allgc = L1; /* anchor it on L stack */ imp.setthvalue(L, L.top, L1); imp.api_incr_top(L); imp.preinit_thread(L1, g); L1.hookmask = L.hookmask; L1.basehookcount = L.basehookcount; L1.hook = L.hook; imp.resethookcount(L1); /* initialize L1 extra space */ imp.memcpy(L1.lg.l.extra_, 0, L.lg.l.extra_, LUA_EXTRASPACE); imp.luai_userstatethread(L, L1); imp.stack_init(L1, L); lua_unlock(L); return(L1); }
/* ** open parts of the state that may cause memory-allocation errors. ** ('g->version' != NULL flags that the state was completely build) */ public static void f_luaopen(lua_State L, object ud) { global_State g = G(L); stack_init(L, L); /* init stack */ lstate.init_registry(L, g); luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ luaT_init(L); /* pre-create memory-error message */ g.memerrmsg = luaS_newliteral(L, lstate.MEMERRMSG); luaC_fix(L, g.memerrmsg); /* it should never be collected */ g.version = cc.lua_version(null); luai_userstateopen(L); }
/* ** Create registry table and its predefined values */ public static void init_registry(lua_State L, global_State g) { /* create registry */ Table registry = luaH_new(L); sethvalue(L, g.l_registry, registry); luaH_resize(L, registry, cc.LUA_RIDX_LAST, 0); /* registry[LUA_RIDX_MAINTHREAD] = L */ TValue temp = luaM_newobject <TValue> (L); setthvalue(L, temp, L); /* temp = L */ luaH_setint(L, registry, cc.LUA_RIDX_MAINTHREAD, temp); /* registry[LUA_RIDX_GLOBALS] = table of globals */ sethvalue(L, temp, luaH_new(L)); /* temp = new table (global table) */ luaH_setint(L, registry, cc.LUA_RIDX_GLOBALS, temp); }
public static void close_state(lua_State L) { global_State g = G(L); luaF_close(L, 0); /* close all upvalues for this thread */ luaC_freeallobjects(L); /* collect all objects */ if (g.version != 0) /* closing a fully built state? */ { luai_userstateclose(L); } luaM_freearray(L, g.strt.hash); luaZ_freebuffer(L, g.buff); freestack(L); //lua_assert (gettotalbytes (g) == sizeof (LG)); luaM_free(L, fromstate(L)); }
/* ** preinitialize a thread with consistent values without allocating ** any memory (to avoid errors) */ public static void preinit_thread(lua_State L, global_State g) { L.l_G = g; L.stack = null; L.ci = null; L.stacksize = 0; L.twups = L; L.errorJmp = null; L.nCcalls = 0; L.basehookcount = 0; L.allowhook = 1; resethookcount(L); L.openupval = null; L.nny = 1; L.status = cc.LUA_OK; L.errfunc = 0; }
/* ** Garbage-collection function */ public static int lua_gc(lua_State L, int what, int data) { int res = 0; lua_lock(L); global_State g = imp.G(L); switch (what) { case LUA_GCSTOP: { g.gcrunning = 0; break; } case LUA_GCRESTART: { imp.luaE_setdebt(g, 0); g.gcrunning = 1; break; } case LUA_GCCOLLECT: { imp.luaC_fullgc(L, false); break; } case LUA_GCCOUNT: { /* GC values are expressed in Kbytes: #bytes/2^10 */ res = (int)(imp.gettotalbytes(g) >> 10); break; } case LUA_GCCOUNTB: { res = (int)(imp.gettotalbytes(g) & 0x3ff); break; } case LUA_GCSTEP: { long debt = 1; /* =1 to signal that it did an actual step */ byte oldrunning = g.gcrunning; g.gcrunning = 1; /* allow GC to run */ if (data == 0) { imp.luaE_setdebt(g, -imp.GCSTEPSIZE); /* to do a "small" step */ imp.luaC_step(L); } else /* add 'data' to total debt */ { debt = (long)data * 1024 + g.GCdebt; imp.luaE_setdebt(g, debt); imp.luaC_checkGC(L); } g.gcrunning = oldrunning; /* restore previous state */ if (debt > 0 && g.gcstate == imp.GCSpause) /* end of cycle? */ { res = 1; /* signal it */ } break; } case LUA_GCSETPAUSE: { res = g.gcpause; g.gcpause = data; break; } case LUA_GCSETSTEPMUL: { res = g.gcstepmul; if (data < 40) { data = 40; /* avoid ridiculous low values (and 0) */ } g.gcstepmul = data; break; } case LUA_GCISRUNNING: { res = g.gcrunning; break; } default: { res = -1; /* invalid option */ break; } } lua_unlock(L); return(res); }
/* ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) ** invariant */ public static void luaE_setdebt(global_State g, long debt) { g.totalbytes -= (debt - g.GCdebt); g.GCdebt = debt; }
/* actual number of total bytes allocated */ public static long gettotalbytes(global_State g) { return(g.totalbytes + g.GCdebt); }
public LG() { l = luaM_newobject <LX> (null); l.l.lg = this; g = luaM_newobject <global_State> (null); }