Skip to content

Commit bd873f3

Browse files
committed
Use panic wrapper for warning handler
1 parent 95ebe1b commit bd873f3

File tree

5 files changed

+73
-12
lines changed

5 files changed

+73
-12
lines changed

src/Laylua/Library/Lua.Warnings.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.IO;
3-
using System.Runtime.CompilerServices;
43
using System.Runtime.InteropServices;
54
using System.Text;
65
using Laylua.Moon;
@@ -32,8 +31,7 @@ public sealed unsafe partial class Lua
3231

3332
private MemoryStream? _warningBuffer;
3433

35-
[UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvCdecl) })]
36-
private static void WarningHandler(void* ud, byte* msg, int tocont)
34+
private static readonly LuaWarnFunction _warningHandler = static (ud, msg, tocont) =>
3735
{
3836
var lua = FromExtraSpace((lua_State*) ud);
3937
var msgSpan = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(msg);
@@ -119,7 +117,7 @@ static void ClearWarningBuffer(MemoryStream warningBuffer)
119117
warningBuffer.Position = 0;
120118
warningBuffer.SetLength(0);
121119
}
122-
}
120+
};
123121

124122
/// <inheritdoc cref="EmitWarning(ReadOnlySpan{char})"/>
125123
public void EmitWarning(string? message)

src/Laylua/Library/Lua.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ private Lua(
9494
MainThread = LuaThread.CreateMainThread(this);
9595
Globals = LuaTable.CreateGlobalsTable(this);
9696

97-
lua_setwarnf(state.L, &WarningHandler, State.L);
97+
lua_setwarnf(state.L, LayluaNative.CreateLuaWarnFunctionWrapper(_warningHandler), State.L);
9898
}
9999

