public static UpVal luaF_findupval (LuaState L, StkId level) { GlobalState g = G(L); GCObjectRef pp = new OpenValRef(L); UpVal p; UpVal uv; while (pp.get() != null && (p = ngcotouv(pp.get())).v >= level) { lua_assert(p.v != p.u.value); if (p.v == level) { /* found a corresponding upvalue? */ if (isdead(g, obj2gco(p))) /* is it dead? */ changewhite(obj2gco(p)); /* ressurect it */ return p; } pp = new NextRef(p); } uv = luaM_new<UpVal>(L); /* not found: create a new one */ uv.tt = LUA_TUPVAL; uv.marked = luaC_white(g); uv.v = level; /* current value lives in the stack */ uv.next = pp.get(); /* chain it in the proper position */ pp.set( obj2gco(uv) ); uv.u.l.prev = g.uvhead; /* double link it in `uvhead' list */ uv.u.l.next = g.uvhead.u.l.next; uv.u.l.next.u.l.prev = uv; g.uvhead.u.l.next = uv; lua_assert(uv.u.l.next.u.l.prev == uv && uv.u.l.prev.u.l.next == uv); return uv; }
public static int luaV_tostring (LuaState L, StkId obj) { if (!TTIsNumber(obj)) return 0; else { lua_Number n = NValue(obj); CharPtr s = lua_number2str(n); SetSValue2S(L, obj, luaS_new(L, s)); return 1; } }
public static int luaV_tostring (lua_State L, StkId obj) { if (!ttisnumber(obj)) return 0; else { lua_Number n = nvalue(obj); CharPtr s = lua_number2str(n); setsvalue2s(L, obj, luaS_new(L, s)); return 1; } }
private static void callTMres (lua_State L, StkId res, TValue f, TValue p1, TValue p2) { ptrdiff_t result = savestack(L, res); setobj2s(L, L.top, f); /* push function */ setobj2s(L, L.top+1, p1); /* 1st argument */ setobj2s(L, L.top+2, p2); /* 2nd argument */ luaD_checkstack(L, 3); L.top += 3; luaD_call(L, L.top-3, 1); res = restorestack(L, result); StkId.dec(ref L.top); setobjs2s(L, res, L.top); }
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 luaD_precall(LuaState L, StkId func, int nresults) { LClosure cl; ptrdiff_t funcr; if (!ttisfunction(func)) /* `func' is not a function? */ { func = tryfuncTM(L, func); /* check the `function' tag method */ } funcr = savestack(L, func); cl = clvalue(func).l; L.ci.savedpc = InstructionPtr.Assign(L.savedpc); if (cl.isC == 0) { /* Lua function? prepare its call */ CallInfo ci; StkId st, base_; Proto p = cl.p; luaD_checkstack(L, p.maxstacksize); func = restorestack(L, funcr); if (p.is_vararg == 0) { /* no varargs? */ base_ = L.stack[func + 1]; if (L.top > base_ + p.numparams) { L.top = base_ + p.numparams; } } else { /* vararg function */ int nargs = L.top - func - 1; base_ = adjust_varargs(L, p, nargs); func = restorestack(L, funcr); /* previous call may change the stack */ } ci = inc_ci(L); /* now `enter' new function */ ci.func = func; L.base_ = ci.base_ = base_; ci.top = L.base_ + p.maxstacksize; lua_assert(ci.top <= L.stack_last); L.savedpc = new InstructionPtr(p.code, 0); /* starting point */ ci.tailcalls = 0; ci.nresults = nresults; for (st = L.top; st < ci.top; StkId.inc(ref st)) { setnilvalue(st); } L.top = ci.top; if ((L.hookmask & LUA_MASKCALL) != 0) { InstructionPtr.inc(ref L.savedpc); /* hooks assume 'pc' is already incremented */ luaD_callhook(L, LUA_HOOKCALL, -1); InstructionPtr.dec(ref L.savedpc); /* correct 'pc' */ } return(PCRLUA); } else { /* if is a C function, call it */ CallInfo ci; int n; luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ ci = inc_ci(L); /* now `enter' new function */ ci.func = restorestack(L, funcr); L.base_ = ci.base_ = ci.func + 1; ci.top = L.top + LUA_MINSTACK; lua_assert(ci.top <= L.stack_last); ci.nresults = nresults; if ((L.hookmask & LUA_MASKCALL) != 0) { luaD_callhook(L, LUA_HOOKCALL, -1); } lua_unlock(L); n = curr_func(L).c.f(L); /* do the actual call */ lua_lock(L); if (n < 0) /* yielding? */ { return(PCRYIELD); } else { luaD_poscall(L, L.top - n); return(PCRC); } } }
/* ** access functions (stack . C) */ public static int LinyeeType(LinyeeState L, int idx) { StkId o = Index2Address(L, idx); return((o == LinyeeONilObject) ? LINYEE_TNONE : TType(o)); }
public static void LuaGConcatError (LuaState L, StkId p1, StkId p2) { if (TTIsString(p1) || TTIsNumber(p1)) p1 = p2; LuaAssert(!TTIsString(p1) && !TTIsNumber(p1)); LuaGTypeError(L, p1, "concatenate"); }
public static void incr_top(LuaState L) { luaD_checkstack(L, 1); StkId.inc(ref L.top); }
public static int LuaDPosCall(LuaState L, StkId firstResult) { StkId res; int wanted, i; CallInfo ci; if ((L.hookmask & LUA_MASKRET) != 0) firstResult = CallRetHooks(L, firstResult); ci = CallInfo.Dec(ref L.ci); res = ci.func; /* res == final position of 1st result */ wanted = ci.nresults; L.base_ = (ci - 1).base_; /* restore base */ L.savedpc = InstructionPtr.Assign((ci - 1).savedpc); /* restore savedpc */ /* move results to correct place */ for (i = wanted; i != 0 && firstResult < L.top; i--) { SetObj2S(L, res, firstResult); res = res + 1; firstResult = firstResult + 1; } while (i-- > 0) SetNilValue(StkId.Inc(ref res)); L.top = res; return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ }
private static StkId CallRetHooks(LuaState L, StkId firstResult) { ptrdiff_t fr = SaveStack(L, firstResult); /* next call may change stack */ LuaDCallHook(L, LUA_HOOKRET, -1); if (FIsLua(L.ci)) { /* Lua function? */ while (((L.hookmask & LUA_MASKRET) != 0) && (L.ci.tailcalls-- != 0)) /* tail calls */ LuaDCallHook(L, LUA_HOOKTAILRET, -1); } return RestoreStack(L, fr); }
/* ** access functions (stack . C) */ public static int lua_type(lua_State L, int idx) { StkId o = index2adr(L, idx); return((o == luaO_nilobject) ? LUA_TNONE : ttype(o)); }
public static bool lua_iscfunction(lua_State L, int idx) { StkId o = index2adr(L, idx); return(iscfunction(o)); }
public static LinyeeNativeFunction LinyeeToCFunction(LinyeeState L, int idx) { StkId o = Index2Address(L, idx); return((!IsCFunction(o)) ? null : CLValue(o).c.f); }
public static LinyeeState LinyeeToThread(LinyeeState L, int idx) { StkId o = Index2Address(L, idx); return((!TTIsThread(o)) ? null : THValue(o)); }
public static void IncrementTop(LinyeeState L) { ApiCheck(L, L.top < L.ci.top); StkId.Inc(ref L.top); }
public static void CheckValidIndex(LinyeeState L, StkId i) { ApiCheck(L, i != LinyeeONilObject); }
public static bool LinyeeIsCFunction(LinyeeState L, int idx) { StkId o = Index2Address(L, idx); return(IsCFunction(o)); }
internal static TValue RKC(LuaState L, StkId base_, Instruction i, TValue[] k) { return ISK(GETARG_C(i)) != 0 ? k[INDEXK(GETARG_C(i))] : base_ + GETARG_C(i); }
public static void api_checkvalidindex(lua_State L, StkId i) { api_check(L, i != luaO_nilobject); }
// in the original C code these values save and restore the stack by number of bytes. marshalling sizeof // isn't that straightforward in managed languages, so i implement these by index instead. public static int savestack(LuaState L, StkId p) { return(p); }
public static lua_CFunction lua_tocfunction(lua_State L, int idx) { StkId o = index2adr(L, idx); return((!iscfunction(o)) ? null : clvalue(o).c.f); }
public static void LuaDSetErrorObj(LuaState L, int errcode, StkId oldtop) { switch (errcode) { case LUA_ERRMEM: { SetSValue2S(L, oldtop, luaS_newliteral(L, MEMERRMSG)); break; } case LUA_ERRERR: { SetSValue2S(L, oldtop, luaS_newliteral(L, "error in error handling")); break; } case LUA_ERRSYNTAX: case LUA_ERRRUN: { SetObj2S(L, oldtop, L.top - 1); /* error message on current top */ break; } } L.top = oldtop + 1; }
/* ** returns true if function has been executed (C function) */ public static int luaD_precall(lua_State L, StkId func, int nresults) { lua_CFunction f; CallInfo ci; int n; /* number of arguments (Lua) or returns (C) */ ptrdiff_t funcr = savestack(L, func); switch (ttype(func)) { case LUA_TLCF: /* light C function */ f = fvalue(func); //goto Cfunc; //FIXME:removed, see below luaC_checkGC(L); /* stack grow uses memory */ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ ci = next_ci(L); /* now 'enter' new function */ ci.nresults = (short)nresults; //FIXME:added, (short) ci.func = restorestack(L, funcr); ci.top = L.top + LUA_MINSTACK; lua_assert(ci.top <= L.stack_last); ci.callstatus = 0; if ((L.hookmask & LUA_MASKCALL) != 0) { luaD_hook(L, LUA_HOOKCALL, -1); } lua_unlock(L); n = f(L); /* do the actual call */ lua_lock(L); api_checknelems(L, n); luaD_poscall(L, L.top - n, n); return(1); case LUA_TCCL: { /* C closure */ f = clCvalue(func).f; //Cfunc: //FIXME:removed, see upper luaC_checkGC(L); /* stack grow uses memory */ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ ci = next_ci(L); /* now 'enter' new function */ ci.nresults = (short)nresults; //FIXME:added, (short) ci.func = restorestack(L, funcr); ci.top = L.top + LUA_MINSTACK; lua_assert(ci.top <= L.stack_last); ci.callstatus = 0; if ((L.hookmask & LUA_MASKCALL) != 0) { luaD_hook(L, LUA_HOOKCALL, -1); } lua_unlock(L); n = f(L); /* do the actual call */ lua_lock(L); api_checknelems(L, n); luaD_poscall(L, L.top - n, n); return(1); } case LUA_TLCL: { /* Lua function: prepare its call */ StkId base_; Proto p = clLvalue(func).p; n = cast_int(L.top - func) - 1; /* number of real arguments */ luaC_checkGC(L); /* stack grow uses memory */ luaD_checkstack(L, p.maxstacksize); for (; n < p.numparams; n++) { setnilvalue(lua_TValue.inc(ref L.top)); /* complete missing arguments */ } if (0 == p.is_vararg) { func = restorestack(L, funcr); base_ = func + 1; } else { base_ = adjust_varargs(L, p, n); func = restorestack(L, funcr); /* previous call can change stack */ } ci = next_ci(L); /* now `enter' new function */ ci.nresults = (short)nresults; //FIXME:added, (short) ci.func = func; ci.u.l.base_ = base_; ci.top = base_ + p.maxstacksize; lua_assert(ci.top <= L.stack_last); ci.u.l.savedpc = new InstructionPtr(p.code, 0); /* starting point */ //FIXME:??? //FIXME:??? ci.callstatus = CIST_LUA; L.top = ci.top; if ((L.hookmask & LUA_MASKCALL) != 0) { callhook(L, ci); } return(0); } default: { /* not a function */ luaD_checkstack(L, 1); /* ensure space for metamethod */ func = restorestack(L, funcr); /* previous call may change stack */ tryfuncTM(L, func); /* try to get '__call' metamethod */ return(luaD_precall(L, func, nresults)); /* now it must be a function */ } } }
private static StkId TryFuncTM(LuaState L, StkId func) { /*const*/ TValue tm = luaT_gettmbyobj(L, func, TMS.TM_CALL); StkId p; ptrdiff_t funcr = SaveStack(L, func); if (!TTIsFunction(tm)) LuaGTypeError(L, func, "call"); /* Open a hole inside the stack at `func' */ for (p = L.top; p > func; StkId.Dec(ref p)) SetObj2S(L, p, p - 1); IncrTop(L); func = RestoreStack(L, funcr); /* previous call may change stack */ SetObj2S(L, func, tm); /* tag method is the new function to be called */ return func; }
public static void luaD_seterrorobj (lua_State L, int errcode, StkId oldtop) { switch (errcode) { case LUA_ERRMEM: { setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); break; } case LUA_ERRERR: { setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); break; } case LUA_ERRSYNTAX: case LUA_ERRRUN: { setobjs2s(L, oldtop, L.top-1); /* error message on current top */ break; } } L.top = oldtop + 1; }
public static int luaH_next (LuaState L, Table t, StkId key) { int i = findindex(L, t, key); /* find original element */ for (i++; i < t.sizearray; i++) { /* try first array part */ if (!TTIsNil(t.array[i])) { /* a non-nil value? */ SetNValue(key, CastNum(i+1)); SetObj2S(L, key+1, t.array[i]); return 1; } } for (i -= t.sizearray; i < SizeNode(t); i++) { /* then hash part */ if (!TTIsNil(gval(gnode(t, i)))) { /* a non-nil value? */ SetObj2S(L, key, key2tval(gnode(t, i))); SetObj2S(L, key+1, gval(gnode(t, i))); return 1; } } return 0; /* no more elements */ }
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"); }
static CharPtr aux_upvalue(StkId fi, int n, ref TValue val) { Closure f; if (!ttisfunction(fi)) return null; f = clvalue(fi); if (f.c.isC != 0) { if (!(1 <= n && n <= f.c.nupvalues)) return null; val = f.c.upvalue[n - 1]; return ""; } else { Proto p = f.l.p; if (!(1 <= n && n <= p.sizeupvalues)) return null; val = f.l.upvals[n - 1].v; return getstr(p.upvalues[n - 1]); } }
public static int tostring(LuaState L, StkId o) { return ((TType(o) == LUA_TSTRING) || (luaV_tostring(L, o) != 0)) ? 1 : 0; }
public static CharPtr svalue(StkId o) { return(getstr(rawtsvalue(o))); }
/* ** returns true if function has been executed (C function) */ public static int luaD_precall(lua_State L, StkId func, int nresults) { LClosure cl; ptrdiff_t funcr; if (!ttisfunction(func)) /* `func' is not a function? */ { func = tryfuncTM(L, func); /* check the `function' tag method */ } funcr = savestack(L, func); cl = clvalue(func).l; L.ci.nresults = (short)nresults; //FIXME:??? if (cl.isC == 0) /* Lua function? prepare its call */ { CallInfo ci; int nparams, nargs; StkId base_; Proto p = cl.p; luaD_checkstack(L, p.maxstacksize); func = restorestack(L, funcr); nargs = cast_int(L.top - func) - 1; /* number of real arguments */ nparams = p.numparams; /* number of expected parameters */ for (; nargs < nparams; nargs++) { setnilvalue(lua_TValue.inc(ref L.top)); /* complete missing arguments */ } if (p.is_vararg == 0) /* no varargs? */ { base_ = L.stack[func + 1]; } else /* vararg function */ { base_ = adjust_varargs(L, p, nargs); } ci = next_ci(L); /* now `enter' new function */ ci.func = func; ci.u.l.base_ = base_; ci.top = base_ + p.maxstacksize; lua_assert(ci.top <= L.stack_last); ci.u.l.savedpc = new InstructionPtr(p.code, 0); /* starting point */ //FIXME:??? //FIXME:??? ci.u.l.tailcalls = 0; ci.callstatus = CIST_LUA; L.top = ci.top; if ((L.hookmask & LUA_MASKCALL) != 0) { InstructionPtr.inc(ref ci.u.l.savedpc); /* hooks assume 'pc' is already incremented */ luaD_callhook(L, LUA_HOOKCALL, -1); InstructionPtr.dec(ref ci.u.l.savedpc); /* correct 'pc' */ } return(0); } else /* if is a C function, call it */ { CallInfo ci; int n; luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ ci = next_ci(L); /* now `enter' new function */ ci.func = restorestack(L, funcr); ci.top = L.top + LUA_MINSTACK; lua_assert(ci.top <= L.stack_last); ci.callstatus = 0; if ((L.hookmask & LUA_MASKCALL) != 0) { luaD_callhook(L, LUA_HOOKCALL, -1); } lua_unlock(L); n = curr_func(L).c.f(L); /* do the actual call */ lua_lock(L); luaD_poscall(L, L.top - n); return(1); } }
public static void luaV_gettable (LuaState L, TValue t, TValue key, StkId val) { int loop; for (loop = 0; loop < MAXTAGLOOP; loop++) { TValue tm; if (TTIsTable(t)) { /* `t' is a table? */ Table h = HValue(t); TValue res = luaH_get(h, key); /* do a primitive get */ if (!TTIsNil(res) || /* result is no nil? */ (tm = fasttm(L, h.metatable, TMS.TM_INDEX)) == null) { /* or no TM? */ SetObj2S(L, val, res); return; } /* else will try the tag method */ } else if (TTIsNil(tm = luaT_gettmbyobj(L, t, TMS.TM_INDEX))) LuaGTypeError(L, t, "index"); if (TTIsFunction(tm)) { callTMres(L, val, tm, t, key); return; } t = tm; /* else repeat with `tm' */ } LuaGRunError(L, "loop in gettable"); }
public static int lua_isinteger(lua_State L, int idx) { StkId o = index2addr(L, idx); return(ttisinteger(o) ? 1 : 0); }
private static int call_binTM (LuaState L, TValue p1, TValue p2, StkId res, TMS event_) { TValue tm = luaT_gettmbyobj(L, p1, event_); /* try first operand */ if (TTIsNil(tm)) tm = luaT_gettmbyobj(L, p2, event_); /* try second operand */ if (TTIsNil(tm)) return 0; callTMres(L, res, tm, p1, p2); return 1; }
public static TValue RC(lua_State L, StkId base_, Instruction i) { return(base_ + GETARG_C(i)); }
public static int tonumber(ref StkId o, TValue n) { return ((TType(o) == LUA_TNUMBER || (((o) = luaV_tonumber(o, n)) != null))) ? 1 : 0; }
public static TValue RKC(lua_State L, StkId base_, Instruction i, TValue[] k) { return(ISK(GETARG_C(i)) != 0 ? k[INDEXK(GETARG_C(i))] : base_ + GETARG_C(i)); }
internal static TValue RC(LuaState L, StkId base_, Instruction i) { return base_ + GETARG_C(i); }
//#define Protect(x) { {x;}; base = L.base_; } public static void arith_op(lua_State L, op_delegate op, TMS tm, StkId base_, Instruction i, TValue[] k, StkId ra /*, InstructionPtr pc*/) { TValue rb = RKB(L, base_, i, k); TValue rc = RKC(L, base_, i, k); if (ttisnumber(rb) && ttisnumber(rc)) { lua_Number nb = nvalue(rb), nc = nvalue(rc); setnvalue(ra, op(L, nb, nc)); } else { //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: Arith(L, ra, rb, rc, tm); base_ = L.base_; //); } }
public static void arith_op(LuaState L, op_delegate op, TMS tm, StkId base_, Instruction i, TValue[] k, StkId ra, InstructionPtr pc) { TValue rb = RKB(L, base_, i, k); TValue rc = RKC(L, base_, i, k); if (TTIsNumber(rb) && TTIsNumber(rc)) { lua_Number nb = NValue(rb), nc = NValue(rc); SetNValue(ra, op(nb, nc)); } else { //Protect( L.savedpc = InstructionPtr.Assign(pc); Arith(L, ra, rb, rc, tm); base_ = L.base_; //); } }
public static void luaV_execute(lua_State L, int nexeccalls) { LClosure cl; StkId base_; TValue[] k; reentry: /* entry point */ lua_assert(isLua(L.ci)); cl = clvalue(L.ci.func).l; base_ = L.base_; k = cl.p.k; /* main loop of interpreter */ for (;;) { /*const*/ Instruction i = InstructionPtr.inc(ref L.savedpc)[0]; 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 L.savedpc); /* undo increment */ 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(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 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_ = 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_ = 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_ = 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_ = 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_ = 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_ = 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); continue; } case OpCode.OP_SUB: { arith_op(L, luai_numsub, TMS.TM_SUB, base_, i, k, ra); continue; } case OpCode.OP_MUL: { arith_op(L, luai_nummul, TMS.TM_MUL, base_, i, k, ra); continue; } case OpCode.OP_DIV: { arith_op(L, luai_numdiv, TMS.TM_DIV, base_, i, k, ra); continue; } case OpCode.OP_MOD: { arith_op(L, luai_nummod, TMS.TM_MOD, base_, i, k, ra); continue; } case OpCode.OP_POW: { arith_op(L, luai_numpow, TMS.TM_POW, base_, i, k, ra); 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: Arith(L, ra, rb, rb, TMS.TM_UNM); base_ = 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: { 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); //FIXME: if (call_binTM(L, rb, rb, 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); //FIXME: 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, 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); //FIXME: if (equalobj(L, rb, rc) == GETARG_A(i)) { dojump(L, GETARG_sBx(L.savedpc[0])); } base_ = L.base_; //); InstructionPtr.inc(ref 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(L, GETARG_sBx(L.savedpc[0])); } base_ = L.base_; //); InstructionPtr.inc(ref L.savedpc); continue; } case OpCode.OP_LE: { //Protect( //L.savedpc = InstructionPtr.Assign(pc); //FIXME: if (lessequal(L, RKB(L, base_, i, k), RKC(L, base_, i, k)) == GETARG_A(i)) { dojump(L, GETARG_sBx(L.savedpc[0])); } base_ = L.base_; //); InstructionPtr.inc(ref L.savedpc); continue; } case OpCode.OP_TEST: { if (l_isfalse(ra) != GETARG_C(i)) { dojump(L, GETARG_sBx(L.savedpc[0])); } InstructionPtr.inc(ref L.savedpc); continue; } case OpCode.OP_TESTSET: { TValue rb = RB(L, base_, i); if (l_isfalse(rb) != GETARG_C(i)) { setobjs2s(L, ra, rb); dojump(L, GETARG_sBx(L.savedpc[0])); } InstructionPtr.inc(ref 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 */ } 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 */ } 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); InstructionPtr.Assign(L.savedpc, ref ci.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_); } 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(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(L, 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; 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(L, 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);//FIXME: 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, GETARG_sBx(L.savedpc[0])); /* jump back */ } InstructionPtr.inc(ref L.savedpc); 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) { c = cast_int(L.savedpc[0]); InstructionPtr.inc(ref L.savedpc); } 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); } L.top = L.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++, InstructionPtr.inc(ref L.savedpc)) { Instruction u = L.savedpc[0]; 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_ = 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);//FIXME: 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; } } } }
private static void callTMres (LuaState L, StkId res, TValue f, TValue p1, TValue p2) { ptrdiff_t result = SaveStack(L, res); SetObj2S(L, L.top, f); /* push function */ SetObj2S(L, L.top+1, p1); /* 1st argument */ SetObj2S(L, L.top+2, p2); /* 2nd argument */ LuaDCheckStack(L, 3); L.top += 3; LuaDCall(L, L.top-3, 1); res = RestoreStack(L, result); StkId.Dec(ref L.top); SetObj2S(L, res, L.top); }
/* ** access functions (stack . C) */ public static int lua_type(lua_State L, int idx) { StkId o = index2addr(L, idx); return(isvalid(o) ? ttypenv(o) : LUA_TNONE); }
public static int LuaDPreCall(LuaState L, StkId func, int nresults) { LClosure cl; ptrdiff_t funcr; if (!TTIsFunction(func)) /* `func' is not a function? */ func = TryFuncTM(L, func); /* check the `function' tag method */ funcr = SaveStack(L, func); cl = CLValue(func).l; L.ci.savedpc = InstructionPtr.Assign(L.savedpc); if (cl.isC == 0) { /* Lua function? prepare its call */ CallInfo ci; StkId st, base_; Proto p = cl.p; LuaDCheckStack(L, p.maxstacksize); func = RestoreStack(L, funcr); if (p.is_vararg == 0) { /* no varargs? */ base_ = L.stack[func + 1]; if (L.top > base_ + p.numparams) L.top = base_ + p.numparams; } else { /* vararg function */ int nargs = L.top - func - 1; base_ = AdjustVarArgs(L, p, nargs); func = RestoreStack(L, funcr); /* previous call may change the stack */ } ci = IncCI(L); /* now `enter' new function */ ci.func = func; L.base_ = ci.base_ = base_; ci.top = L.base_ + p.maxstacksize; LuaAssert(ci.top <= L.stack_last); L.savedpc = new InstructionPtr(p.code, 0); /* starting point */ ci.tailcalls = 0; ci.nresults = nresults; for (st = L.top; st < ci.top; StkId.Inc(ref st)) SetNilValue(st); L.top = ci.top; if ((L.hookmask & LUA_MASKCALL) != 0) { InstructionPtr.inc(ref L.savedpc); /* hooks assume 'pc' is already incremented */ LuaDCallHook(L, LUA_HOOKCALL, -1); InstructionPtr.dec(ref L.savedpc); /* correct 'pc' */ } return PCRLUA; } else { /* if is a C function, call it */ CallInfo ci; int n; LuaDCheckStack(L, LUA_MINSTACK); /* ensure minimum stack size */ ci = IncCI(L); /* now `enter' new function */ ci.func = RestoreStack(L, funcr); L.base_ = ci.base_ = ci.func + 1; ci.top = L.top + LUA_MINSTACK; LuaAssert(ci.top <= L.stack_last); ci.nresults = nresults; if ((L.hookmask & LUA_MASKCALL) != 0) LuaDCallHook(L, LUA_HOOKCALL, -1); LuaUnlock(L); n = CurrFunc(L).c.f(L); /* do the actual call */ LuaLock(L); if (n < 0) /* yielding? */ return PCRYIELD; else { LuaDPosCall(L, L.top - n); return PCRC; } } }
public static bool lua_iscfunction(lua_State L, int idx) { StkId o = index2addr(L, idx); return(ttislcf(o) || (ttisCclosure(o))); }
// in the original C code these values save and restore the stack by number of bytes. marshalling sizeof // isn't that straightforward in managed languages, so i implement these by index instead. public static int SaveStack(LuaState L, StkId p) { return p; }
/* test for valid but not pseudo index */ public static bool isstackindex(int i, StkId o) { return(isvalid(o) && !ispseudo(i)); }
/* ** Call a function (C or Lua). The function to be called is at *func. ** The arguments are on the stack, right after the function. ** When returns, all the results are on the stack, starting at the original ** function position. */ private static void LuaDCall(LuaState L, StkId func, int nResults) { if (++L.nCcalls >= LUAI_MAXCCALLS) { if (L.nCcalls == LUAI_MAXCCALLS) LuaGRunError(L, "C stack overflow"); else if (L.nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS >> 3))) LuaDThrow(L, LUA_ERRERR); /* error while handing stack error */ } if (LuaDPreCall(L, func, nResults) == PCRLUA) /* is a Lua function? */ luaV_execute(L, 1); /* call it */ L.nCcalls--; LuaCCheckGC(L); }
public static void api_checkstackindex(lua_State L, int i, StkId o) { api_check(L, isstackindex(i, o), "index not in the stack"); }
private static void CheckStackSizes (LuaState L, StkId max) { int ci_used = CastInt(L.ci - L.base_ci[0]); /* number of `ci' in use */ int s_used = CastInt(max - L.stack); /* part of stack in use */ if (L.size_ci > LUAI_MAXCALLS) /* handling overflow? */ return; /* do not touch the stacks */ if (4*ci_used < L.size_ci && 2*BASICCISIZE < L.size_ci) LuaDReallocCI(L, L.size_ci/2); /* still big enough... */ //condhardstacktests(luaD_reallocCI(L, ci_used + 1)); if (4*s_used < L.stacksize && 2*(BASICSTACKSIZE+EXTRASTACK) < L.stacksize) LuaDRealAllocStack(L, L.stacksize/2); /* still big enough... */ //condhardstacktests(luaD_reallocstack(L, s_used)); }
public static lua_State lua_tothread(lua_State L, int idx) { StkId o = index2addr(L, idx); return((!ttisthread(o)) ? null : thvalue(o)); }
/* ** returns the index of a `key' for table traversals. First goes all ** elements in the array part, then elements in the hash part. The ** beginning of a traversal is signalled by -1. */ private static int findindex (LuaState L, Table t, StkId key) { int i; if (TTIsNil(key)) return -1; /* first iteration */ i = arrayindex(key); if (0 < i && i <= t.sizearray) /* is `key' inside array part? */ return i-1; /* yes; that's the index (corrected to C) */ else { Node n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ /* key may be dead already, but it is ok to use it in `next' */ if ((LuaORawEqualObj(key2tval(n), key) != 0) || (TType(gkey(n)) == LUATDEADKEY && IsCollectable(key) && GCValue(gkey(n)) == GCValue(key))) { i = CastInt(n - gnode(t, 0)); /* key index in hash table */ /* hash elements are numbered after array ones */ return i + t.sizearray; } else n = gnext(n); } while (n != null); LuaGRunError(L, "invalid key to " + LUA_QL("next")); /* key not found */ return 0; /* to avoid warnings */ } }
public static int tostring(lua_State L, StkId o) { return(((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o) != 0)) ? 1 : 0); }
public static void luaF_close (LuaState L, StkId level) { UpVal uv; GlobalState g = G(L); while (L.openupval != null && (uv = ngcotouv(L.openupval)).v >= level) { GCObject o = obj2gco(uv); lua_assert(!isblack(o) && uv.v != uv.u.value); L.openupval = uv.next; /* remove from `open' list */ if (isdead(g, o)) luaF_freeupval(L, uv); /* free upvalue */ else { unlinkupval(uv); setobj(L, uv.u.value, uv.v); uv.v = uv.u.value; /* now current value lives here */ luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ } } }
public static int tonumber(ref StkId o, TValue n) { return(((ttype(o) == LUA_TNUMBER || (((o) = luaV_tonumber(o, n)) != null))) ? 1 : 0); }
public static CharPtr SValue(StkId o) { return GetStr(RawTSValue(o)); }
internal static TValue RB(lua_State L, StkId base_, Instruction i) { return(base_ + GETARG_B(i)); }
public static void api_checkvalidindex(LuaState L, StkId i) { api_check(L, i != luaO_nilobject); }
/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ public static CharPtr luaO_pushvfstring(lua_State L, CharPtr fmt, params object[] argp) { int parm_index = 0; //FIXME: added, for emulating va_arg(argp, xxx) int n = 0; for (;;) { CharPtr e = strchr(fmt, '%'); if (e == null) { break; } luaD_checkstack(L, 2); /* fmt + item */ pushstr(L, fmt, (uint)(e - fmt)); switch (e[1]) { case 's': { object o = argp[parm_index++]; //FIXME: changed CharPtr s = o as CharPtr; //FIXME: changed if (s == null) //FIXME: changed { s = (string)o; //FIXME: changed } if (s == null) { s = "(null)"; } pushstr(L, s, (uint)strlen(s)); //FIXME:changed, (uint) break; } case 'c': { CharPtr buff = new char[1]; //FIXME:???char->CharPtr buff[0] = (char)(int)argp[parm_index++]; pushstr(L, buff, 1); //FIXME:???&buff break; } case 'd': { setnvalue(L.top, (int)argp[parm_index++]); StkId.inc(ref L.top); break; } case 'f': { setnvalue(L.top, (l_uacNumber)argp[parm_index++]); StkId.inc(ref L.top); break; } case 'p': { CharPtr buff = new char[32]; /* should be enough space for a `%p' */ //FIXME: changed, char buff[4*sizeof(void *) + 8]; uint l = (uint)sprintf(buff, "0x%08x", argp[parm_index++].GetHashCode()); //FIXME: changed, %p->%08x //FIXME:changed, (uint) pushstr(L, buff, l); break; } case '%': { pushstr(L, "%", 1); break; } default: { luaG_runerror(L, "invalid option " + LUA_QL("%%%c") + " to " + LUA_QL("lua_pushfstring"), (e + 1).ToString()); //FIXME: changed, *(e+1) break; //FIXME:added } } n += 2; fmt = e + 2; } luaD_checkstack(L, 1); pushstr(L, fmt, (uint)strlen(fmt)); //FIXME:changed, (uint) if (n > 0) { luaV_concat(L, n + 1); } return(svalue(L.top - 1)); }