static int MetaUnaryOpFunctionInternal(lua_State L) { var objectArg = Api.luaL_testudata(L, 1, Lua.objectMetaTable); // test first one if (objectArg == IntPtr.Zero) { throw new LuaException(string.Format("Binary op {0} called on unexpected values.", Api.lua_tostring(L, Api.lua_upvalueindex(1)))); } var obj = Lua.UdataToObject(objectArg); var type = obj.GetType(); var opName = Api.lua_tostring(L, Api.lua_upvalueindex(1)); var members = Lua.GetMembers(type, opName, hasPrivatePrivillage: false); if (members.Length == 0) { throw new LuaException(string.Format("{0} not found in type {1}", opName, type.ToString())); } // upvalue 1 --> invocationFlags // upvalue 2 --> userdata (host of metatable). // upvalue 3 --> members Api.lua_pushinteger(L, (long)Lua.InvocationFlags.Static); Lua.PushObjectInternal(L, type); Lua.PushObjectInternal(L, members); Api.lua_pushcclosure(L, Lua.InvokeMethod, 3); Api.lua_pushvalue(L, 1); Lua.CallInternal(L, 1, 1); return(1); }
static int LuaDelegateInternal(IntPtr L) { var func = (Delegate)Lua.ObjectAtInternal(L, Api.lua_upvalueindex(1)); var numArgs = Api.lua_gettop(L); var refToDelegate = Lua.MakeRefToInternal(L, func); try { Api.lua_pushinteger(L, 0); // upvalue 1 --> invocationFlags Lua.PushRefInternal(L, refToDelegate); // upvalue 2 --> userdata, first parameter of __index var members = Lua.GetMembers(func.GetType(), "Invoke", hasPrivatePrivillage: false); Lua.PushObjectInternal(L, members); // upvalue 3 --> members Api.lua_pushcclosure(L, Lua.InvokeMethod, 3); Lua.PushRefInternal(L, refToDelegate); for (int i = 1; i <= numArgs; ++i) { Api.lua_pushvalue(L, i); } Lua.CallInternal(L, numArgs + 1, 1); Lua.UnrefInternal(L, refToDelegate); } catch (Exception e) { Lua.UnrefInternal(L, refToDelegate); throw e; } return(1); }
static int MetaBinaryOpFunctionInternal(lua_State L) { var op = (Lua.BinaryOp)Api.lua_tointeger(L, Api.lua_upvalueindex(2)); var objectArg = Api.luaL_testudata(L, 1, Lua.objectMetaTable); var objectArg2 = Api.luaL_testudata(L, 2, Lua.objectMetaTable); if (objectArg == IntPtr.Zero && objectArg2 == IntPtr.Zero) { throw new LuaException(string.Format("Binary op {0} called on unexpected values.", Api.lua_tostring(L, Api.lua_upvalueindex(1)))); } object obj1 = null, obj2 = null; if (objectArg != IntPtr.Zero) { obj1 = Lua.UdataToObject(objectArg); } if (objectArg2 != IntPtr.Zero) { obj2 = Lua.UdataToObject(objectArg2); } if (op == Lua.BinaryOp.op_Equality) { if ((obj1 == obj2) || (obj1 != null && obj1.Equals(obj2)) || (obj2 != null && obj2.Equals(obj1))) { Api.lua_pushboolean(L, true); } else { Api.lua_pushboolean(L, false); } return(1); } var obj = obj1; if (obj == null) { obj = obj2; } var type = obj.GetType(); var opName = Api.lua_tostring(L, Api.lua_upvalueindex(1)); var members = Lua.GetMembers(type, opName, hasPrivatePrivillage: false); if (members.Length == 0) { throw new LuaException(string.Format("{0} not found in type {1}", opName, type.ToString())); } long invocationFlags = (long)Lua.InvocationFlags.Static; Api.lua_pushinteger(L, invocationFlags); // upvalue 1 --> invocationFlags Lua.PushObjectInternal(L, type); // upvalue 2 --> userdata (host of metatable). Lua.PushObjectInternal(L, members); // upvalue 3 --> members Api.lua_pushcclosure(L, Lua.InvokeMethod, 3); Api.lua_pushvalue(L, 1); Api.lua_pushvalue(L, 2); Lua.CallInternal(L, 2, 1); return(1); }