From 364d551940141827a68fcee62cab2092a051621b Mon Sep 17 00:00:00 2001 From: nattthebear Date: Sat, 6 Jun 2020 15:51:51 -0400 Subject: [PATCH] waterbox linux progress uzem runs. i don't know about anything else yet. DO NOT ATTEMPT TO LOAD A SAVESTATE. --- src/BizHawk.BizInvoke/BizInvoker.cs | 9 +++- src/BizHawk.BizInvoke/BizInvokerUtilities.cs | 48 +++++++++++++++++++ .../Waterbox/Syscalls/Syscalls.cs | 8 ++-- 3 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 src/BizHawk.BizInvoke/BizInvokerUtilities.cs diff --git a/src/BizHawk.BizInvoke/BizInvoker.cs b/src/BizHawk.BizInvoke/BizInvoker.cs index 85681491b3..59d4844a2c 100644 --- a/src/BizHawk.BizInvoke/BizInvoker.cs +++ b/src/BizHawk.BizInvoke/BizInvoker.cs @@ -49,11 +49,17 @@ namespace BizHawk.BizInvoke /// private static readonly ModuleBuilder ImplModuleBuilder; + /// + /// How far into a class pointer the first field is. Different on mono and fw. + /// + private static readonly int ClassFieldOffset; + static BizInvoker() { var aname = new AssemblyName("BizInvokeProxyAssembly"); ImplAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(aname, AssemblyBuilderAccess.Run); ImplModuleBuilder = ImplAssemblyBuilder.DefineDynamicModule("BizInvokerModule"); + ClassFieldOffset = BizInvokerUtilities.ComputeClassFieldOffset(); } /// @@ -476,6 +482,7 @@ namespace BizHawk.BizInvoke if (typeof(Delegate).IsAssignableFrom(type)) { + // callback -- use the same callingconventionadapter on it that the invoker is being made from var mi = typeof(ICallingConventionAdapter).GetMethod("GetFunctionPointerForDelegate"); var end = il.DefineLabel(); var isNull = il.DefineLabel(); @@ -515,7 +522,7 @@ namespace BizHawk.BizInvoke il.Emit(OpCodes.Stloc, loc); il.Emit(OpCodes.Conv_I); // skip past the methodtable pointer to the first field - il.Emit(IntPtr.Size == 4 ? OpCodes.Ldc_I4_4 : OpCodes.Ldc_I4_8); + il.Emit(OpCodes.Ldc_I4, ClassFieldOffset); il.Emit(OpCodes.Conv_I); il.Emit(OpCodes.Add); il.Emit(OpCodes.Br, end); diff --git a/src/BizHawk.BizInvoke/BizInvokerUtilities.cs b/src/BizHawk.BizInvoke/BizInvokerUtilities.cs new file mode 100644 index 0000000000..a07a40df86 --- /dev/null +++ b/src/BizHawk.BizInvoke/BizInvokerUtilities.cs @@ -0,0 +1,48 @@ +using System; +using System.Runtime.InteropServices; + +namespace BizHawk.BizInvoke +{ + public static unsafe class BizInvokerUtilities + { + [StructLayout(LayoutKind.Explicit)] + private class U + { + [FieldOffset(0)] + public U1 First; + [FieldOffset(0)] + public U2 Second; + } + [StructLayout(LayoutKind.Explicit)] + private class U1 + { + [FieldOffset(0)] + public UIntPtr P; + } + [StructLayout(LayoutKind.Explicit)] + private class U2 + { + [FieldOffset(0)] + public CF Target; + } + private class CF + { + public int FirstField; + } + /// + /// Didn't I have code somewhere else to do this already? + /// + /// + public static unsafe int ComputeClassFieldOffset() + { + var c = new CF(); + int ret; + fixed(int* fx = &c.FirstField) + { + var u = new U { Second = new U2 { Target = c }}; + ret = (int)((ulong)(UIntPtr)fx - (ulong)u.First.P); + } + return ret; + } + } +} diff --git a/src/BizHawk.Emulation.Cores/Waterbox/Syscalls/Syscalls.cs b/src/BizHawk.Emulation.Cores/Waterbox/Syscalls/Syscalls.cs index 1ed67b4bba..cf3b9e51c3 100644 --- a/src/BizHawk.Emulation.Cores/Waterbox/Syscalls/Syscalls.cs +++ b/src/BizHawk.Emulation.Cores/Waterbox/Syscalls/Syscalls.cs @@ -394,17 +394,17 @@ namespace BizHawk.Emulation.Cores.Waterbox } [StructLayout(LayoutKind.Sequential)] - public class TimeSpec + public struct TimeSpec { public long Seconds; public long NanoSeconds; } [BizExport(CallingConvention.Cdecl, EntryPoint = "__wsyscalltab[228]")] - public int SysClockGetTime(int which, [In, Out] TimeSpec time) + public unsafe int SysClockGetTime(int which, TimeSpec* time) { - time.Seconds = 1495889068; - time.NanoSeconds = 0; + time->Seconds = 1495889068; + time->NanoSeconds = 0; return 0; }