public static void luaC_upvalbarrier(lua_State L, UpVal uv) { if (iscollectable(uv.v) && !upisopen(uv)) { luaC_upvalbarrier_(L, uv); } }
public static void LinyeeFreeUpVal(LinyeeState L, UpVal uv) { if (uv.v != uv.u.value) /* is it open? */ { UnlinkUpVal(uv); /* remove from open list */ } LinyeeMFree(L, uv); /* free upvalue */ }
public static void luaF_freeupval(lua_State L, UpVal uv) { if (uv.v != uv.u.value) /* is it open? */ { unlinkupval(uv); /* remove from open list */ } luaM_free(L, uv); /* free upvalue */ }
public static UpVal luaF_newupval(lua_State L) { UpVal uv = luaC_newobj <UpVal>(L, LUA_TUPVAL, (uint)GetUnmanagedSize(typeof(UpVal)), null, 0).uv; uv.v = uv.u.value; setnilvalue(uv.v); return(uv); }
private static void ReallyMarkObject(GlobalState g, GCObject o) { LuaAssert(IsWhite(o) && !IsDead(g, o)); White2Gray(o); switch (o.gch.tt) { case LUA_TSTRING: { return; } case LUA_TUSERDATA: { Table mt = gco2u(o).metatable; Gray2Black(o); /* udata are never gray */ if (mt != null) { MarkObject(g, mt); } MarkObject(g, gco2u(o).env); return; } case LUATUPVAL: { UpVal uv = gco2uv(o); MarkValue(g, uv.v); if (uv.v == uv.u.value) /* closed? */ { Gray2Black(o); /* open upvalues are never black */ } return; } case LUA_TFUNCTION: { gco2cl(o).c.gclist = g.gray; g.gray = o; break; } case LUA_TTABLE: { gco2h(o).gclist = g.gray; g.gray = o; break; } case LUA_TTHREAD: { gco2th(o).gclist = g.gray; g.gray = o; break; } case LUATPROTO: { gco2p(o).gclist = g.gray; g.gray = o; break; } default: LuaAssert(0); break; } }
private static void reallymarkobject(global_State g, GCObject o) { lua_assert(iswhite(o) && !isdead(g, o)); white2gray(o); switch (o.gch.tt) { case LUA_TSTRING: { return; } case LUA_TUSERDATA: { Table mt = gco2u(o).metatable; gray2black(o); /* udata are never gray */ if (mt != null) { markobject(g, mt); } markobject(g, gco2u(o).env); return; } case LUA_TUPVAL: { UpVal uv = gco2uv(o); markvalue(g, uv.v); if (uv.v == uv.u.value) /* closed? */ { gray2black(o); /* open upvalues are never black */ } return; } case LUA_TFUNCTION: { gco2cl(o).c.gclist = g.gray; g.gray = o; break; } case LUA_TTABLE: { gco2h(o).gclist = g.gray; g.gray = o; break; } case LUA_TTHREAD: { gco2th(o).gclist = g.gray; g.gray = o; break; } case LUA_TPROTO: { gco2p(o).gclist = g.gray; g.gray = o; break; } default: lua_assert(0); break; } }
public static void uvcopy(UpVal o1, UpVal o2) { tvcopy(o1.v, o2.v); o1.refcount = o2.refcount; o1.level = o2.level; o1.u.open.touched = o2.u.open.touched; o1.u.open.next = o2.u.open.next; tvcopy(o1.u.value, o2.u.value); }
public static UpVal LuaFNewUpVal(LuaState L) { UpVal uv = LuaMNew <UpVal>(L); LuaCLink(L, obj2gco(uv), LUATUPVAL); uv.v = uv.u.value; SetNilValue(uv.v); return(uv); }
public static UpVal luaF_newupval(lua_State L) { UpVal uv = luaM_new <UpVal>(L); luaC_link(L, obj2gco(uv), LUA_TUPVAL); uv.v = uv.u.value; setnilvalue(uv.v); return(uv); }
public static UpVal LinyeeFNewUpVal(LinyeeState L) { UpVal uv = LinyeeMNew <UpVal>(L); LinyeeCLink(L, obj2gco(uv), LUATUPVAL); uv.v = uv.u.value; SetNilValue(uv.v); return(uv); }
/* ** fill a closure with new closed upvalues */ public static void luaF_initupvals(lua_State L, LClosure cl) { for (int i = 0; i < cl.nupvalues; i++) { UpVal uv = luaM_newobject <UpVal> (L); uv.refcount = 1; uv.v = uv.u.value; /* make it closed */ setnilvalue(uv.v); cl.upvals[i] = uv; } }
/* }====================================================== */ /* ** {====================================================== ** Mark functions ** ======================================================= */ /* ** mark an object. Userdata and closed upvalues are visited and turned ** black here. Strings remain gray (it is the same as making them ** black). Other objects are marked gray and added to appropriate list ** to be visited (and turned black) later. (Open upvalues are already ** linked in 'headuv' list.) */ private static void reallymarkobject(global_State g, GCObject o) { lua_assert(iswhite(o) && !isdead(g, o)); white2gray(o); switch (gch(o).tt) { case LUA_TSTRING: { return; /* for strings, gray is as good as black */ } case LUA_TUSERDATA: { Table mt = gco2u(o).metatable; markobject(g, mt); markobject(g, gco2u(o).env); gray2black(o); /* all pointers marked */ return; } case LUA_TUPVAL: { UpVal uv = gco2uv(o); markvalue(g, uv.v); if (uv.v == uv.u.value_) /* closed? (open upvalues remain gray) */ { gray2black(o); /* make it black */ } return; } case LUA_TFUNCTION: { gco2cl(o).c.gclist = g.gray; g.gray = o; break; } case LUA_TTABLE: { linktable(gco2t(o), ref g.gray); break; } case LUA_TTHREAD: { gco2th(o).gclist = g.gray; g.gray = o; break; } case LUA_TPROTO: { gco2p(o).gclist = g.gray; g.gray = o; break; } default: lua_assert(0); break; //FIXME: add break } }
public static CharPtr lua_getupvalue(lua_State L, int funcindex, int n) { CharPtr name; TValue val = null; /* to avoid warnings */ lua_lock(L); CClosure null_ = null; //FIXME:added UpVal null__ = new UpVal(); //FIXME:added name = aux_upvalue(index2addr(L, funcindex), n, ref val, ref null_, ref null__); //FIXME:changed if (name != null) { setobj2s(L, L.top, val); api_incr_top(L); } lua_unlock(L); return(name); }
public static void luaF_close(lua_State L, int level) { while (L.openupval != null && L.openupval.level >= level) { UpVal uv = L.openupval; lua_assert(upisopen(uv)); L.openupval = uv.u.open.next; /* remove from 'open' list */ if (uv.refcount == 0) /* no references? */ { luaM_free(L, uv); /* free upvalue */ } else { setobj(L, uv.u.value, uv.v); /* move value to upvalue slot */ uv.v = uv.u.value; /* now current value lives here */ luaC_upvalbarrier(L, uv); } } }
/* ** check color (and invariants) for an upvalue that was closed, ** i.e., moved into the 'allgc' list */ public static void luaC_checkupvalcolor(global_State g, UpVal uv) { GCObject o = obj2gco(uv); lua_assert(!isblack(o)); /* open upvalues are never black */ if (isgray(o)) { if (keepinvariant(g)) { resetoldbit(o); /* see MOVE OLD rule */ gray2black(o); /* it is being visited now */ markvalue(g, uv.v); } else { lua_assert(issweepphase(g)); makewhite(g, o); } } }
private static void f_parser (lua_State L, object ud) { int i; Closure cl; SParser p = (SParser)ud; int c = zgetc(p.z); /* read first character */ if (c == LUA_SIGNATURE[0]) { checkmode(L, p.mode, "binary"); cl = luaU_undump(L, p.z, p.buff, p.name); } else { checkmode(L, p.mode, "text"); cl = luaY_parser(L, p.z, p.buff, p.dyd, p.name, c); } lua_assert(cl.l.nupvalues == cl.l.p.sizeupvalues); for (i = 0; i < cl.l.nupvalues; i++) { /* initialize upvalues */ UpVal up = luaF_newupval(L); cl.l.upvals[i] = up; luaC_objbarrier(L, cl, up); } }
public static void LuaCLinkUpVal(LuaState L, UpVal uv) { GlobalState g = G(L); GCObject o = obj2gco(uv); o.gch.next = g.rootgc; /* link upvalue into `rootgc' list */ g.rootgc = o; if (IsGray(o)) { if (g.gcstate == GCSpropagate) { Gray2Black(o); /* closed upvalues need barrier */ LuaCBarrier(L, uv, uv.v); } else /* sweep phase: sweep it (turning it into white) */ { MakeWhite(g, o); LuaAssert(g.gcstate != GCSfinalize && g.gcstate != GCSpause); } } }
public static void luaC_linkupval(lua_State L, UpVal uv) { global_State g = G(L); GCObject o = obj2gco(uv); o.gch.next = g.rootgc; /* link upvalue into `rootgc' list */ g.rootgc = o; if (isgray(o)) { if (g.gcstate == GCSpropagate) { gray2black(o); /* closed upvalues need barrier */ luaC_barrier(L, uv, uv.v); } else /* sweep phase: sweep it (turning it into white) */ { makewhite(g, o); lua_assert(g.gcstate != GCSfinalize && g.gcstate != GCSpause); } } }
public static void LuaFreeUpVal (LuaState L, UpVal uv) { if (uv.v != uv.u.value) /* is it open? */ UnlinkUpVal(uv); /* remove from open list */ LuaMFree(L, uv); /* free upvalue */ }
public static void luaV_execute(lua_State L, int nexeccalls) { LClosure cl; StkId base_; TValue[] k; /*const*/ InstructionPtr pc; reentry: /* entry point */ lua_assert(isLua(L.ci)); pc = InstructionPtr.Assign(L.savedpc); cl = clvalue(L.ci.func).l; base_ = L.base_; k = cl.p.k; /* main loop of interpreter */ for (;;) { /*const*/ Instruction i = InstructionPtr.inc(ref pc)[0]; StkId ra; if (((L.hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) != 0) && (((--L.hookcount) == 0) || ((L.hookmask & LUA_MASKLINE) != 0))) { traceexec(L, pc); if (L.status == LUA_YIELD) /* did hook yield? */ { L.savedpc = new InstructionPtr(pc.codes, pc.pc - 1); return; } base_ = L.base_; } /* warning!! several calls may realloc the stack and invalidate `ra' */ ra = RA(L, base_, i); lua_assert(base_ == L.base_ && L.base_ == L.ci.base_); lua_assert(base_ <= L.top && ((L.top - L.stack) <= L.stacksize)); lua_assert(L.top == L.ci.top || (luaG_checkopenop(i) != 0)); //Dump(pc.pc, i); switch (GET_OPCODE(i)) { case OpCode.OP_MOVE: { setobjs2s(L, ra, RB(L, base_, i)); continue; } case OpCode.OP_LOADK: { setobj2s(L, ra, KBx(L, i, k)); continue; } case OpCode.OP_LOADBOOL: { setbvalue(ra, GETARG_B(i)); if (GETARG_C(i) != 0) { InstructionPtr.inc(ref pc); /* skip next instruction (if C) */ } continue; } case OpCode.OP_LOADNIL: { TValue rb = RB(L, base_, i); do { setnilvalue(StkId.dec(ref rb)); } while (rb >= ra); continue; } case OpCode.OP_GETUPVAL: { int b = GETARG_B(i); setobj2s(L, ra, cl.upvals[b].v); continue; } case OpCode.OP_GETGLOBAL: { TValue g = new TValue(); TValue rb = KBx(L, i, k); sethvalue(L, g, cl.env); lua_assert(ttisstring(rb)); //Protect( L.savedpc = InstructionPtr.Assign(pc); luaV_gettable(L, g, rb, ra); base_ = L.base_; //); L.savedpc = InstructionPtr.Assign(pc); continue; } case OpCode.OP_GETTABLE: { //Protect( L.savedpc = InstructionPtr.Assign(pc); luaV_gettable(L, RB(L, base_, i), RKC(L, base_, i, k), ra); base_ = L.base_; //); L.savedpc = InstructionPtr.Assign(pc); continue; } case OpCode.OP_SETGLOBAL: { TValue g = new TValue(); sethvalue(L, g, cl.env); lua_assert(ttisstring(KBx(L, i, k))); //Protect( L.savedpc = InstructionPtr.Assign(pc); luaV_settable(L, g, KBx(L, i, k), ra); base_ = L.base_; //); L.savedpc = InstructionPtr.Assign(pc); continue; } case OpCode.OP_SETUPVAL: { UpVal uv = cl.upvals[GETARG_B(i)]; setobj(L, uv.v, ra); luaC_barrier(L, uv, ra); continue; } case OpCode.OP_SETTABLE: { //Protect( L.savedpc = InstructionPtr.Assign(pc); luaV_settable(L, ra, RKB(L, base_, i, k), RKC(L, base_, i, k)); base_ = L.base_; //); L.savedpc = InstructionPtr.Assign(pc); continue; } case OpCode.OP_NEWTABLE: { int b = GETARG_B(i); int c = GETARG_C(i); sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); //Protect( L.savedpc = InstructionPtr.Assign(pc); luaC_checkGC(L); base_ = L.base_; //); L.savedpc = InstructionPtr.Assign(pc); continue; } case OpCode.OP_SELF: { StkId rb = RB(L, base_, i); setobjs2s(L, ra + 1, rb); //Protect( L.savedpc = InstructionPtr.Assign(pc); luaV_gettable(L, rb, RKC(L, base_, i, k), ra); base_ = L.base_; //); L.savedpc = InstructionPtr.Assign(pc); continue; } case OpCode.OP_ADD: { arith_op(L, luai_numadd, TMS.TM_ADD, base_, i, k, ra, pc); continue; } case OpCode.OP_SUB: { arith_op(L, luai_numsub, TMS.TM_SUB, base_, i, k, ra, pc); continue; } case OpCode.OP_MUL: { arith_op(L, luai_nummul, TMS.TM_MUL, base_, i, k, ra, pc); continue; } case OpCode.OP_DIV: { arith_op(L, luai_numdiv, TMS.TM_DIV, base_, i, k, ra, pc); continue; } case OpCode.OP_MOD: { arith_op(L, luai_nummod, TMS.TM_MOD, base_, i, k, ra, pc); continue; } case OpCode.OP_POW: { arith_op(L, luai_numpow, TMS.TM_POW, base_, i, k, ra, pc); continue; } case OpCode.OP_UNM: { TValue rb = RB(L, base_, i); if (ttisnumber(rb)) { lua_Number nb = nvalue(rb); setnvalue(ra, luai_numunm(nb)); } else { //Protect( L.savedpc = InstructionPtr.Assign(pc); Arith(L, ra, rb, rb, TMS.TM_UNM); base_ = L.base_; //); L.savedpc = InstructionPtr.Assign(pc); } continue; } case OpCode.OP_NOT: { int res = l_isfalse(RB(L, base_, i)) == 0 ? 0 : 1; /* next assignment may change this value */ setbvalue(ra, res); continue; } case OpCode.OP_LEN: { TValue rb = RB(L, base_, i); switch (ttype(rb)) { case LUA_TTABLE: { setnvalue(ra, (lua_Number)luaH_getn(hvalue(rb))); break; } case LUA_TSTRING: { setnvalue(ra, (lua_Number)tsvalue(rb).len); break; } default: { /* try metamethod */ //Protect( L.savedpc = InstructionPtr.Assign(pc); if (call_binTM(L, rb, luaO_nilobject, ra, TMS.TM_LEN) == 0) { luaG_typeerror(L, rb, "get length of"); } base_ = L.base_; //) break; } } continue; } case OpCode.OP_CONCAT: { int b = GETARG_B(i); int c = GETARG_C(i); //Protect( L.savedpc = InstructionPtr.Assign(pc); luaV_concat(L, c - b + 1, c); luaC_checkGC(L); base_ = L.base_; //); setobjs2s(L, RA(L, base_, i), base_ + b); continue; } case OpCode.OP_JMP: { dojump(L, pc, GETARG_sBx(i)); continue; } case OpCode.OP_EQ: { TValue rb = RKB(L, base_, i, k); TValue rc = RKC(L, base_, i, k); //Protect( L.savedpc = InstructionPtr.Assign(pc); if (equalobj(L, rb, rc) == GETARG_A(i)) { dojump(L, pc, GETARG_sBx(pc[0])); } base_ = L.base_; //); InstructionPtr.inc(ref pc); continue; } case OpCode.OP_LT: { //Protect( L.savedpc = InstructionPtr.Assign(pc); if (luaV_lessthan(L, RKB(L, base_, i, k), RKC(L, base_, i, k)) == GETARG_A(i)) { dojump(L, pc, GETARG_sBx(pc[0])); } base_ = L.base_; //); InstructionPtr.inc(ref pc); continue; } case OpCode.OP_LE: { //Protect( L.savedpc = InstructionPtr.Assign(pc); if (lessequal(L, RKB(L, base_, i, k), RKC(L, base_, i, k)) == GETARG_A(i)) { dojump(L, pc, GETARG_sBx(pc[0])); } base_ = L.base_; //); InstructionPtr.inc(ref pc); continue; } case OpCode.OP_TEST: { if (l_isfalse(ra) != GETARG_C(i)) { dojump(L, pc, GETARG_sBx(pc[0])); } InstructionPtr.inc(ref pc); continue; } case OpCode.OP_TESTSET: { TValue rb = RB(L, base_, i); if (l_isfalse(rb) != GETARG_C(i)) { setobjs2s(L, ra, rb); dojump(L, pc, GETARG_sBx(pc[0])); } InstructionPtr.inc(ref pc); continue; } case OpCode.OP_CALL: { int b = GETARG_B(i); int nresults = GETARG_C(i) - 1; if (b != 0) { L.top = ra + b; /* else previous instruction set top */ } L.savedpc = InstructionPtr.Assign(pc); switch (luaD_precall(L, ra, nresults)) { case PCRLUA: { nexeccalls++; goto reentry; /* restart luaV_execute over new Lua function */ } case PCRC: { /* it was a C function (`precall' called it); adjust results */ if (nresults >= 0) { L.top = L.ci.top; } base_ = L.base_; continue; } default: { return; /* yield */ } } } case OpCode.OP_TAILCALL: { int b = GETARG_B(i); if (b != 0) { L.top = ra + b; /* else previous instruction set top */ } L.savedpc = InstructionPtr.Assign(pc); lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); switch (luaD_precall(L, ra, LUA_MULTRET)) { case PCRLUA: { /* tail call: put new frame in place of previous one */ CallInfo ci = L.ci - 1; /* previous frame */ int aux; StkId func = ci.func; StkId pfunc = (ci + 1).func; /* previous function index */ if (L.openupval != null) { luaF_close(L, ci.base_); } L.base_ = ci.base_ = ci.func + (ci[1].base_ - pfunc); for (aux = 0; pfunc + aux < L.top; aux++) /* move frame down */ { setobjs2s(L, func + aux, pfunc + aux); } ci.top = L.top = func + aux; /* correct top */ lua_assert(L.top == L.base_ + clvalue(func).l.p.maxstacksize); ci.savedpc = InstructionPtr.Assign(L.savedpc); ci.tailcalls++; /* one more call lost */ CallInfo.dec(ref L.ci); /* remove new frame */ goto reentry; } case PCRC: { /* it was a C function (`precall' called it) */ base_ = L.base_; continue; } default: { return; /* yield */ } } } case OpCode.OP_RETURN: { int b = GETARG_B(i); if (b != 0) { L.top = ra + b - 1; } if (L.openupval != null) { luaF_close(L, base_); } L.savedpc = InstructionPtr.Assign(pc); b = luaD_poscall(L, ra); if (--nexeccalls == 0) /* was previous function running `here'? */ { return; /* no: return */ } else /* yes: continue its execution */ { if (b != 0) { L.top = L.ci.top; } lua_assert(isLua(L.ci)); lua_assert(GET_OPCODE(L.ci.savedpc[-1]) == OpCode.OP_CALL); goto reentry; } } case OpCode.OP_FORLOOP: { lua_Number step = nvalue(ra + 2); lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ lua_Number limit = nvalue(ra + 1); if (luai_numlt(0, step) ? luai_numle(idx, limit) : luai_numle(limit, idx)) { dojump(L, pc, GETARG_sBx(i)); /* jump back */ setnvalue(ra, idx); /* update internal index... */ setnvalue(ra + 3, idx); /* ...and external index */ } continue; } case OpCode.OP_FORPREP: { TValue init = ra; TValue plimit = ra + 1; TValue pstep = ra + 2; L.savedpc = InstructionPtr.Assign(pc); /* next steps may throw errors */ if (tonumber(ref init, ra) == 0) { luaG_runerror(L, LUA_QL("for") + " initial value must be a number"); } else if (tonumber(ref plimit, ra + 1) == 0) { luaG_runerror(L, LUA_QL("for") + " limit must be a number"); } else if (tonumber(ref pstep, ra + 2) == 0) { luaG_runerror(L, LUA_QL("for") + " step must be a number"); } setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); dojump(L, pc, GETARG_sBx(i)); continue; } case OpCode.OP_TFORLOOP: { StkId cb = ra + 3; /* call base */ setobjs2s(L, cb + 2, ra + 2); setobjs2s(L, cb + 1, ra + 1); setobjs2s(L, cb, ra); L.top = cb + 3; /* func. + 2 args (state and index) */ //Protect( L.savedpc = InstructionPtr.Assign(pc); luaD_call(L, cb, GETARG_C(i)); base_ = L.base_; //); L.top = L.ci.top; cb = RA(L, base_, i) + 3; /* previous call may change the stack */ if (!ttisnil(cb)) /* continue loop? */ { setobjs2s(L, cb - 1, cb); /* save control variable */ dojump(L, pc, GETARG_sBx(pc[0])); /* jump back */ } InstructionPtr.inc(ref pc); continue; } case OpCode.OP_SETLIST: { int n = GETARG_B(i); int c = GETARG_C(i); int last; Table h; if (n == 0) { n = cast_int(L.top - ra) - 1; L.top = L.ci.top; } if (c == 0) { c = cast_int(pc[0]); InstructionPtr.inc(ref pc); } runtime_check(L, ttistable(ra)); h = hvalue(ra); last = ((c - 1) * LFIELDS_PER_FLUSH) + n; if (last > h.sizearray) /* needs more space? */ { luaH_resizearray(L, h, last); /* pre-alloc it at once */ } for (; n > 0; n--) { TValue val = ra + n; setobj2t(L, luaH_setnum(L, h, last--), val); luaC_barriert(L, h, val); } continue; } case OpCode.OP_CLOSE: { luaF_close(L, ra); continue; } case OpCode.OP_CLOSURE: { Proto p; Closure ncl; int nup, j; p = cl.p.p[GETARG_Bx(i)]; nup = p.nups; ncl = luaF_newLclosure(L, nup, cl.env); ncl.l.p = p; for (j = 0; j < nup; j++, InstructionPtr.inc(ref pc)) { if (GET_OPCODE(pc[0]) == OpCode.OP_GETUPVAL) { ncl.l.upvals[j] = cl.upvals[GETARG_B(pc[0])]; } else { lua_assert(GET_OPCODE(pc[0]) == OpCode.OP_MOVE); ncl.l.upvals[j] = luaF_findupval(L, base_ + GETARG_B(pc[0])); } } setclvalue(L, ra, ncl); //Protect( L.savedpc = InstructionPtr.Assign(pc); luaC_checkGC(L); base_ = L.base_; //); continue; } case OpCode.OP_VARARG: { int b = GETARG_B(i) - 1; int j; CallInfo ci = L.ci; int n = cast_int(ci.base_ - ci.func) - cl.p.numparams - 1; if (b == LUA_MULTRET) { //Protect( L.savedpc = InstructionPtr.Assign(pc); luaD_checkstack(L, n); base_ = L.base_; //); ra = RA(L, base_, i); /* previous call may change the stack */ b = n; L.top = ra + n; } for (j = 0; j < b; j++) { if (j < n) { setobjs2s(L, ra + j, ci.base_ - n + j); } else { setnilvalue(ra + j); } } continue; } } } }
public void set(UpVal val) { this.L.openupval = val; }
private static void UnlinkUpVal(UpVal uv) { LinyeeAssert(uv.u.l.next.u.l.prev == uv && uv.u.l.prev.u.l.next == uv); uv.u.l.next.u.l.prev = uv.u.l.prev; /* remove from `uvhead' list */ uv.u.l.prev.u.l.next = uv.u.l.next; }
private static void UnlinkUpVal (UpVal uv) { LuaAssert(uv.u.l.next.u.l.prev == uv && uv.u.l.prev.u.l.next == uv); uv.u.l.next.u.l.prev = uv.u.l.prev; /* remove from `uvhead' list */ uv.u.l.prev.u.l.next = uv.u.l.next; }
private static void unlinkupval(UpVal uv) { lua_assert(uv.u.l.next.u.l.prev == uv && uv.u.l.prev.u.l.next == uv); uv.u.l.next.u.l.prev = uv.u.l.prev; /* remove from `uvhead' list */ uv.u.l.prev.u.l.next = uv.u.l.next; }
public static void luaC_linkupval(lua_State L, UpVal uv) { global_State g = G(L); GCObject o = obj2gco(uv); o.gch.next = g.rootgc; /* link upvalue into `rootgc' list */ g.rootgc = o; if (isgray(o)) { if (g.gcstate == GCSpropagate) { gray2black(o); /* closed upvalues need barrier */ luaC_barrier(L, uv, uv.v); } else { /* sweep phase: sweep it (turning it into white) */ makewhite(g, o); lua_assert(g.gcstate != GCSfinalize && g.gcstate != GCSpause); } } }
public static void LuaCLinkUpVal(LuaState L, UpVal uv) { GlobalState g = G(L); GCObject o = obj2gco(uv); o.gch.next = g.rootgc; /* link upvalue into `rootgc' list */ g.rootgc = o; if (IsGray(o)) { if (g.gcstate == GCSpropagate) { Gray2Black(o); /* closed upvalues need barrier */ LuaCBarrier(L, uv, uv.v); } else { /* sweep phase: sweep it (turning it into white) */ MakeWhite(g, o); LuaAssert(g.gcstate != GCSfinalize && g.gcstate != GCSpause); } } }
public void set(UpVal val) { this.u.next = val; }
public static void luaF_freeupval (LuaState L, UpVal uv) { if (uv.v != uv.u.value) /* is it open? */ unlinkupval(uv); /* remove from open list */ luaM_free(L, uv); /* free upvalue */ }
public static void luaV_execute(lua_State L) { CallInfo ci = L.ci; LClosure cl = clvalue(ci.func).l; TValue[] k = cl.p.k; StkId base_ = ci.u.l.base_; lua_assert(isLua(ci)); /* main loop of interpreter */ for (;;) { Instruction i = ci.u.l.savedpc[0]; InstructionPtr.inc(ref ci.u.l.savedpc); //FIXME:++ StkId ra; if (((L.hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) != 0) && (((--L.hookcount) == 0) || ((L.hookmask & LUA_MASKLINE) != 0))) { traceexec(L); if (L.status == LUA_YIELD) /* did hook yield? */ { InstructionPtr.dec(ref ci.u.l.savedpc); /* undo increment */ luaD_throw(L, LUA_YIELD); } base_ = ci.u.l.base_; } /* warning!! several calls may realloc the stack and invalidate `ra' */ ra = RA(L, base_, i); lua_assert(base_ == ci.u.l.base_); lua_assert(base_ <= L.top && ((L.top - L.stack) <= L.stacksize)); //Dump(L.ci.u.l.savedpc.pc, i); //FIXME:added, only for debugging switch (GET_OPCODE(i)) { case OpCode.OP_MOVE: { setobjs2s(L, ra, RB(L, base_, i)); continue; } case OpCode.OP_LOADK: { setobj2s(L, ra, KBx(L, i, k)); continue; } case OpCode.OP_LOADBOOL: { setbvalue(ra, GETARG_B(i)); if (GETARG_C(i) != 0) { InstructionPtr.inc(ref ci.u.l.savedpc); /* skip next instruction (if C) */ } continue; } case OpCode.OP_LOADNIL: { TValue rb = RB(L, base_, i); do { setnilvalue(StkId.dec(ref rb)); } while (rb >= ra); continue; } case OpCode.OP_GETUPVAL: { int b = GETARG_B(i); setobj2s(L, ra, cl.upvals[b].v); continue; } case OpCode.OP_GETGLOBAL: { TValue g = new TValue(); TValue rb = KBx(L, i, k); sethvalue(L, g, cl.env); lua_assert(ttisstring(rb)); //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: luaV_gettable(L, g, rb, ra); base_ = ci.u.l.base_; //); //L.savedpc = InstructionPtr.Assign(pc); //FIXME:??? continue; } case OpCode.OP_GETTABLE: { //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: luaV_gettable(L, RB(L, base_, i), RKC(L, base_, i, k), ra); base_ = ci.u.l.base_; //); //L.savedpc = InstructionPtr.Assign(pc);//FIXME:??? continue; } case OpCode.OP_SETGLOBAL: { TValue g = new TValue(); sethvalue(L, g, cl.env); lua_assert(ttisstring(KBx(L, i, k))); //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: luaV_settable(L, g, KBx(L, i, k), ra); base_ = ci.u.l.base_; //); //L.savedpc = InstructionPtr.Assign(pc); //FIXME:??? continue; } case OpCode.OP_SETUPVAL: { UpVal uv = cl.upvals[GETARG_B(i)]; setobj(L, uv.v, ra); luaC_barrier(L, uv, ra); continue; } case OpCode.OP_SETTABLE: { //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: luaV_settable(L, ra, RKB(L, base_, i, k), RKC(L, base_, i, k)); base_ = ci.u.l.base_; //); //L.savedpc = InstructionPtr.Assign(pc); //FIXME:??? continue; } case OpCode.OP_NEWTABLE: { int b = GETARG_B(i); int c = GETARG_C(i); Table t = luaH_new(L); sethvalue(L, ra, t); if (b != 0 || c != 0) { luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); } //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: luaC_checkGC(L); base_ = ci.u.l.base_; //); //L.savedpc = InstructionPtr.Assign(pc); //FIXME:??? continue; } case OpCode.OP_SELF: { StkId rb = RB(L, base_, i); setobjs2s(L, ra + 1, rb); //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: luaV_gettable(L, rb, RKC(L, base_, i, k), ra); base_ = ci.u.l.base_; //); //L.savedpc = InstructionPtr.Assign(pc); //FIXME:??? continue; } case OpCode.OP_ADD: { arith_op(L, luai_numadd, TMS.TM_ADD, base_, i, k, ra, ci); continue; } case OpCode.OP_SUB: { arith_op(L, luai_numsub, TMS.TM_SUB, base_, i, k, ra, ci); continue; } case OpCode.OP_MUL: { arith_op(L, luai_nummul, TMS.TM_MUL, base_, i, k, ra, ci); continue; } case OpCode.OP_DIV: { arith_op(L, luai_numdiv, TMS.TM_DIV, base_, i, k, ra, ci); continue; } case OpCode.OP_MOD: { arith_op(L, luai_nummod, TMS.TM_MOD, base_, i, k, ra, ci); continue; } case OpCode.OP_POW: { arith_op(L, luai_numpow, TMS.TM_POW, base_, i, k, ra, ci); continue; } case OpCode.OP_UNM: { TValue rb = RB(L, base_, i); if (ttisnumber(rb)) { lua_Number nb = nvalue(rb); setnvalue(ra, luai_numunm(L, nb)); } else { //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: luaV_arith(L, ra, rb, rb, TMS.TM_UNM); base_ = ci.u.l.base_; //); //L.savedpc = InstructionPtr.Assign(pc);//FIXME:??? } continue; } case OpCode.OP_NOT: { int res = l_isfalse(RB(L, base_, i)) == 0 ? 0 : 1; /* next assignment may change this value */ setbvalue(ra, res); continue; } case OpCode.OP_LEN: { //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: objlen(L, ra, RB(L, base_, i)); base_ = ci.u.l.base_; //FIXME:??? //) continue; } case OpCode.OP_CONCAT: { int b = GETARG_B(i); int c = GETARG_C(i); L.top = base_ + c + 1; /* mark the end of concat operands */ //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: luaV_concat(L, c - b + 1); luaC_checkGC(L); base_ = ci.u.l.base_; //); L.top = ci.top; /* restore top */ setobjs2s(L, RA(L, base_, i), base_ + b); continue; } case OpCode.OP_JMP: { dojump(GETARG_sBx(i), ci, L); continue; } case OpCode.OP_EQ: { TValue rb = RKB(L, base_, i, k); TValue rc = RKC(L, base_, i, k); //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: if (equalobj(L, rb, rc) == GETARG_A(i)) { dojump(GETARG_sBx(ci.u.l.savedpc[0]), ci, L); } base_ = ci.u.l.base_; //); InstructionPtr.inc(ref ci.u.l.savedpc); continue; } case OpCode.OP_LT: { //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: if (luaV_lessthan(L, RKB(L, base_, i, k), RKC(L, base_, i, k)) == GETARG_A(i)) { dojump(GETARG_sBx(ci.u.l.savedpc[0]), ci, L); } base_ = ci.u.l.base_; //); InstructionPtr.inc(ref ci.u.l.savedpc); continue; } case OpCode.OP_LE: { //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: if (luaV_lessequal(L, RKB(L, base_, i, k), RKC(L, base_, i, k)) == GETARG_A(i)) { dojump(GETARG_sBx(ci.u.l.savedpc[0]), ci, L); } base_ = ci.u.l.base_; //); InstructionPtr.inc(ref ci.u.l.savedpc); continue; } case OpCode.OP_TEST: { if (GETARG_C(i) != 0 ? l_isfalse(ra) == 0 : l_isfalse(ra) != 0) { dojump(GETARG_sBx(ci.u.l.savedpc[0]), ci, L); } InstructionPtr.inc(ref ci.u.l.savedpc); continue; } case OpCode.OP_TESTSET: { TValue rb = RB(L, base_, i); if (GETARG_C(i) != 0 ? l_isfalse(rb) == 0 : l_isfalse(rb) != 0) { setobjs2s(L, ra, rb); dojump(GETARG_sBx(ci.u.l.savedpc[0]), ci, L); } InstructionPtr.inc(ref ci.u.l.savedpc); continue; } case OpCode.OP_CALL: { int b = GETARG_B(i); int nresults = GETARG_C(i) - 1; if (b != 0) { L.top = ra + b; /* else previous instruction set top */ } if (luaD_precall(L, ra, nresults) != 0) /* C function? */ { if (nresults >= 0) { L.top = ci.top; /* adjust results */ } base_ = ci.u.l.base_; continue; } else /* Lua function */ { ci = L.ci; ci.callstatus |= CIST_REENTRY; break; /* restart luaV_execute over new Lua function */ } } case OpCode.OP_TAILCALL: { int b = GETARG_B(i); if (b != 0) { L.top = ra + b; /* else previous instruction set top */ } lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); if (luaD_precall(L, ra, LUA_MULTRET) != 0) /* C function? */ { base_ = ci.u.l.base_; continue; } else { /* tail call: put called frame (n) in place of caller one (o) */ CallInfo nci = L.ci; /* called frame */ CallInfo oci = nci.previous; /* caller frame */ StkId nfunc = nci.func; /* called function index */ StkId ofunc = oci.func; int aux; if (cl.p.sizep > 0) { luaF_close(L, oci.u.l.base_); } oci.u.l.base_ = ofunc + (nci.u.l.base_ - nfunc); for (aux = 0; nfunc + aux < L.top; aux++) /* move frame down */ { setobjs2s(L, ofunc + aux, nfunc + aux); } oci.top = L.top = ofunc + aux; /* correct top */ lua_assert(L.top == oci.u.l.base_ + clvalue(ofunc).l.p.maxstacksize); oci.u.l.savedpc = nci.u.l.savedpc; oci.u.l.tailcalls++; /* one more call lost */ ci = L.ci = oci; /* remove new frame */ break; /* restart luaV_execute over new Lua function */ } } case OpCode.OP_RETURN: { int b = GETARG_B(i); if (b != 0) { L.top = ra + b - 1; } if (cl.p.sizep > 0) { luaF_close(L, base_); } b = luaD_poscall(L, ra); if ((ci.callstatus & CIST_REENTRY) == 0) /* 'ci' still the called one */ { return; /* external invocation: return */ } else /* invocation via reentry: continue execution */ { ci = L.ci; if (b != 0) { L.top = ci.top; } lua_assert(isLua(ci)); lua_assert(GET_OPCODE(ci.u.l.savedpc[-1]) == OpCode.OP_CALL); break; /* restart luaV_execute over new Lua function */ } } case OpCode.OP_FORLOOP: { lua_Number step = nvalue(ra + 2); lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ lua_Number limit = nvalue(ra + 1); if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) : luai_numle(L, limit, idx)) { dojump(GETARG_sBx(i), ci, L); /* jump back */ setnvalue(ra, idx); /* update internal index... */ setnvalue(ra + 3, idx); /* ...and external index */ } continue; } case OpCode.OP_FORPREP: { TValue init = ra; TValue plimit = ra + 1; TValue pstep = ra + 2; if (tonumber(ref init, ra) == 0) { luaG_runerror(L, LUA_QL("for") + " initial value must be a number"); } else if (tonumber(ref plimit, ra + 1) == 0) { luaG_runerror(L, LUA_QL("for") + " limit must be a number"); } else if (tonumber(ref pstep, ra + 2) == 0) { luaG_runerror(L, LUA_QL("for") + " step must be a number"); } setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); dojump(GETARG_sBx(i), ci, L); continue; } case OpCode.OP_TFORCALL: { StkId cb = ra + 3; /* call base */ setobjs2s(L, cb + 2, ra + 2); setobjs2s(L, cb + 1, ra + 1); setobjs2s(L, cb, ra); L.top = cb + 3; /* func. + 2 args (state and index) */ //Protect( //L.savedpc = InstructionPtr.Assign(pc);//FIXME: luaD_call(L, cb, GETARG_C(i), 1); base_ = ci.u.l.base_; //); L.top = ci.top; i = ci.u.l.savedpc[0]; InstructionPtr.inc(ref ci.u.l.savedpc); /* go to next instruction */ //FIXME:++ ra = RA(L, base_, i); lua_assert(GET_OPCODE(i) == OpCode.OP_TFORLOOP); /* go through */ goto case OpCode.OP_TFORLOOP; //FIXME:added } case OpCode.OP_TFORLOOP: { if (!ttisnil(ra + 1)) /* continue loop? */ { setobjs2s(L, ra, ra + 1); /* save control variable */ dojump(GETARG_sBx(i), ci, L); /* jump back */ } continue; } case OpCode.OP_SETLIST: { int n = GETARG_B(i); int c = GETARG_C(i); int last; Table h; if (n == 0) { n = cast_int(L.top - ra) - 1; } if (c == 0) { lua_assert(GET_OPCODE(ci.u.l.savedpc[0]) == OpCode.OP_EXTRAARG); c = GETARG_Ax(ci.u.l.savedpc[0]); InstructionPtr.inc(ref ci.u.l.savedpc); //FIXME:++ } h = hvalue(ra); last = ((c - 1) * LFIELDS_PER_FLUSH) + n; if (last > h.sizearray) /* needs more space? */ { luaH_resizearray(L, h, last); /* pre-alloc it at once */ } for (; n > 0; n--) { TValue val = ra + n; setobj2t(L, luaH_setnum(L, h, last--), val); luaC_barriert(L, h, val); } L.top = ci.top; /* correct top (in case of previous open call) */ continue; } case OpCode.OP_CLOSE: { luaF_close(L, ra); continue; } case OpCode.OP_CLOSURE: { Proto p; Closure ncl; int nup, j; p = cl.p.p[GETARG_Bx(i)]; nup = p.nups; ncl = luaF_newLclosure(L, nup, cl.env); ncl.l.p = p; setclvalue(L, ra, ncl); for (j = 0; j < nup; j++) { Instruction u = ci.u.l.savedpc[0]; InstructionPtr.inc(ref ci.u.l.savedpc); if (GET_OPCODE(u) == OpCode.OP_GETUPVAL) { ncl.l.upvals[j] = cl.upvals[GETARG_B(u)]; } else { lua_assert(GET_OPCODE(u) == OpCode.OP_MOVE); ncl.l.upvals[j] = luaF_findupval(L, base_ + GETARG_B(u)); } } //Protect( //L.savedpc = InstructionPtr.Assign(pc);//FIXME: luaC_checkGC(L); base_ = ci.u.l.base_; //); continue; } case OpCode.OP_VARARG: { int b = GETARG_B(i) - 1; int j; int n = cast_int(base_ - ci.func) - cl.p.numparams - 1; if (b == LUA_MULTRET) { //Protect( //L.savedpc = InstructionPtr.Assign(pc);//FIXME: luaD_checkstack(L, n); base_ = ci.u.l.base_; //); ra = RA(L, base_, i); /* previous call may change the stack */ b = n; L.top = ra + n; } for (j = 0; j < b; j++) { if (j < n) { setobjs2s(L, ra + j, base_ - n + j); } else { setnilvalue(ra + j); } } continue; } case OpCode.OP_EXTRAARG: { luaG_runerror(L, "bad opcode"); return; } } /* function changed (call/return): update pointers */ lua_assert(ci == L.ci); cl = clvalue(ci.func).l; k = cl.p.k; base_ = ci.u.l.base_; } }
private static void unlinkupval (UpVal uv) { lua_assert(uv.u.l.next.u.l.prev == uv && uv.u.l.prev.u.l.next == uv); uv.u.l.next.u.l.prev = uv.u.l.prev; /* remove from `uvhead' list */ uv.u.l.prev.u.l.next = uv.u.l.next; }
public void set(UpVal val) { this._upVals[this._index] = val; }
public static bool upisopen(UpVal up) { return(up.v != up.u.value_); }