private StkId T_GetTMByObj( ref TValue o, TMS tm ) { LuaTable mt = null; switch( o.Tt ) { case (int)LuaType.LUA_TTABLE: { var tbl = o.HValue(); mt = tbl.MetaTable; break; } case (int)LuaType.LUA_TUSERDATA: { var ud = o.RawUValue(); mt = ud.MetaTable; break; } default: { mt = G.MetaTables[o.Tt]; break; } } return (mt != null) ? mt.GetStr( GetTagMethodName( tm ) ) : TheNilValue; }
private LuaObject T_GetTMByObj( LuaObject o, TMS tm ) { LuaTable mt = null; switch( o.LuaType ) { case LuaType.LUA_TTABLE: { LuaTable tbl = o as LuaTable; mt = tbl.MetaTable; break; } case LuaType.LUA_TUSERDATA: { LuaUserData ud = o as LuaUserData; mt = ud.MetaTable; break; } default: { mt = G.MetaTables[(int)o.LuaType]; break; } } return (mt != null) ? mt.GetStr( GetTagMethodName( tm ) ) : new LuaNil(); }
/* ** function to be used with macro "fasttm": optimized for absence of ** tag methods */ public static TValue luaT_gettm (Table events, TMS event_, TString ename) { /*const*/ TValue tm = luaH_getstr(events, ename); LuaAssert(event_ <= TMS.TM_EQ); if (TTIsNil(tm)) { /* no tag method? */ events.flags |= (byte)(1<<(int)event_); /* cache this fact */ return null; } else return tm; }
private LuaObject FastTM( LuaTable et, TMS tm ) { if( et == null ) return null; if( (et.NoTagMethodFlags & (1u << (int)tm)) != 0u ) return null; return T_GetTM( et, tm ); }
private bool CallBinTM( StkId p1, StkId p2, StkId res, TMS tm ) { var tmObj = T_GetTMByObj(ref p1.V, tm); if(tmObj.V.TtIsNil()) tmObj = T_GetTMByObj(ref p2.V, tm); if(tmObj.V.TtIsNil()) return false; CallTM( ref tmObj.V, ref p1.V, ref p2.V, res, true ); return true; }
private bool CallBinTM( StkId p1, StkId p2, StkId res, TMS tm ) { var tmObj = T_GetTMByObj( p1.Value, tm ); if( tmObj.IsNil ) tmObj = T_GetTMByObj( p2.Value, tm ); if( tmObj.IsNil ) return false; CallTM( tmObj, p1.Value, p2.Value, res, true ); return true; }
private bool CallOrderTM( StkId p1, StkId p2, TMS tm, out bool error ) { if( !CallBinTM( p1, p2, Top, tm ) ) { error = true; // no metamethod return false; } error = false; return !IsFalse(ref Top.V); }
private StkId T_GetTM( LuaTable mt, TMS tm ) { if( mt == null ) return null; var res = mt.GetStr( GetTagMethodName( tm ) ); if(res.V.TtIsNil()) // no tag method? { // cache this fact mt.NoTagMethodFlags |= 1u << (int)tm; return null; } else return res; }
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(nb, nc)); } else { //Protect( L.savedpc = InstructionPtr.Assign(pc); Arith(L, ra, rb, rc, tm); base_ = L.base_; //); } }
public static TValue luaT_gettmbyobj(LuaState L, TValue o, TMS event_) { Table mt; switch (TType(o)) { case LUA_TTABLE: mt = HValue(o).metatable; break; case LUA_TUSERDATA: mt = UValue(o).metatable; break; default: mt = G(L).mt[TType(o)]; break; } return ((mt != null) ? luaH_getstr(mt, G(L).tmname[(int)event_]) : LuaONilObject); }
public static void Arith(lua_State L, StkId ra, TValue rb, TValue rc, TMS op) { TValue tempb = new TValue(), tempc = new TValue(); 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: lua_assert(false); break; } } else if (call_binTM(L, rb, rc, ra, op) == 0) luaG_aritherror(L, rb, rc); }
private string GetTagMethodName( TMS tm ) { switch( tm ) { case TMS.TM_INDEX: return "__index"; case TMS.TM_NEWINDEX: return "__newindex"; case TMS.TM_GC: return "__gc"; case TMS.TM_MODE: return "__mode"; case TMS.TM_LEN: return "__len"; case TMS.TM_EQ: return "__eq"; case TMS.TM_ADD: return "__add"; case TMS.TM_SUB: return "__sub"; case TMS.TM_MUL: return "__mul"; case TMS.TM_DIV: return "__div"; case TMS.TM_MOD: return "__mod"; case TMS.TM_POW: return "__pow"; case TMS.TM_UNM: return "__unm"; case TMS.TM_LT: return "__lt"; case TMS.TM_LE: return "__le"; case TMS.TM_CONCAT: return "__concat"; case TMS.TM_CALL: return "__call"; default: throw new System.NotImplementedException(); } }
public static TValue fasttm(LuaState l, Table et, TMS e) { return gfasttm(G(l), et, e); }
public static TValue gfasttm(GlobalState g, Table et, TMS e) { return (et == null) ? null : ((et.flags & (1 << (int)e)) != 0) ? null : luaT_gettm(et, e, g.tmname[(int)e]); }
private LuaOp TMS2OP( TMS op ) { switch( op ) { case TMS.TM_ADD: return LuaOp.LUA_OPADD; case TMS.TM_SUB: return LuaOp.LUA_OPSUB; case TMS.TM_MUL: return LuaOp.LUA_OPMUL; case TMS.TM_DIV: return LuaOp.LUA_OPDIV; case TMS.TM_POW: return LuaOp.LUA_OPPOW; case TMS.TM_UNM: return LuaOp.LUA_OPUNM; // case TMS.TM_EQ: return LuaOp.LUA_OPEQ; // case TMS.TM_LT: return LuaOp.LUA_OPLT; // case TMS.TM_LE: return LuaOp.LUA_OPLE; default: throw new System.NotImplementedException(); } }
private StkId GetEqualTM( LuaTable mt1, LuaTable mt2, TMS tm ) { var tm1 = FastTM( mt1, tm ); if(tm1 == null) // no metamethod return null; if(mt1 == mt2) // same metatables => same metamethods return tm1; var tm2 = FastTM( mt2, tm ); if(tm2 == null) // no metamethod return null; if(V_RawEqualObj(ref tm1.V, ref tm2.V)) // same metamethods? return tm1; return null; }
public static TValue gfasttm(global_State g, Table et, TMS e) { return((et == null) ? null : ((et.flags & (1 << (int)e)) != 0) ? null : luaT_gettm(et, e, g.tmname[(int)e])); }
private static int call_orderTM(lua_State L, TValue p1, TValue p2, TMS event_) { TValue tm1 = luaT_gettmbyobj(L, p1, event_); TValue tm2; if (ttisnil(tm1)) return -1; /* no metamethod? */ tm2 = luaT_gettmbyobj(L, p2, event_); if (luaO_rawequalObj(tm1, tm2)==0) /* different metamethods? */ return -1; callTMres(L, L.top, tm1, p1, p2); return l_isfalse(L.top) == 0 ? 1 : 0; }
public static TValue luaT_gettmbyobj(lua_State L, TValue o, TMS event_) { Table mt; switch (ttype(o)) { case LUA_TTABLE: mt = hvalue(o).metatable; break; case LUA_TUSERDATA: mt = uvalue(o).metatable; break; default: mt = G(L).mt[ttype(o)]; break; } return ((mt!=null) ? luaH_getstr(mt, G(L).tmname[(int)event_]) : luaO_nilobject); }
private void V_Arith( StkId ra, StkId rb, StkId rc, TMS op ) { var b = V_ToNumber( rb.Value ); var c = V_ToNumber( rc.Value ); if( b != null && c != null ) { var res = O_Arith( TMS2OP(op), b.Value, c.Value ); ra.Value = new LuaNumber( res ); } else if( !CallBinTM( rb, rc, ra, op ) ) { G_ArithError( rb, rc ); } }
private LuaObject GetEqualTM( LuaTable mt1, LuaTable mt2, TMS tm ) { LuaObject tm1 = FastTM( mt1, tm ); if( tm1 == null ) // no metamethod return null; if( mt1 == mt2 ) // same metatables => same metamethods return tm1; LuaObject tm2 = FastTM( mt2, tm ); if( tm2 == null ) // no metamethod return null; if( V_RawEqualObj( tm1, tm2 ) ) // same metamethods? return tm1; return null; }
public static TValue fasttm(lua_State l, Table et, TMS e) { return(gfasttm(G(l), et, e)); }
private static CharPtr getfuncname(lua_State L, CallInfo ci, ref CharPtr name) { TMS tm = 0; Instruction i; if ((ci.callstatus & CIST_TAIL) != 0 || isLua(ci.previous) == 0) { return(null); /* calling function is not Lua (or is unknown) */ } ci = ci.previous; /* calling function */ i = ci_func(ci).p.code[currentpc(ci)]; if (GET_OPCODE(i) == OpCode.OP_EXTRAARG) /* extra argument? */ { i = ci_func(ci).p.code[currentpc(ci) - 1]; /* get 'real' instruction */ } switch (GET_OPCODE(i)) { case OpCode.OP_CALL: case OpCode.OP_TAILCALL: return(getobjname(L, ci, GETARG_A(i), ref name)); case OpCode.OP_TFORCALL: { name = "for iterator"; return("for iterator"); } case OpCode.OP_SELF: case OpCode.OP_GETTABUP: case OpCode.OP_GETTABLE: tm = TMS.TM_INDEX; break; case OpCode.OP_SETTABUP: case OpCode.OP_SETTABLE: tm = TMS.TM_NEWINDEX; break; case OpCode.OP_EQ: tm = TMS.TM_EQ; break; case OpCode.OP_ADD: tm = TMS.TM_ADD; break; case OpCode.OP_SUB: tm = TMS.TM_SUB; break; case OpCode.OP_MUL: tm = TMS.TM_MUL; break; case OpCode.OP_DIV: tm = TMS.TM_DIV; break; case OpCode.OP_MOD: tm = TMS.TM_MOD; break; case OpCode.OP_POW: tm = TMS.TM_POW; break; case OpCode.OP_UNM: tm = TMS.TM_UNM; break; case OpCode.OP_LEN: tm = TMS.TM_LEN; break; case OpCode.OP_LT: tm = TMS.TM_LT; break; case OpCode.OP_LE: tm = TMS.TM_LE; break; case OpCode.OP_CONCAT: tm = TMS.TM_CONCAT; break; default: return(null); /* else no useful name can be found */ } name = getstr(G(L).tmname[(int)tm]); //FIXME:(int) return("metamethod"); }
public void ArithOp( LuaState lua, TMS tm, ArithDelegate op ) { var lhs = RKB.Value as LuaNumber; var rhs = RKC.Value as LuaNumber; if( lhs != null && rhs != null ) { var ra = RA; var res = op( lhs.Value, rhs.Value ); ra.Value = new LuaNumber( res ); } else lua.V_Arith( RA, RKB, RKC, tm ); }
private static int call_orderTM (LuaState L, TValue p1, TValue p2, TMS event_) { TValue tm1 = luaT_gettmbyobj(L, p1, event_); TValue tm2; if (TTIsNil(tm1)) return -1; /* no metamethod? */ tm2 = luaT_gettmbyobj(L, p2, event_); if (LuaORawEqualObj(tm1, tm2)==0) /* different metamethods? */ return -1; callTMres(L, L.top, tm1, p1, p2); return LIsFalse(L.top) == 0 ? 1 : 0; }
private static int call_binTM(lua_State 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; }
private void V_Arith( StkId ra, StkId rb, StkId rc, TMS op ) { var nb = new TValue(); var nc = new TValue(); if(V_ToNumber(rb, ref nb) && V_ToNumber(rc, ref nc)) { var res = O_Arith( TMS2OP(op), nb.NValue, nc.NValue ); ra.V.SetNValue( res ); } else if( !CallBinTM( rb, rc, ra, op ) ) { G_ArithError( rb, rc ); } }
private static TValue get_compTM(lua_State L, Table mt1, Table mt2, TMS event_) { TValue tm1 = fasttm(L, mt1, event_); TValue tm2; if (tm1 == null) return null; /* no metamethod */ if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ tm2 = fasttm(L, mt2, event_); if (tm2 == null) return null; /* no metamethod */ if (luaO_rawequalObj(tm1, tm2) != 0) /* same metamethods? */ return tm1; return null; }
/* ** Try to find a name for a function based on the code that called it. ** (Only works when function was called by a Lua function.) ** Returns what the name is (e.g., "for iterator", "method", ** "metamethod") and sets '*name' to point to the name. */ private static CharPtr funcnamefromcode(lua_State L, CallInfo ci, ref CharPtr name) { TMS tm = (TMS)0; /* (initial value avoids warnings) */ //FIXME:added, = 0 Proto p = ci_func(ci).p; /* calling function */ int pc = currentpc(ci); /* calling instruction index */ Instruction i = p.code[pc]; /* calling instruction */ if (0 != (ci.callstatus & CIST_HOOKED)) /* was it called inside a hook? */ { name = "?"; return("hook"); } switch (GET_OPCODE(i)) { case OpCode.OP_CALL: case OpCode.OP_TAILCALL: return(getobjname(p, pc, GETARG_A(i), ref name)); /* get function name */ case OpCode.OP_TFORCALL: { /* for iterator */ name = "for iterator"; return("for iterator"); } /* other instructions can do calls through metamethods */ case OpCode.OP_SELF: case OpCode.OP_GETTABUP: case OpCode.OP_GETTABLE: tm = TMS.TM_INDEX; break; case OpCode.OP_SETTABUP: case OpCode.OP_SETTABLE: tm = TMS.TM_NEWINDEX; break; case OpCode.OP_ADD: case OpCode.OP_SUB: case OpCode.OP_MUL: case OpCode.OP_MOD: case OpCode.OP_POW: case OpCode.OP_DIV: case OpCode.OP_IDIV: case OpCode.OP_BAND: case OpCode.OP_BOR: case OpCode.OP_BXOR: case OpCode.OP_SHL: case OpCode.OP_SHR: { int offset = cast_int(GET_OPCODE(i)) - cast_int(OpCode.OP_ADD); /* ORDER OP */ tm = (TMS)(offset + cast_int(TMS.TM_ADD)); /* ORDER TM */ break; } case OpCode.OP_UNM: tm = TMS.TM_UNM; break; case OpCode.OP_BNOT: tm = TMS.TM_BNOT; break; case OpCode.OP_LEN: tm = TMS.TM_LEN; break; case OpCode.OP_CONCAT: tm = TMS.TM_CONCAT; break; case OpCode.OP_EQ: tm = TMS.TM_EQ; break; case OpCode.OP_LT: tm = TMS.TM_LT; break; case OpCode.OP_LE: tm = TMS.TM_LE; break; default: return(null); /* cannot find a reasonable name */ } name = getstr(G(L).tmname[(int)tm]); //FIXME:(int) return("metamethod"); }