diff --git a/.github/workflows/build-libs.yml b/.github/workflows/build-libs.yml index 830687f..b40b1fd 100644 --- a/.github/workflows/build-libs.yml +++ b/.github/workflows/build-libs.yml @@ -279,17 +279,6 @@ jobs: make - # FNA (Only built on Linux, due to being platform agnostic) - - uses: actions/setup-dotnet@v4 - if: ${{ matrix.platform == 'linux' }} - with: - dotnet-version: '8' - - - name: Build FNA - if: ${{ matrix.platform == 'linux' }} - working-directory: source/FNA - run: dotnet build -c ${{ env.BUILD_TYPE }} FNA.NetFramework.csproj - # Upload - name: Copy binaries (Windows) if: ${{ matrix.platform == 'windows' }} @@ -312,8 +301,6 @@ jobs: - name: Copy binaries (Linux) if: ${{ matrix.platform == 'linux' }} run: | - cp source/FNA/bin/${{ env.BUILD_TYPE }}/net4.0/FNA.dll FNA.dll - cp source/FNA/bin/${{ env.BUILD_TYPE }}/net4.0/FNA.pdb FNA.pdb cp ${{ env.SDL2_DIR }}/lib/libSDL2-2.0.so.0 libSDL2-2.0.so.0 cp source/FNA/lib/FAudio/build/libFAudio.so.0 libFAudio.so.0 cp source/FNA/lib/FNA3D/build/libFNA3D.so.0 libFNA3D.so.0 @@ -349,13 +336,71 @@ jobs: with: name: fnalibs-linux-x86_64 path: | - FNA.dll - FNA.pdb libSDL2-2.0.so.0 libFAudio.so.0 libFNA3D.so.0 libtheorafile.so + build-managed-libs: + name: Managed Libraries + runs-on: ubuntu-latest + defaults: + run: + shell: sh + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + sparse-checkout: | + source + patches + submodules: recursive + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + global-json-file: source/MonoMod/global.json + + - name: Install SN + run: sudo apt install -y mono-devel + + - name: Build MonoMod + working-directory: source/MonoMod + run: | + dotnet publish -c ${{ env.BUILD_TYPE }} -f ${{ env.NET_FRAMEWORK }} src/MonoMod.Utils/MonoMod.Utils.csproj + dotnet publish -c ${{ env.BUILD_TYPE }} -f ${{ env.NET_FRAMEWORK }} src/MonoMod.Patcher/MonoMod.Patcher.csproj + dotnet publish -c ${{ env.BUILD_TYPE }} -f ${{ env.NET_FRAMEWORK }} src/MonoMod.RuntimeDetour/MonoMod.RuntimeDetour.csproj + dotnet publish -c ${{ env.BUILD_TYPE }} -f ${{ env.NET_FRAMEWORK }} src/MonoMod.RuntimeDetour.HookGen/MonoMod.RuntimeDetour.HookGen.csproj + + - name: Build NLua + working-directory: source/NLua + run: dotnet publish -c ${{ env.BUILD_TYPE }} build/net6.0/NLua.net6.0.csproj + + - name: Build FNA + working-directory: source/FNA + run: dotnet build -c ${{ env.BUILD_TYPE }} FNA.NetFramework.csproj + + - name: Copy artifacts + run: | + MM_DIR=$(echo "${{ env.BUILD_TYPE }} ${{ env.NET_FRAMEWORK }}" | awk '{print tolower($1) "_" $2}') + mkdir all_artifacts + cp source/MonoMod/artifacts/publish/MonoMod.Utils/$MM_DIR/* all_artifacts + cp source/MonoMod/artifacts/publish/MonoMod.Patcher/$MM_DIR/* all_artifacts + cp source/MonoMod/artifacts/publish/MonoMod.RuntimeDetour/$MM_DIR/* all_artifacts + cp source/MonoMod/artifacts/publish/MonoMod.RuntimeDetour.HookGen/$MM_DIR/* all_artifacts + + cp -r source/NLua/lib/${{ env.BUILD_TYPE }}/net6.0/publish/* all_artifacts + + cp source/FNA/bin/${{ env.BUILD_TYPE }}/net4.0/FNA.dll all_artifacts + cp source/FNA/bin/${{ env.BUILD_TYPE }}/net4.0/FNA.pdb all_artifacts + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: managed-libraries + path: all_artifacts + build-piton: strategy: matrix: @@ -430,7 +475,7 @@ jobs: generate-lib-ext: name: Generate lib-ext runs-on: ubuntu-latest - needs: [build-fnalibs, build-piton] + needs: [build-fnalibs, build-managed-libs, build-piton] steps: - uses: actions/checkout@v4 @@ -472,6 +517,8 @@ jobs: mkdir -p ../lib-ext/lib64-win-x64 mkdir -p ../lib-ext/lib64-osx mkdir -p ../lib-ext/lib64-linux + + mkdir -p ../lib-ext/piton ### Vendored files cp README_lib-ext.md ../lib-ext/README.md @@ -492,8 +539,8 @@ jobs: pushd ../lib-ext ### Vanilla overrides - cp ../binaries/fnalibs-linux-x86_64/FNA.dll lib-vanilla - cp ../binaries/fnalibs-linux-x86_64/FNA.pdb lib-vanilla + cp ../binaries/managed-libraries/FNA.dll lib-vanilla + cp ../binaries/managed-libraries/FNA.pdb lib-vanilla # Windows x86 cp ../binaries/fnalibs-windows-i686/FNA3D.dll lib-vanilla @@ -516,8 +563,10 @@ jobs: cp ../binaries/fnalibs-linux-x86_64/libtheorafile.so lib-vanilla/lib64 ### Everest Libraries - mv ../binaries/fnalibs-linux-x86_64/FNA.dll . - mv ../binaries/fnalibs-linux-x86_64/FNA.pdb . + mv ../binaries/managed-libraries/FNA.dll . + mv ../binaries/managed-libraries/FNA.pdb . + + mv ../binaries/managed-libraries/* . mv ../binaries/fnalibs-windows-i686/* lib64-win-x86 mv ../binaries/fnalibs-windows-x86_64/* lib64-win-x64 @@ -530,7 +579,10 @@ jobs: cp ../binaries/discord_game_sdk/lib/x86_64/discord_game_sdk.so lib64-linux/libdiscord_game_sdk.so ### Piton - mv ../binaries/piton-apphosts piton + mv ../binaries/piton-apphosts-i686-pc-windows-msvc/* piton + mv ../binaries/piton-apphosts-x86_64-pc-windows-msvc/* piton + mv ../binaries/piton-apphosts-x86_64-unknown-linux-gnu/* piton + mv ../binaries/piton-apphosts-x86_64-apple-darwin/* piton - name: Display the new structure run: ls -R ../lib-ext diff --git a/.gitmodules b/.gitmodules index 1c6dcfa..efc31a4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,10 +1,10 @@ -[submodule "FNA"] +[submodule "source/FNA"] path = source/FNA url = https://github.com/FNA-XNA/FNA -[submodule "SDL2"] +[submodule "source/SDL2"] path = source/SDL2 url = https://github.com/libsdl-org/SDL/ -[submodule "Piton"] +[submodule "source/Piton"] path = source/Piton url = https://github.com/Popax21/Piton [submodule "source/MoltenVK"] @@ -19,3 +19,9 @@ [submodule "source/SDL_GameControllerDB"] path = source/SDL_GameControllerDB url = https://github.com/mdqinc/SDL_GameControllerDB +[submodule "source/MonoMod"] + path = source/MonoMod + url = https://github.com/MonoMod/MonoMod/ +[submodule "source/NLua"] + path = source/NLua + url = https://github.com/NLua/NLua/ diff --git a/README.md b/README.md index db5ec6e..8ddaa94 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ These libraries are open source and are built in CI. - MoltenVK `1.2.11` - Vulkan Loader `1.3.296` - Piton [21c7868](https://github.com/Popax21/Piton/tree/21c7868d06007f0c5e7d9030a0109fe892df1bf3) +- NLua `1.6.2` with patches +- MonoMod [be053cf](https://github.com/MonoMod/MonoMod/tree/be053cf084f320a0cd5b516288e1e332b855471d) ### Closed-Source Libraries These libraries are closed source and cannot be _built_ in CI. diff --git a/patches/NLua_FixTracebackLeak.patch b/patches/NLua_FixTracebackLeak.patch new file mode 100644 index 0000000..b3d9ae7 --- /dev/null +++ b/patches/NLua_FixTracebackLeak.patch @@ -0,0 +1,113 @@ +From cafdb0330111df64e008d74c679abc7edf951ef6 Mon Sep 17 00:00:00 2001 +From: Wartori54 +Date: Wed, 23 Oct 2024 23:43:40 +0200 +Subject: [PATCH] Remove debug.traceback references from stack after PCall + with UseTraceback enabled + +--- + src/Lua.cs | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/src/Lua.cs b/src/Lua.cs +index ad3d107..b622b0e 100644 +--- a/src/Lua.cs ++++ b/src/Lua.cs +@@ -496,10 +496,12 @@ namespace NLua + ThrowExceptionFromError(oldTop); + + int errorFunctionIndex = 0; ++ int errorFunctionAbsoluteIndex = -1; + + if (UseTraceback) + { + errorFunctionIndex = PushDebugTraceback(_luaState, 0); ++ errorFunctionAbsoluteIndex = _luaState.GetTop() + errorFunctionIndex + 1; + oldTop++; + } + +@@ -512,6 +514,9 @@ namespace NLua + } + finally + { ++ if (errorFunctionAbsoluteIndex != -1) ++ _luaState.Remove(errorFunctionAbsoluteIndex); ++ + _executing = false; + } + } +@@ -531,10 +536,12 @@ namespace NLua + ThrowExceptionFromError(oldTop); + + int errorFunctionIndex = 0; ++ int errorFunctionAbsoluteIndex = -1; + + if (UseTraceback) + { + errorFunctionIndex = PushDebugTraceback(_luaState, 0); ++ errorFunctionAbsoluteIndex = _luaState.GetTop() + errorFunctionIndex + 1; + oldTop++; + } + +@@ -547,6 +554,9 @@ namespace NLua + } + finally + { ++ if (errorFunctionAbsoluteIndex != -1) ++ _luaState.Remove(errorFunctionAbsoluteIndex); ++ + _executing = false; + } + } +@@ -565,9 +575,11 @@ namespace NLua + _executing = true; + + int errorFunctionIndex = 0; ++ int errorFunctionAbsoluteIndex = -1; + if (UseTraceback) + { + errorFunctionIndex = PushDebugTraceback(_luaState, 0); ++ errorFunctionAbsoluteIndex = _luaState.GetTop() + errorFunctionIndex + 1; + oldTop++; + } + +@@ -580,6 +592,9 @@ namespace NLua + } + finally + { ++ if (errorFunctionAbsoluteIndex != -1) ++ _luaState.Remove(errorFunctionAbsoluteIndex); ++ + _executing = false; + } + } +@@ -820,12 +835,14 @@ namespace NLua + + _executing = true; + ++ int errfunctionAbs = -1; + try + { + int errfunction = 0; + if (UseTraceback) + { + errfunction = PushDebugTraceback(_luaState, nArgs); ++ errfunctionAbs = _luaState.GetTop() + errfunction + 1; + oldTop++; + } + +@@ -835,6 +852,12 @@ namespace NLua + } + finally + { ++ if (errfunctionAbs != -1) ++ { ++ _luaState.Remove(errfunctionAbs); ++ oldTop--; ++ } ++ + _executing = false; + } + +-- +2.49.0 + diff --git a/patches/NLua_WrapLuaErrors.patch b/patches/NLua_WrapLuaErrors.patch new file mode 100644 index 0000000..40b9d4f --- /dev/null +++ b/patches/NLua_WrapLuaErrors.patch @@ -0,0 +1,631 @@ +From e5b81a252f13f95b4280f784b7dbdca8bad4b79a Mon Sep 17 00:00:00 2001 +From: Popax21 +Date: Mon, 6 Feb 2023 00:20:37 +0100 +Subject: [PATCH] Wrap C functions to throw errors in Lua functions + +This change makes all C functions not throw their Lua errors directly, +and instead makes them return it for a Lua wrapper to pick up and raise. +By doing this, the issue of longjmp translation is bypassed/fixed on +non-Windows platforms, as the errors are thrown and caught inside native +Lua runtime code. + +Fixes #344 +--- + src/Lua.cs | 5 +- + src/Metatables.cs | 95 ++++++++++++++++----------- + src/ObjectTranslator.cs | 138 ++++++++++++++++++++++++++-------------- + 3 files changed, 152 insertions(+), 86 deletions(-) + +diff --git a/src/Lua.cs b/src/Lua.cs +index ad3d107..fd8a85f 100644 +--- a/src/Lua.cs ++++ b/src/Lua.cs +@@ -1,4 +1,4 @@ +-using System; ++using System; + using System.Linq; + using System.Reflection; + using System.Collections.Generic; +@@ -315,6 +315,9 @@ namespace NLua + } + _luaState.PushGlobalTable(); + _luaState.GetGlobal("luanet"); ++ _luaState.PushString("_G"); ++ _luaState.GetGlobal("_G"); ++ _luaState.SetTable(-3); + _luaState.PushString("getmetatable"); + _luaState.GetGlobal("getmetatable"); + _luaState.SetTable(-3); +diff --git a/src/Metatables.cs b/src/Metatables.cs +index ec9cc93..c42e5d9 100644 +--- a/src/Metatables.cs ++++ b/src/Metatables.cs +@@ -1,4 +1,4 @@ +-using System; ++using System; + using System.Linq; + using System.Collections; + using System.Reflection; +@@ -47,6 +47,25 @@ namespace NLua + readonly Dictionary> _memberCache = new Dictionary>(); + readonly ObjectTranslator _translator; + ++ /* ++ * C function wrapper. Has to be in Lua to not mess up the CLR stack ++ */ ++ public const string LuaCFunctionWrapper = @"local function w(f)return function(...)local r={_G.pcall(f,...)}if not _G.table.remove(r, 1) then _G.error('UNWRAPPED LUA ERROR FROM MANAGED CODE!');elseif _G.table.remove(r, 1) then _G.error(_G.table.unpack(r));else return _G.table.unpack(r);end end end;return w"; ++ //@"local function wrap(func) ++ // return function(...) ++ // local r = { _G.pcall(func, ...) } ++ // if not _G.table.remove(r, 1) then ++ // _G.error('UNWRAPPED LUA ERROR FROM MANAGED CODE!') ++ // elseif _G.table.remove(r, 1) then ++ // _G.error(_G.table.unpack(r)) ++ // else ++ // return _G.table.unpack(r) ++ // end ++ // end ++ // end ++ ++ // return wrap"; ++ + /* + * __index metafunction for CLR objects. Implemented in Lua. + */ +@@ -94,15 +113,15 @@ namespace NLua + var translator = ObjectTranslatorPool.Instance.Find(state); + var func = (LuaNativeFunction)translator.GetRawNetObject(state, 1); + if (func == null) +- return state.Error(); ++ return translator.ErrorFromWrappedCFunction(state); + + state.Remove(1); + int result = func(luaState); + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + /* +@@ -115,7 +134,7 @@ namespace NLua + { + var luaState = LuaState.FromIntPtr(state); + var translator = ObjectTranslatorPool.Instance.Find(luaState); +- return CollectObject(luaState, translator); ++ return translator.ReturnFromWrappedCFunction(luaState, CollectObject(luaState, translator)); + } + + private static int CollectObject(LuaState luaState, ObjectTranslator translator) +@@ -138,7 +157,7 @@ namespace NLua + { + var luaState = LuaState.FromIntPtr(state); + var translator = ObjectTranslatorPool.Instance.Find(luaState); +- return ToStringLua(luaState, translator); ++ return translator.ReturnFromWrappedCFunction(luaState, ToStringLua(luaState, translator)); + } + + private static int ToStringLua(LuaState luaState, ObjectTranslator translator) +@@ -168,8 +187,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + /* +@@ -186,8 +205,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + /* +@@ -204,8 +223,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + /* +@@ -222,8 +241,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + /* +@@ -240,8 +259,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + /* +@@ -258,8 +277,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + static int UnaryNegationLua(LuaState luaState, ObjectTranslator translator) //-V3009 +@@ -300,8 +319,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + /* +@@ -318,8 +337,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + /* +@@ -336,8 +355,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + /// +@@ -387,8 +406,8 @@ namespace NLua + var exception = translator.GetObject(luaState, -1) as LuaScriptException; + + if (exception != null) +- return luaState.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(luaState); ++ return translator.ReturnFromWrappedCFunction(luaState, result); + } + + private int GetMethodInternal(LuaState luaState) +@@ -691,8 +710,8 @@ namespace NLua + var exception = translator.GetObject(luaState, -1) as LuaScriptException; + + if (exception != null) +- return luaState.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(luaState); ++ return translator.ReturnFromWrappedCFunction(luaState, result); + } + + private int GetBaseMethodInternal(LuaState luaState) +@@ -994,8 +1013,8 @@ namespace NLua + var exception = translator.GetObject(luaState, -1) as LuaScriptException; + + if (exception != null) +- return luaState.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(luaState); ++ return translator.ReturnFromWrappedCFunction(luaState, result); + } + + private int SetFieldOrPropertyInternal(LuaState luaState) +@@ -1199,8 +1218,8 @@ namespace NLua + var exception = translator.GetObject(luaState, -1) as LuaScriptException; + + if (exception != null) +- return luaState.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(luaState); ++ return translator.ReturnFromWrappedCFunction(luaState, result); + } + + private int GetClassMethodInternal(LuaState luaState) +@@ -1245,8 +1264,8 @@ namespace NLua + var exception = translator.GetObject(luaState, -1) as LuaScriptException; + + if (exception != null) +- return luaState.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(luaState); ++ return translator.ReturnFromWrappedCFunction(luaState, result); + } + + private int SetClassFieldOrPropertyInternal(LuaState luaState) +@@ -1277,9 +1296,9 @@ namespace NLua + var exception = translator.GetObject(luaState, -1) as LuaScriptException; + + if (exception != null) +- return luaState.Error(); ++ return translator.ErrorFromWrappedCFunction(luaState); + +- return result; ++ return translator.ReturnFromWrappedCFunction(luaState, result); + } + + int CallDelegateInternal(LuaState luaState) +@@ -1346,8 +1365,8 @@ namespace NLua + var exception = translator.GetObject(luaState, -1) as LuaScriptException; + + if (exception != null) +- return luaState.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(luaState); ++ return translator.ReturnFromWrappedCFunction(luaState, result); + } + + private static ConstructorInfo[] ReorderConstructors(ConstructorInfo[] constructors) +diff --git a/src/ObjectTranslator.cs b/src/ObjectTranslator.cs +index 2c0dd35..a6233fa 100644 +--- a/src/ObjectTranslator.cs ++++ b/src/ObjectTranslator.cs +@@ -1,4 +1,4 @@ +-using System; ++using System; + using System.IO; + using System.Reflection; + using System.Collections.Generic; +@@ -79,6 +79,7 @@ namespace NLua + assemblies = new List(); + + CreateLuaObjectList(luaState); ++ CreateCFunctionWrapperFunction(luaState); + CreateIndexingMetaFunction(luaState); + CreateBaseClassMetatable(luaState); + CreateClassMetatable(luaState); +@@ -102,6 +103,17 @@ namespace NLua + luaState.SetTable((int)LuaRegistry.Index); + } + ++ /* ++ * Registers the wrapper function for C functions ++ * to be called from Lua ++ */ ++ private void CreateCFunctionWrapperFunction(LuaState luaState) ++ { ++ luaState.PushString("luaNet_cfuncwrapper"); ++ luaState.DoString(MetaFunctions.LuaCFunctionWrapper); ++ luaState.RawSet(LuaRegistry.Index); ++ } ++ + /* + * Registers the indexing function of CLR objects + * passed to Lua +@@ -121,16 +133,16 @@ namespace NLua + { + luaState.NewMetaTable("luaNet_searchbase"); + luaState.PushString("__gc"); +- luaState.PushCFunction(MetaFunctions.GcFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.GcFunction); + luaState.SetTable(-3); + luaState.PushString("__tostring"); +- luaState.PushCFunction(MetaFunctions.ToStringFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.ToStringFunction); + luaState.SetTable(-3); + luaState.PushString("__index"); +- luaState.PushCFunction(MetaFunctions.BaseIndexFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.BaseIndexFunction); + luaState.SetTable(-3); + luaState.PushString("__newindex"); +- luaState.PushCFunction(MetaFunctions.NewIndexFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.NewIndexFunction); + luaState.SetTable(-3); + luaState.SetTop(-2); + } +@@ -142,19 +154,19 @@ namespace NLua + { + luaState.NewMetaTable("luaNet_class"); + luaState.PushString("__gc"); +- luaState.PushCFunction(MetaFunctions.GcFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.GcFunction); + luaState.SetTable(-3); + luaState.PushString("__tostring"); +- luaState.PushCFunction(MetaFunctions.ToStringFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.ToStringFunction); + luaState.SetTable(-3); + luaState.PushString("__index"); +- luaState.PushCFunction(MetaFunctions.ClassIndexFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.ClassIndexFunction); + luaState.SetTable(-3); + luaState.PushString("__newindex"); +- luaState.PushCFunction(MetaFunctions.ClassNewIndexFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.ClassNewIndexFunction); + luaState.SetTable(-3); + luaState.PushString("__call"); +- luaState.PushCFunction(MetaFunctions.CallConstructorFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.CallConstructorFunction); + luaState.SetTable(-3); + luaState.SetTop(-2); + } +@@ -164,23 +176,23 @@ namespace NLua + */ + private void SetGlobalFunctions(LuaState luaState) + { +- luaState.PushCFunction(MetaFunctions.IndexFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.IndexFunction); + luaState.SetGlobal("get_object_member"); +- luaState.PushCFunction(_importTypeFunction); ++ PushWrappedCFunction(luaState, _importTypeFunction); + luaState.SetGlobal("import_type"); +- luaState.PushCFunction(_loadAssemblyFunction); ++ PushWrappedCFunction(luaState, _loadAssemblyFunction); + luaState.SetGlobal("load_assembly"); +- luaState.PushCFunction(_registerTableFunction); ++ PushWrappedCFunction(luaState, _registerTableFunction); + luaState.SetGlobal("make_object"); +- luaState.PushCFunction(_unregisterTableFunction); ++ PushWrappedCFunction(luaState, _unregisterTableFunction); + luaState.SetGlobal("free_object"); +- luaState.PushCFunction(_getMethodSigFunction); ++ PushWrappedCFunction(luaState, _getMethodSigFunction); + luaState.SetGlobal("get_method_bysig"); +- luaState.PushCFunction(_getConstructorSigFunction); ++ PushWrappedCFunction(luaState, _getConstructorSigFunction); + luaState.SetGlobal("get_constructor_bysig"); +- luaState.PushCFunction(_ctypeFunction); ++ PushWrappedCFunction(luaState, _ctypeFunction); + luaState.SetGlobal("ctype"); +- luaState.PushCFunction(_enumFromIntFunction); ++ PushWrappedCFunction(luaState, _enumFromIntFunction); + luaState.SetGlobal("enum"); + } + +@@ -191,10 +203,10 @@ namespace NLua + { + luaState.NewMetaTable("luaNet_function"); + luaState.PushString("__gc"); +- luaState.PushCFunction(MetaFunctions.GcFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.GcFunction); + luaState.SetTable(-3); + luaState.PushString("__call"); +- luaState.PushCFunction(MetaFunctions.ExecuteDelegateFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.ExecuteDelegateFunction); + luaState.SetTable(-3); + luaState.SetTop(-2); + } +@@ -257,8 +269,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + private int LoadAssemblyInternal(LuaState luaState) +@@ -357,7 +369,7 @@ namespace NLua + { + var state = LuaState.FromIntPtr(luaState); + var translator = ObjectTranslatorPool.Instance.Find(state); +- return translator.ImportTypeInternal(state); ++ return translator.ReturnFromWrappedCFunction(state, translator.ImportTypeInternal(state)); + } + + private int ImportTypeInternal(LuaState luaState) +@@ -389,8 +401,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + private int RegisterTableInternal(LuaState luaState) +@@ -456,8 +468,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + private int UnregisterTableInternal(LuaState luaState) +@@ -513,8 +525,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + private int GetMethodSignatureInternal(LuaState luaState) //-V3009 +@@ -578,8 +590,8 @@ namespace NLua + var exception = translator.GetObject(state, -1) as LuaScriptException; + + if (exception != null) +- return state.Error(); +- return result; ++ return translator.ErrorFromWrappedCFunction(state); ++ return translator.ReturnFromWrappedCFunction(state, result); + } + + private int GetConstructorSignatureInternal(LuaState luaState) //-V3009 +@@ -632,6 +644,38 @@ namespace NLua + } + + ++ /* ++ * Pushes a C function, wrapping it so that errors aren't ++ * thrown directly but instead by a small Lua wrapper ++ */ ++ internal void PushWrappedCFunction(LuaState luaState, LuaNativeFunction func) ++ { ++ luaState.PushString("luaNet_cfuncwrapper"); ++ luaState.RawGet(LuaRegistry.Index); ++ luaState.PushCFunction(func); ++ luaState.PCall(1, 1, 0); ++ } ++ ++ /* ++ * Normally returns from a wrapped C function ++ */ ++ internal int ReturnFromWrappedCFunction(LuaState luaState, int numRets) ++ { ++ luaState.PushBoolean(false); ++ luaState.Insert(-(numRets + 1)); ++ return numRets + 1; ++ } ++ ++ /* ++ * Errors out from a wrapped C function ++ */ ++ internal int ErrorFromWrappedCFunction(LuaState luaState) ++ { ++ luaState.PushBoolean(true); ++ luaState.Insert(-2); ++ return 2; ++ } ++ + /* + * Pushes a CLR object into the Lua stack as an userdata + * with the provided metatable +@@ -703,13 +747,13 @@ namespace NLua + luaState.RawGet(LuaRegistry.Index); + luaState.RawSet(-3); + luaState.PushString("__gc"); +- luaState.PushCFunction(MetaFunctions.GcFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.GcFunction); + luaState.RawSet(-3); + luaState.PushString("__tostring"); +- luaState.PushCFunction(MetaFunctions.ToStringFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.ToStringFunction); + luaState.RawSet(-3); + luaState.PushString("__newindex"); +- luaState.PushCFunction(MetaFunctions.NewIndexFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.NewIndexFunction); + luaState.RawSet(-3); + // Bind C# operator with Lua metamethods (__add, __sub, __mul) + RegisterOperatorsFunctions(luaState, o.GetType()); +@@ -737,7 +781,7 @@ namespace NLua + return; + + luaState.PushString("__call"); +- luaState.PushCFunction(MetaFunctions.CallDelegateFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.CallDelegateFunction); + luaState.RawSet(-3); + } + +@@ -746,55 +790,55 @@ namespace NLua + if (type.HasAdditionOperator()) + { + luaState.PushString("__add"); +- luaState.PushCFunction(MetaFunctions.AddFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.AddFunction); + luaState.RawSet(-3); + } + if (type.HasSubtractionOperator()) + { + luaState.PushString("__sub"); +- luaState.PushCFunction(MetaFunctions.SubtractFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.SubtractFunction); + luaState.RawSet(-3); + } + if (type.HasMultiplyOperator()) + { + luaState.PushString("__mul"); +- luaState.PushCFunction(MetaFunctions.MultiplyFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.MultiplyFunction); + luaState.RawSet(-3); + } + if (type.HasDivisionOperator()) + { + luaState.PushString("__div"); +- luaState.PushCFunction(MetaFunctions.DivisionFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.DivisionFunction); + luaState.RawSet(-3); + } + if (type.HasModulusOperator()) + { + luaState.PushString("__mod"); +- luaState.PushCFunction(MetaFunctions.ModulosFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.ModulosFunction); + luaState.RawSet(-3); + } + if (type.HasUnaryNegationOperator()) + { + luaState.PushString("__unm"); +- luaState.PushCFunction(MetaFunctions.UnaryNegationFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.UnaryNegationFunction); + luaState.RawSet(-3); + } + if (type.HasEqualityOperator()) + { + luaState.PushString("__eq"); +- luaState.PushCFunction(MetaFunctions.EqualFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.EqualFunction); + luaState.RawSet(-3); + } + if (type.HasLessThanOperator()) + { + luaState.PushString("__lt"); +- luaState.PushCFunction(MetaFunctions.LessThanFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.LessThanFunction); + luaState.RawSet(-3); + } + if (type.HasLessThanOrEqualOperator()) + { + luaState.PushString("__le"); +- luaState.PushCFunction(MetaFunctions.LessThanOrEqualFunction); ++ PushWrappedCFunction(luaState, MetaFunctions.LessThanOrEqualFunction); + luaState.RawSet(-3); + } + } +@@ -1137,7 +1181,7 @@ namespace NLua + { + var state = LuaState.FromIntPtr(luaState); + var translator = ObjectTranslatorPool.Instance.Find(state); +- return translator.CTypeInternal(state); ++ return translator.ReturnFromWrappedCFunction(state, translator.CTypeInternal(state)); + } + + int CTypeInternal(LuaState luaState) +@@ -1157,7 +1201,7 @@ namespace NLua + { + var state = LuaState.FromIntPtr(luaState); + var translator = ObjectTranslatorPool.Instance.Find(state); +- return translator.EnumFromIntInternal(state); ++ return translator.ReturnFromWrappedCFunction(state, translator.EnumFromIntInternal(state)); + } + + int EnumFromIntInternal(LuaState luaState) +-- +2.49.0 + diff --git a/source/MonoMod b/source/MonoMod new file mode 160000 index 0000000..be053cf --- /dev/null +++ b/source/MonoMod @@ -0,0 +1 @@ +Subproject commit be053cf084f320a0cd5b516288e1e332b855471d diff --git a/source/NLua b/source/NLua new file mode 160000 index 0000000..94f2c18 --- /dev/null +++ b/source/NLua @@ -0,0 +1 @@ +Subproject commit 94f2c180282d822189c3668a43f475df81856c3b