public LuaTypeValue(LuaTypeValue copy) { this.values = copy.values; this.index = copy.index; this.value.Copy(copy.value); this.tt = copy.tt; }
public static void LuaGArithError(LuaState L, TValue p1, TValue p2) { TValue temp = new LuaTypeValue(); if (luaV_tonumber(p1, temp) == null) p2 = p1; /* first operand is wrong */ LuaGTypeError(L, p2, "perform arithmetic on"); }
public static void Arith(LuaState L, StkId ra, TValue rb, TValue rc, TMS op) { TValue tempb = new LuaTypeValue(), tempc = new LuaTypeValue(); TValue b, c; if ((b = luaV_tonumber(rb, tempb)) != null && (c = luaV_tonumber(rc, tempc)) != null) { lua_Number nb = NValue(b), nc = NValue(c); switch (op) { case TMS.TM_ADD: SetNValue(ra, luai_numadd(nb, nc)); break; case TMS.TM_SUB: SetNValue(ra, luai_numsub(nb, nc)); break; case TMS.TM_MUL: SetNValue(ra, luai_nummul(nb, nc)); break; case TMS.TM_DIV: SetNValue(ra, luai_numdiv(nb, nc)); break; case TMS.TM_MOD: SetNValue(ra, luai_nummod(nb, nc)); break; case TMS.TM_POW: SetNValue(ra, luai_numpow(nb, nc)); break; case TMS.TM_UNM: SetNValue(ra, luai_numunm(nb)); break; default: LuaAssert(false); break; } } else if (call_binTM(L, rb, rc, ra, op) == 0) { LuaGArithError(L, rb, rc); } }
public static int LuaKStringK(FuncState fs, TString s) { TValue o = new LuaTypeValue(); SetSValue(fs.L, o, s); return(AddK(fs, o, o)); }
private static int BoolValueK(FuncState fs, int b) { TValue o = new LuaTypeValue(); SetBValue(o, b); return(AddK(fs, o, o)); }
public static int LuaKNumberK(FuncState fs, LuaNumberType r) { TValue o = new LuaTypeValue(); SetNValue(o, r); return(AddK(fs, o, o)); }
public static int LuaIsNumber(LuaState L, int idx) { TValue n = new LuaTypeValue(); TValue o = Index2Address(L, idx); return(tonumber(ref o, n)); }
private static int NilK(FuncState fs) { TValue k = new LuaTypeValue(), v = new LuaTypeValue(); 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)); }
public static void LuaGArithError(LuaState L, TValue p1, TValue p2) { TValue temp = new LuaTypeValue(); if (luaV_tonumber(p1, temp) == null) { p2 = p1; /* first operand is wrong */ } LuaGTypeError(L, p2, "perform arithmetic on"); }
public static void LuaGetField(LuaState L, int idx, CharPtr k) { StkId t; TValue key = new LuaTypeValue(); LuaLock(L); t = Index2Address(L, idx); CheckValidIndex(L, t); SetSValue(L, key, luaS_new(L, k)); luaV_gettable(L, t, key, L.top); IncrementTop(L); LuaUnlock(L); }
public static void LuaSetField(LuaState L, int idx, CharPtr k) { StkId t; TValue key = new LuaTypeValue(); LuaLock(L); CheckNElements(L, 1); t = Index2Address(L, idx); CheckValidIndex(L, t); SetSValue(L, key, luaS_new(L, k)); luaV_settable(L, t, key, L.top - 1); StkId.Dec(ref L.top); /* pop value */ LuaUnlock(L); }
public static lua_Number LuaToNumber(LuaState L, int idx) { TValue n = new LuaTypeValue(); TValue o = Index2Address(L, idx); if (tonumber(ref o, n) != 0) { return(NValue(o)); } else { return(0); } }
public static TValue luaH_setnum(LuaState L, Table t, int key) { TValue p = luaH_getnum(t, key); if (p != LuaONilObject) { return((TValue)p); } else { TValue k = new LuaTypeValue(); SetNValue(k, CastNum(key)); return(newkey(L, t, k)); } }
public static TValue luaH_setstr(LuaState L, Table t, TString key) { TValue p = luaH_getstr(t, key); if (p != LuaONilObject) { return((TValue)p); } else { TValue k = new LuaTypeValue(); SetSValue(L, k, key); return(newkey(L, t, k)); } }
public static CharPtr LuaGetUpValue(LuaState L, int funcindex, int n) { CharPtr name; TValue val = new LuaTypeValue(); LuaLock(L); name = AuxUpValue(Index2Address(L, funcindex), n, ref val); if (name != null) { SetObj2S(L, L.top, val); IncrementTop(L); } LuaUnlock(L); return(name); }
public static lua_Integer LuaToInteger(LuaState L, int idx) { TValue n = new LuaTypeValue(); TValue o = Index2Address(L, idx); if (tonumber(ref o, n) != 0) { lua_Integer res; lua_Number num = NValue(o); lua_number2integer(out res, num); return(res); } else { return(0); } }
public static CharPtr LuaSetUpValue(LuaState L, int funcindex, int n) { CharPtr name; TValue val = new LuaTypeValue(); StkId fi; LuaLock(L); fi = Index2Address(L, funcindex); CheckNElements(L, 1); name = AuxUpValue(fi, n, ref val); if (name != null) { StkId.Dec(ref L.top); SetObj(L, val, L.top); LuaCBarrier(L, CLValue(fi), L.top); } LuaUnlock(L); return(name); }
public static void Arith(LuaState L, StkId ra, TValue rb, TValue rc, TMS op) { TValue tempb = new LuaTypeValue(), tempc = new LuaTypeValue(); TValue b, c; if ((b = luaV_tonumber(rb, tempb)) != null && (c = luaV_tonumber(rc, tempc)) != null) { lua_Number nb = NValue(b), nc = NValue(c); switch (op) { case TMS.TM_ADD: SetNValue(ra, luai_numadd(nb, nc)); break; case TMS.TM_SUB: SetNValue(ra, luai_numsub(nb, nc)); break; case TMS.TM_MUL: SetNValue(ra, luai_nummul(nb, nc)); break; case TMS.TM_DIV: SetNValue(ra, luai_numdiv(nb, nc)); break; case TMS.TM_MOD: SetNValue(ra, luai_nummod(nb, nc)); break; case TMS.TM_POW: SetNValue(ra, luai_numpow(nb, nc)); break; case TMS.TM_UNM: SetNValue(ra, luai_numunm(nb)); break; default: LuaAssert(false); break; } } else if (call_binTM(L, rb, rc, ra, op) == 0) LuaGArithError(L, rb, rc); }
public static void luaV_settable(LuaState L, TValue t, TValue key, StkId val) { int loop; TValue temp = new LuaTypeValue(); for (loop = 0; loop < MAXTAGLOOP; loop++) { TValue tm; if (TTIsTable(t)) /* `t' is a table? */ { Table h = HValue(t); TValue oldval = luaH_set(L, h, key); /* do a primitive set */ if (!TTIsNil(oldval) || /* result is no nil? */ (tm = fasttm(L, h.metatable, TMS.TM_NEWINDEX)) == null) /* or no TM? */ { SetObj2T(L, oldval, val); h.flags = 0; LuaCBarrierT(L, h, val); return; } /* else will try the tag method */ } else if (TTIsNil(tm = luaT_gettmbyobj(L, t, TMS.TM_NEWINDEX))) { LuaGTypeError(L, t, "index"); } if (TTIsFunction(tm)) { callTM(L, tm, t, key, val); return; } /* else repeat with `tm' */ SetObj(L, temp, tm); /* avoid pointing inside table (may rehash) */ t = temp; } LuaGRunError(L, "loop in settable"); }
public static void luaV_settable (LuaState L, TValue t, TValue key, StkId val) { int loop; TValue temp = new LuaTypeValue(); for (loop = 0; loop < MAXTAGLOOP; loop++) { TValue tm; if (TTIsTable(t)) { /* `t' is a table? */ Table h = HValue(t); TValue oldval = luaH_set(L, h, key); /* do a primitive set */ if (!TTIsNil(oldval) || /* result is no nil? */ (tm = fasttm(L, h.metatable, TMS.TM_NEWINDEX)) == null) { /* or no TM? */ SetObj2T(L, oldval, val); h.flags = 0; LuaCBarrierT(L, h, val); return; } /* else will try the tag method */ } else if (TTIsNil(tm = luaT_gettmbyobj(L, t, TMS.TM_NEWINDEX))) LuaGTypeError(L, t, "index"); if (TTIsFunction(tm)) { callTM(L, tm, t, key, val); return; } /* else repeat with `tm' */ SetObj (L, temp, tm); /* avoid pointing inside table (may rehash) */ t = temp; } LuaGRunError(L, "loop in settable"); }
public static void luaV_execute(LuaState L, int nexeccalls) { LClosure cl; StkId base_; TValue[] k; /*const*/ InstructionPtr pc; reentry: /* entry point */ LuaAssert(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); LuaAssert(base_ == L.base_ && L.base_ == L.ci.base_); LuaAssert(base_ <= L.top && ((L.top - L.stack) <= L.stacksize)); LuaAssert(L.top == L.ci.top || (LuaGCheckOpenOp(i) != 0)); //Dump(pc.pc, i); switch (GET_OPCODE(i)) { case OpCode.OP_MOVE: { SetObj2S(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 LuaTypeValue(); TValue rb = KBx(L, i, k); SetHValue(L, g, cl.env); LuaAssert(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 LuaTypeValue(); SetHValue(L, g, cl.env); LuaAssert(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); LuaCBarrier(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, LuaOFBInt(b), LuaOFBInt(c))); //Protect( L.savedpc = InstructionPtr.Assign(pc); LuaCCheckGC(L); base_ = L.base_; //); L.savedpc = InstructionPtr.Assign(pc); continue; } case OpCode.OP_SELF: { StkId rb = RB(L, base_, i); SetObj2S(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 = LIsFalse(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, LuaONilObject, ra, TMS.TM_LEN) == 0) { LuaGTypeError(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); LuaCCheckGC(L); base_ = L.base_; //); SetObj2S(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 (LIsFalse(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 (LIsFalse(rb) != GETARG_C(i)) { SetObj2S(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 (LuaDPreCall(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); LuaAssert(GETARG_C(i) - 1 == LUA_MULTRET); switch (LuaDPreCall(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) { LuaFClose(L, ci.base_); } L.base_ = ci.base_ = ci.func + (ci[1].base_ - pfunc); for (aux = 0; pfunc + aux < L.top; aux++) /* move frame down */ { SetObj2S(L, func + aux, pfunc + aux); } ci.top = L.top = func + aux; /* correct top */ LuaAssert(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) { LuaFClose(L, base_); } L.savedpc = InstructionPtr.Assign(pc); b = LuaDPosCall(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; } LuaAssert(IsLua(L.ci)); LuaAssert(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) { LuaGRunError(L, LUA_QL("for") + " initial value must be a number"); } else if (tonumber(ref plimit, ra + 1) == 0) { LuaGRunError(L, LUA_QL("for") + " limit must be a number"); } else if (tonumber(ref pstep, ra + 2) == 0) { LuaGRunError(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 */ SetObj2S(L, cb + 2, ra + 2); SetObj2S(L, cb + 1, ra + 1); SetObj2S(L, cb, ra); L.top = cb + 3; /* func. + 2 args (state and index) */ //Protect( L.savedpc = InstructionPtr.Assign(pc); LuaDCall(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? */ { SetObj2S(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 = CastInt(L.top - ra) - 1; L.top = L.ci.top; } if (c == 0) { c = CastInt(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); LuaCBarrierT(L, h, val); } continue; } case OpCode.OP_CLOSE: { LuaFClose(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 = LuaFNewLClosure(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 { LuaAssert(GET_OPCODE(pc[0]) == OpCode.OP_MOVE); ncl.l.upvals[j] = LuaFindUpVal(L, base_ + GETARG_B(pc[0])); } } SetCLValue(L, ra, ncl); //Protect( L.savedpc = InstructionPtr.Assign(pc); LuaCCheckGC(L); base_ = L.base_; //); continue; } case OpCode.OP_VARARG: { int b = GETARG_B(i) - 1; int j; CallInfo ci = L.ci; int n = CastInt(ci.base_ - ci.func) - cl.p.numparams - 1; if (b == LUA_MULTRET) { //Protect( L.savedpc = InstructionPtr.Assign(pc); LuaDCheckStack(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) { SetObj2S(L, ra + j, ci.base_ - n + j); } else { SetNilValue(ra + j); } } continue; } } } }
public static lua_Number LuaToNumber(LuaState L, int idx) { TValue n = new LuaTypeValue(); TValue o = Index2Address(L, idx); if (tonumber(ref o, n) != 0) return NValue(o); else return 0; }
public static lua_Integer LuaToInteger(LuaState L, int idx) { TValue n = new LuaTypeValue(); TValue o = Index2Address(L, idx); if (tonumber(ref o, n) != 0) { lua_Integer res; lua_Number num = NValue(o); lua_number2integer(out res, num); return res; } else return 0; }
public static CharPtr LuaSetUpValue(LuaState L, int funcindex, int n) { CharPtr name; TValue val = new LuaTypeValue(); StkId fi; LuaLock(L); fi = Index2Address(L, funcindex); CheckNElements(L, 1); name = AuxUpValue(fi, n, ref val); if (name != null) { StkId.Dec(ref L.top); SetObj(L, val, L.top); LuaCBarrier(L, CLValue(fi), L.top); } LuaUnlock(L); return name; }
private static int BoolValueK (FuncState fs, int b) { TValue o = new LuaTypeValue(); SetBValue(o, b); return AddK(fs, o, o); }
public static LuaTypeValue Dec(ref LuaTypeValue value) { value = value[-1]; return(value[1]); }
public static TValue luaH_setnum (LuaState L, Table t, int key) { TValue p = luaH_getnum(t, key); if (p != LuaONilObject) return (TValue)p; else { TValue k = new LuaTypeValue(); SetNValue(k, CastNum(key)); return newkey(L, t, k); } }
public static TValue luaH_setstr (LuaState L, Table t, TString key) { TValue p = luaH_getstr(t, key); if (p != LuaONilObject) return (TValue)p; else { TValue k = new LuaTypeValue(); SetSValue(L, k, key); return newkey(L, t, k); } }
public static void luaV_execute (LuaState L, int nexeccalls) { LClosure cl; StkId base_; TValue[] k; /*const*/ InstructionPtr pc; reentry: /* entry point */ LuaAssert(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); LuaAssert(base_ == L.base_ && L.base_ == L.ci.base_); LuaAssert(base_ <= L.top && ((L.top - L.stack) <= L.stacksize)); LuaAssert(L.top == L.ci.top || (LuaGCheckOpenOp(i)!=0)); //Dump(pc.pc, i); switch (GET_OPCODE(i)) { case OpCode.OP_MOVE: { SetObj2S(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 LuaTypeValue(); TValue rb = KBx(L, i, k); SetHValue(L, g, cl.env); LuaAssert(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 LuaTypeValue(); SetHValue(L, g, cl.env); LuaAssert(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); LuaCBarrier(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, LuaOFBInt(b), LuaOFBInt(c))); //Protect( L.savedpc = InstructionPtr.Assign(pc); LuaCCheckGC(L); base_ = L.base_; //); L.savedpc = InstructionPtr.Assign(pc); continue; } case OpCode.OP_SELF: { StkId rb = RB(L, base_, i); SetObj2S(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 = LIsFalse(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, LuaONilObject, ra, TMS.TM_LEN) == 0) LuaGTypeError(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); LuaCCheckGC(L); base_ = L.base_; //); SetObj2S(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 (LIsFalse(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 (LIsFalse(rb) != GETARG_C(i)) { SetObj2S(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 (LuaDPreCall(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); LuaAssert(GETARG_C(i) - 1 == LUA_MULTRET); switch (LuaDPreCall(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) LuaFClose(L, ci.base_); L.base_ = ci.base_ = ci.func + (ci[1].base_ - pfunc); for (aux = 0; pfunc+aux < L.top; aux++) /* move frame down */ SetObj2S(L, func+aux, pfunc+aux); ci.top = L.top = func+aux; /* correct top */ LuaAssert(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) LuaFClose(L, base_); L.savedpc = InstructionPtr.Assign(pc); b = LuaDPosCall(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; LuaAssert(IsLua(L.ci)); LuaAssert(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) LuaGRunError(L, LUA_QL("for") + " initial value must be a number"); else if (tonumber(ref plimit, ra+1) == 0) LuaGRunError(L, LUA_QL("for") + " limit must be a number"); else if (tonumber(ref pstep, ra+2) == 0) LuaGRunError(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 */ SetObj2S(L, cb+2, ra+2); SetObj2S(L, cb+1, ra+1); SetObj2S(L, cb, ra); L.top = cb+3; /* func. + 2 args (state and index) */ //Protect( L.savedpc = InstructionPtr.Assign(pc); LuaDCall(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? */ SetObj2S(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 = CastInt(L.top - ra) - 1; L.top = L.ci.top; } if (c == 0) { c = CastInt(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); LuaCBarrierT(L, h, val); } continue; } case OpCode.OP_CLOSE: { LuaFClose(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 = LuaFNewLClosure(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 { LuaAssert(GET_OPCODE(pc[0]) == OpCode.OP_MOVE); ncl.l.upvals[j] = LuaFindUpVal(L, base_ + GETARG_B(pc[0])); } } SetCLValue(L, ra, ncl); //Protect( L.savedpc = InstructionPtr.Assign(pc); LuaCCheckGC(L); base_ = L.base_; //); continue; } case OpCode.OP_VARARG: { int b = GETARG_B(i) - 1; int j; CallInfo ci = L.ci; int n = CastInt(ci.base_ - ci.func) - cl.p.numparams - 1; if (b == LUA_MULTRET) { //Protect( L.savedpc = InstructionPtr.Assign(pc); LuaDCheckStack(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) { SetObj2S(L, ra + j, ci.base_ - n + j); } else { SetNilValue(ra + j); } } continue; } } } }
public static int LuaKStringK (FuncState fs, TString s) { TValue o = new LuaTypeValue(); SetSValue(fs.L, o, s); return AddK(fs, o, o); }
public static LuaTypeValue Inc(ref LuaTypeValue value) { value = value[1]; return value[-1]; }
public static int LuaKNumberK (FuncState fs, LuaNumberType r) { TValue o = new LuaTypeValue(); SetNValue(o, r); return AddK(fs, o, o); }
public static CharPtr LuaGetUpValue(LuaState L, int funcindex, int n) { CharPtr name; TValue val = new LuaTypeValue(); LuaLock(L); name = AuxUpValue(Index2Address(L, funcindex), n, ref val); if (name != null) { SetObj2S(L, L.top, val); IncrementTop(L); } LuaUnlock(L); return name; }
private static int NilK (FuncState fs) { TValue k = new LuaTypeValue(), v = new LuaTypeValue(); 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); }
public static int LuaIsNumber(LuaState L, int idx) { TValue n = new LuaTypeValue(); TValue o = Index2Address(L, idx); return tonumber(ref o, n); }