100100
private Lua(

src/Laylua/Moon/Native/Extern/LuaNative.Delegates.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace Laylua.Moon;
3030
/// <param name="ud"> The userdata. </param>
3131
/// <param name="msg"> The message. </param>
3232
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
33-
public unsafe delegate void LuaWarnFunction(void* ud, [MarshalAs(UnmanagedType.LPStr)] string msg, int tocont);
33+
public unsafe delegate void LuaWarnFunction(void* ud, byte* msg, int tocont);
3434

3535
/// <summary>
3636
/// Represents a Lua allocation function.

src/Laylua/Moon/Native/Extern/LuaNative.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -585,13 +585,22 @@ public static int lua_yield(lua_State* L, int nresults)
585585
public static extern void lua_setwarnf(lua_State* L, LuaWarnFunction f, void* ud);
586586

587587
[DllImport(DllName, CallingConvention = Cdecl)]
588-
public static extern void lua_setwarnf(lua_State* L, delegate* unmanaged[Cdecl]<void*, byte*, int, void> f, void* ud);
588+
public static extern void lua_setwarnf(lua_State* L, IntPtr f, void* ud);
589589

590590
[DllImport(DllName, CallingConvention = Cdecl)]
591-
public static extern void lua_warning(lua_State* L, [MarshalAs(UnmanagedType.LPUTF8Str)] string msg, bool tocont);
591+
public static extern void lua_setwarnf(lua_State* L, delegate* unmanaged[Cdecl]<void*, byte*, int, void> f, void* ud);
592592

593-
[DllImport(DllName, CallingConvention = Cdecl)]
594-
private static extern void lua_warning(lua_State* L, byte* msg, bool tocont);
593+
[UnmanagedFunctionPointer(Cdecl)]
594+
private delegate void _lua_warningDelegate(lua_State* L, byte* msg, bool tocont);
595+
596+
private static _lua_warningDelegate _lua_warning = null!;
597+
598+
[ErrorExport]
599+
[MethodImpl(MethodImplOptions.NoInlining)]
600+
private static void lua_warning(lua_State* L, byte* msg, bool tocont)
601+
{
602+
_lua_warning(L, msg, tocont);
603+
}
595604

596605
public static void lua_warning(lua_State* L, ReadOnlySpan<char> msg, bool tocont)
597606
{

src/Laylua/Moon/Native/Laylua/LayluaNative.FunctionWrappers.cs

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,55 @@ public static IntPtr CreateLuaWriterFunctionWrapper(LuaWriterFunction function)
205205
return asmPtr;
206206
}
207207

208+
public static IntPtr CreateLuaWarnFunctionWrapper(LuaWarnFunction function)
209+
{
210+
var asmSpan = AllocFunctionWrapperAsm(out var asmPtr);
211+
212+
var functionWrapper = FunctionWrappers.GetValue(function, static function => (LuaWarnFunction) ((ud, msg, tocont) =>
213+
{
214+
try
215+
{
216+
#if TRACE_PANIC
217+
Console.WriteLine("LuaWarnFunction: calling delegate...");
218+
#endif
219+
Unsafe.As<LuaWarnFunction>(function)(ud, msg, tocont);
220+
}
221+
catch (Exception ex)
222+
{
223+
#if TRACE_PANIC
224+
Console.WriteLine("LuaWarnFunction: caught exception...");
225+
#endif
226+
var L = (lua_State*) ud;
227+
var laylua = LayluaState.FromExtraSpace(L);
228+
if (laylua.Panic != null)
229+
{
230+
#if TRACE_PANIC
231+
Console.WriteLine($"LuaWarnFunction: setting panic exception: {ex}");
232+
#endif
233+
laylua.Panic.Exception = ExceptionDispatchInfo.Capture(ex);
234+
}
235+
else
236+
{
237+
#if TRACE_PANIC
238+
Console.WriteLine($"LuaWarnFunction: panic is null, throwing exception: {ex}");
239+
#endif
240+
luaL_error(L, ex.Message);
241+
}
242+
}
243+
#if TRACE_PANIC
244+
Console.WriteLine("LuaWarnFunction: returning...");
245+
#endif
246+
}));
247+
248+
WriteFunctionWrapperPointers(asmSpan,
249+
#if TRACE_PANIC
250+
asmPtr,
251+
#endif
252+
function, functionWrapper);
253+
254+
return asmPtr;
255+
}
256+
208257
public static IntPtr CreateLuaHookFunctionWrapper(LuaHookFunction function)
209258
{
210259
var asmSpan = AllocFunctionWrapperAsm(out var asmPtr);
@@ -277,13 +326,18 @@ private static void WriteFunctionWrapperPointers(Span<byte> asmSpan,
277326
var functionWrapperPtr = Marshal.GetFunctionPointerForDelegate(functionWrapper);
278327

279328
// MemoryMarshal.Write(asmSpan.Slice(21), ref functionPtr);
280-
MemoryMarshal.Write(asmSpan.Slice(40 - 13), ref functionWrapperPtr);
281-
MemoryMarshal.Write(asmSpan.Slice(71 - 13), ref getPotentialPanicPtr);
329+
WriteFunctionWrapperPointers(asmSpan, functionWrapperPtr);
282330

283331
// Console.WriteLine("Stack State at 0x{0:X}", (IntPtr) stackState);
284332

285333
#if TRACE_PANIC
286334
Console.WriteLine("ManagedPanic for {0} asmPtr: 0x{1:X}\nGetPotentialPanicPtr: 0x{2:X}\nCallLuaCFunction: 0x{3:X} (for 0x{4:X})", callerName, asmPtr, getPotentialPanicPtr, functionWrapperPtr, functionPtr);
287335
#endif
288336
}
337+
338+
private static void WriteFunctionWrapperPointers(Span<byte> asmSpan, IntPtr functionWrapperPtr)
339+
{
340+
MemoryMarshal.Write(asmSpan.Slice(40 - 13), ref functionWrapperPtr);
341+
MemoryMarshal.Write(asmSpan.Slice(71 - 13), ref getPotentialPanicPtr);
342+
}
289343
}

0 commit comments

Comments
 (0)