public static void CompleteTypeMeta(IntPtr ptr, LuaCSFunction con, Type self) { LuaNativeMethods.lua_pushstring(ptr, ObjectCache.GetAQName(self)); LuaNativeMethods.lua_setfield(ptr, -3, "__fullname"); indexFunction.Push(ptr); LuaNativeMethods.lua_setfield(ptr, -2, "__index"); newIndexFunction.Push(ptr); LuaNativeMethods.lua_setfield(ptr, -2, "__newindex"); if (con == null) { con = NoConstructor; } PushValue(ptr, con); LuaNativeMethods.lua_setfield(ptr, -2, "__call"); LuaNativeMethods.lua_pushcfunction(ptr, TypeToString); LuaNativeMethods.lua_setfield(ptr, -2, "__tostring"); LuaNativeMethods.lua_pushvalue(ptr, -1); LuaNativeMethods.lua_setmetatable(ptr, -3); LuaNativeMethods.lua_setfield(ptr, LuaIndexes.LUARegistryIndex, self.FullName); }
public static bool CheckType(IntPtr ptr, int p, out LuaDelegate f) { LuaState state = LuaState.Get(ptr); p = LuaNativeMethods.lua_absindex(ptr, p); LuaNativeMethods.luaL_checktype(ptr, p, LuaTypes.TYPE_FUNCTION); LuaNativeMethods.lua_getglobal(ptr, DelgateTable); LuaNativeMethods.lua_pushvalue(ptr, p); LuaNativeMethods.lua_gettable(ptr, -2); // find function in __LuaDelegate table if (LuaNativeMethods.lua_isnil(ptr, -1)) { // not found LuaNativeMethods.lua_pop(ptr, 1); // pop nil f = NewDelegate(ptr, p); } else { int fref = LuaNativeMethods.lua_tointeger(ptr, -1); LuaNativeMethods.lua_pop(ptr, 1); // pop ref value; f = state.DelegateMap[fref]; if (f == null) { f = NewDelegate(ptr, p); } } LuaNativeMethods.lua_pop(ptr, 1); // pop DelgateTable return(true); }
public static bool CheckType(IntPtr ptr, int p, out LuaTable t) { if (LuaNativeMethods.lua_isnil(ptr, p)) { t = null; return(true); } LuaNativeMethods.luaL_checktype(ptr, p, LuaTypes.TYPE_TABLE); LuaNativeMethods.lua_pushvalue(ptr, p); int fref = LuaNativeMethods.luaL_ref(ptr, LuaIndexes.LUARegistryIndex); t = new LuaTable(ptr, fref); return(true); }
public static bool CheckType(IntPtr ptr, int p, out LuaFunction f) { if (LuaNativeMethods.lua_isnil(ptr, p)) { f = null; return(true); } LuaNativeMethods.luaL_checktype(ptr, p, LuaTypes.TYPE_FUNCTION); LuaNativeMethods.lua_pushvalue(ptr, p); int fref = LuaNativeMethods.luaL_ref(ptr, LuaIndexes.LUARegistryIndex); f = new LuaFunction(ptr, fref); return(true); }
public int PushTry() { if (errorRef == 0) { LuaNativeMethods.lua_pushcfunction(statePointer, LuaState.errorFunc); LuaNativeMethods.lua_pushvalue(statePointer, -1); errorRef = LuaNativeMethods.luaL_ref(statePointer, LuaIndexes.LUARegistryIndex); } else { LuaNativeMethods.lua_getref(statePointer, errorRef); } return(LuaNativeMethods.lua_gettop(statePointer)); }
public static LuaDelegate NewDelegate(IntPtr ptr, int p) { LuaState state = LuaState.Get(ptr); LuaNativeMethods.lua_pushvalue(ptr, p); // push function int fref = LuaNativeMethods.luaL_ref(ptr, LuaIndexes.LUARegistryIndex); // new ref function LuaDelegate f = new LuaDelegate(ptr, fref); LuaNativeMethods.lua_pushvalue(ptr, p); LuaNativeMethods.lua_pushinteger(ptr, fref); LuaNativeMethods.lua_settable(ptr, -3); // __LuaDelegate[func]= fref state.DelegateMap[fref] = f; return(f); }
public static int LuaUnaryOp(IntPtr ptr, string f, string tip) { int err = GetOpFunction(ptr, f, tip); LuaNativeMethods.lua_pushvalue(ptr, 1); if (LuaNativeMethods.lua_pcall(ptr, 1, 1, err) != 0) { LuaNativeMethods.lua_pop(ptr, 1); } LuaNativeMethods.lua_remove(ptr, err); PushValue(ptr, true); LuaNativeMethods.lua_insert(ptr, -2); return(2); }
private static void CompleteInstanceMeta(IntPtr ptr, Type self) { LuaNativeMethods.lua_pushstring(ptr, "__typename"); LuaNativeMethods.lua_pushstring(ptr, self.Name); LuaNativeMethods.lua_rawset(ptr, -3); // for instance indexFunction.Push(ptr); LuaNativeMethods.lua_setfield(ptr, -2, "__index"); newIndexFunction.Push(ptr); LuaNativeMethods.lua_setfield(ptr, -2, "__newindex"); PushValue(ptr, luaAdd); LuaNativeMethods.lua_setfield(ptr, -2, "__add"); PushValue(ptr, luaSub); LuaNativeMethods.lua_setfield(ptr, -2, "__sub"); PushValue(ptr, luaMul); LuaNativeMethods.lua_setfield(ptr, -2, "__mul"); PushValue(ptr, luaDiv); LuaNativeMethods.lua_setfield(ptr, -2, "__div"); PushValue(ptr, luaUnm); LuaNativeMethods.lua_setfield(ptr, -2, "__unm"); PushValue(ptr, luaEq); LuaNativeMethods.lua_setfield(ptr, -2, "__eq"); PushValue(ptr, luaLe); LuaNativeMethods.lua_setfield(ptr, -2, "__le"); PushValue(ptr, luaLt); LuaNativeMethods.lua_setfield(ptr, -2, "__lt"); PushValue(ptr, luaToString); LuaNativeMethods.lua_setfield(ptr, -2, "__tostring"); LuaNativeMethods.lua_pushcfunction(ptr, LuaGC); LuaNativeMethods.lua_setfield(ptr, -2, "__gc"); if (self.IsValueType && IsImplByLua(self)) { LuaNativeMethods.lua_pushvalue(ptr, -1); LuaNativeMethods.lua_setglobal(ptr, self.FullName + ".Instance"); } LuaNativeMethods.lua_setfield(ptr, LuaIndexes.LUARegistryIndex, ObjectCache.GetAQName(self)); }
public static int As(IntPtr ptr) { try { if (!LuaObject.IsTypeTable(ptr, 2)) { return(Error(ptr, "No matched type of param 2")); } string meta = LuaNativeMethods.lua_tostring(ptr, -1); LuaNativeMethods.luaL_getmetatable(ptr, meta); LuaNativeMethods.lua_setmetatable(ptr, 1); LuaObject.PushValue(ptr, true); LuaNativeMethods.lua_pushvalue(ptr, 1); return(2); } catch (Exception e) { return(Error(ptr, e)); } }
public static int PrintError(IntPtr ptr) { int n = LuaNativeMethods.lua_gettop(ptr); s.Length = 0; LuaNativeMethods.lua_getglobal(ptr, "tostring"); for (int i = 1; i <= n; i++) { if (i > 1) { s.Append(" "); } LuaNativeMethods.lua_pushvalue(ptr, -1); LuaNativeMethods.lua_pushvalue(ptr, i); LuaNativeMethods.lua_call(ptr, 1, 1); s.Append(LuaNativeMethods.lua_tostring(ptr, -1)); LuaNativeMethods.lua_pop(ptr, 1); } LuaNativeMethods.lua_settop(ptr, n); LuaNativeMethods.lua_getglobal(ptr, "debug"); LuaNativeMethods.lua_getfield(ptr, -1, "traceback"); LuaNativeMethods.lua_call(ptr, 0, 1); s.Append("\n"); s.Append(LuaNativeMethods.lua_tostring(ptr, -1)); LuaNativeMethods.lua_pop(ptr, 1); Logger.LogError(s.ToString(), true); if (ErrorEvent != null) { ErrorEvent(s.ToString()); } return(0); }
public static void NewTypeTable(IntPtr ptr, string name) { string[] subt = name.Split('.'); LuaNativeMethods.lua_pushglobaltable(ptr); foreach (string t in subt) { LuaNativeMethods.lua_pushstring(ptr, t); LuaNativeMethods.lua_rawget(ptr, -2); if (LuaNativeMethods.lua_isnil(ptr, -1)) { LuaNativeMethods.lua_pop(ptr, 1); LuaNativeMethods.lua_createtable(ptr, 0, 0); LuaNativeMethods.lua_pushstring(ptr, t); LuaNativeMethods.lua_pushvalue(ptr, -2); LuaNativeMethods.lua_rawset(ptr, -4); } LuaNativeMethods.lua_remove(ptr, -2); } }
public static int ExtractFunction(IntPtr ptr, int p) { int op = 0; LuaTypes t = LuaNativeMethods.lua_type(ptr, p); switch (t) { case LuaTypes.TYPE_NIL: case LuaTypes.TYPE_USERDATA: op = 0; break; case LuaTypes.TYPE_TABLE: LuaNativeMethods.lua_rawgeti(ptr, p, 1); LuaNativeMethods.lua_pushstring(ptr, "+="); if (LuaNativeMethods.lua_rawequal(ptr, -1, -2) == 1) { op = 1; } else { op = 2; } LuaNativeMethods.lua_pop(ptr, 2); LuaNativeMethods.lua_rawgeti(ptr, p, 2); break; case LuaTypes.TYPE_FUNCTION: LuaNativeMethods.lua_pushvalue(ptr, p); break; default: throw new Exception("expect valid Delegate"); } return(op); }
public static int ErrorReport(IntPtr ptr) { LuaNativeMethods.lua_getglobal(ptr, "debug"); LuaNativeMethods.lua_getfield(ptr, -1, "traceback"); LuaNativeMethods.lua_pushvalue(ptr, 1); LuaNativeMethods.lua_pushnumber(ptr, 2); LuaNativeMethods.lua_call(ptr, 2, 1); LuaNativeMethods.lua_remove(ptr, -2); string error = LuaNativeMethods.lua_tostring(ptr, -1); LuaNativeMethods.lua_pop(ptr, 1); Logger.LogError(error, true); if (ErrorEvent != null) { ErrorEvent(error); } LuaNativeMethods.lua_getglobal(ptr, "dumpstack"); LuaNativeMethods.lua_call(ptr, 0, 0); return(0); }
public static int Init(IntPtr ptr) { LuaNativeMethods.lua_pushlightuserdata(ptr, ptr); LuaNativeMethods.lua_setglobal(ptr, "__main_state"); LuaNativeMethods.lua_pushcfunction(ptr, Print); LuaNativeMethods.lua_setglobal(ptr, "print"); LuaNativeMethods.lua_pushcfunction(ptr, PrintError); LuaNativeMethods.lua_setglobal(ptr, "printerror"); LuaNativeMethods.lua_pushcfunction(ptr, ProtectedCall); LuaNativeMethods.lua_setglobal(ptr, "pcall"); PushCSFunction(ptr, Import); LuaNativeMethods.lua_setglobal(ptr, "import"); string resumefunc = @" local resume = coroutine.resume local function check(co, ok, err, ...) if not ok then UnityEngine.Debug.LogError(debug.traceback(co,err)) end return ok, err, ... end coroutine.resume=function(co,...) return check(co, resume(co,...)) end "; // overload resume function for report error LuaState.Get(ptr).DoString(resumefunc); // https://github.com/pkulchenko/MobDebug/blob/master/src/mobdebug.lua#L290 // Dump only 3 stacks, or it will return null (I don't know why) string dumpstackfunc = @" local printerror=printerror dumpstack=function() function vars(f) local dump = string.Emptystring.Empty local func = debug.getinfo(f, string.Emptyfstring.Empty).func local i = 1 local locals = {} -- get locals while true do local name, value = debug.getlocal(f, i) if not name then break end if string.sub(name, 1, 1) ~= '(' then dump = dump .. string.Empty string.Empty .. name .. string.Empty=string.Empty .. tostring(value) .. string.Empty\nstring.Empty end i = i + 1 end -- get varargs (these use negative indices) i = 1 while true do local name, value = debug.getlocal(f, -i) -- `not name` should be enough, but LuaJIT 2.0.0 incorrectly reports `(*temporary)` names here if not name or name ~= string.Empty(*vararg)string.Empty then break end dump = dump .. string.Empty string.Empty .. name .. string.Empty=string.Empty .. tostring(value) .. string.Empty\nstring.Empty i = i + 1 end -- get upvalues i = 1 while func do -- check for func as it may be nil for tail calls local name, value = debug.getupvalue(func, i) if not name then break end dump = dump .. string.Empty string.Empty .. name .. string.Empty=string.Empty .. tostring(value) .. string.Empty\nstring.Empty i = i + 1 end return dump end local dump = string.Emptystring.Empty for i = 3, 100 do local source = debug.getinfo(i, string.EmptySstring.Empty) if not source then break end dump = dump .. string.Empty- stackstring.Empty .. tostring(i-2) .. string.Empty\nstring.Empty dump = dump .. vars(i+1) if source.what == 'main' then break end end printerror(dump) end "; LuaState.Get(ptr).DoString(dumpstackfunc); #if UNITY_ANDROID // fix android performance drop with JIT on according to luajit mailist post LuaState.get(ptr).doString("if jit then require('jit.opt').start('sizemcode=256','maxmcode=256') for i=1,1000 do end end"); #endif PushCSFunction(ptr, DoFile); LuaNativeMethods.lua_setglobal(ptr, "dofile"); PushCSFunction(ptr, LoadFile); LuaNativeMethods.lua_setglobal(ptr, "loadfile"); PushCSFunction(ptr, Loader); int loaderFunc = LuaNativeMethods.lua_gettop(ptr); LuaNativeMethods.lua_getglobal(ptr, "package"); #if LUA_5_3 LuaNativeMethods.lua_getfield(ptr, -1, "searchers"); #else LuaNativeMethods.lua_getfield(ptr, -1, "loaders"); #endif int loaderTable = LuaNativeMethods.lua_gettop(ptr); // Shift table elements right for (int e = LuaNativeMethods.lua_rawlen(ptr, loaderTable) + 1; e > 2; e--) { LuaNativeMethods.lua_rawgeti(ptr, loaderTable, e - 1); LuaNativeMethods.lua_rawseti(ptr, loaderTable, e); } LuaNativeMethods.lua_pushvalue(ptr, loaderFunc); LuaNativeMethods.lua_rawseti(ptr, loaderTable, 2); LuaNativeMethods.lua_settop(ptr, 0); return(0); }
public static void lua_pushglobaltable(IntPtr ptr) { LuaNativeMethods.lua_pushvalue(ptr, LuaIndexes.LUAGlobalIndex); }