diff --git a/src/ARMeilleure/Instructions/InstEmitException.cs b/src/ARMeilleure/Instructions/InstEmitException.cs index d30fb2fbd..c8355eb62 100644 --- a/src/ARMeilleure/Instructions/InstEmitException.cs +++ b/src/ARMeilleure/Instructions/InstEmitException.cs @@ -7,15 +7,17 @@ namespace ARMeilleure.Instructions { static partial class InstEmit { + private const string SupervisorCallName = nameof(NativeInterface.SupervisorCall); + private const string BreakName = nameof(NativeInterface.Break); + private const string UndefinedName = nameof(NativeInterface.Undefined); + public static void Brk(ArmEmitterContext context) { OpCodeException op = (OpCodeException)context.CurrOp; - string name = nameof(NativeInterface.Break); - context.StoreToContext(); - context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.Id)); + context.Call(NativeInterface.Type.GetMethod(BreakName), Const(op.Address), Const(op.Id)); context.LoadFromContext(); @@ -25,12 +27,10 @@ namespace ARMeilleure.Instructions public static void Svc(ArmEmitterContext context) { OpCodeException op = (OpCodeException)context.CurrOp; - - string name = nameof(NativeInterface.SupervisorCall); - + context.StoreToContext(); - context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.Id)); + context.Call(NativeInterface.Type.GetMethod(SupervisorCallName), Const(op.Address), Const(op.Id)); context.LoadFromContext(); @@ -41,11 +41,9 @@ namespace ARMeilleure.Instructions { OpCode op = context.CurrOp; - string name = nameof(NativeInterface.Undefined); - context.StoreToContext(); - context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.RawOpCode)); + context.Call(NativeInterface.Type.GetMethod(UndefinedName), Const(op.Address), Const(op.RawOpCode)); context.LoadFromContext(); diff --git a/src/ARMeilleure/Instructions/InstEmitException32.cs b/src/ARMeilleure/Instructions/InstEmitException32.cs index 57af1522b..3e34b9fec 100644 --- a/src/ARMeilleure/Instructions/InstEmitException32.cs +++ b/src/ARMeilleure/Instructions/InstEmitException32.cs @@ -14,7 +14,7 @@ namespace ARMeilleure.Instructions context.StoreToContext(); - context.Call(typeof(NativeInterface).GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id)); + context.Call(NativeInterface.Type.GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id)); context.LoadFromContext(); @@ -29,7 +29,7 @@ namespace ARMeilleure.Instructions context.StoreToContext(); - context.Call(typeof(NativeInterface).GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id)); + context.Call(NativeInterface.Type.GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id)); context.LoadFromContext(); diff --git a/src/ARMeilleure/Instructions/InstEmitMemoryHelper.cs b/src/ARMeilleure/Instructions/InstEmitMemoryHelper.cs index ace6fe1ce..271b61e68 100644 --- a/src/ARMeilleure/Instructions/InstEmitMemoryHelper.cs +++ b/src/ARMeilleure/Instructions/InstEmitMemoryHelper.cs @@ -478,7 +478,7 @@ namespace ARMeilleure.Instructions context.BranchIf(lblNotWatched, pte, Const(0L), Comparison.GreaterOrEqual, BasicBlockFrequency.Cold); // Signal memory tracking. Size here doesn't matter as address is assumed to be size aligned here. - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)), address, Const(1UL), Const(write ? 1 : 0)); + context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.SignalMemoryTracking)), address, Const(1UL), Const(write ? 1 : 0)); context.MarkLabel(lblNotWatched); pte = context.BitwiseAnd(pte, Const(0xffffffffffffUL)); // Ignore any software protection bits. (they are still used by C# memory access) @@ -489,7 +489,7 @@ namespace ARMeilleure.Instructions context.BranchIfTrue(lblNonNull, pte, BasicBlockFrequency.Cold); // The call is not expected to return (it should throw). - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)), address); + context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess)), address); context.MarkLabel(lblNonNull); } @@ -535,16 +535,16 @@ namespace ARMeilleure.Instructions switch (size) { case 0: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadByte)); break; case 1: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt16)); break; case 2: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt32)); break; case 3: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt64)); break; } @@ -564,19 +564,19 @@ namespace ARMeilleure.Instructions switch (size) { case 0: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadByte)); break; case 1: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt16)); break; case 2: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt32)); break; case 3: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt64)); break; case 4: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadVector128)); break; } @@ -608,16 +608,16 @@ namespace ARMeilleure.Instructions switch (size) { case 0: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteByte)); break; case 1: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt16)); break; case 2: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt32)); break; case 3: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt64)); break; } @@ -643,19 +643,19 @@ namespace ARMeilleure.Instructions switch (size) { case 0: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteByte)); break; case 1: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt16)); break; case 2: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt32)); break; case 3: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt64)); break; case 4: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteVector128)); break; } diff --git a/src/ARMeilleure/Instructions/InstEmitSystem.cs b/src/ARMeilleure/Instructions/InstEmitSystem.cs index 11c1d0328..10e96dec9 100644 --- a/src/ARMeilleure/Instructions/InstEmitSystem.cs +++ b/src/ARMeilleure/Instructions/InstEmitSystem.cs @@ -29,10 +29,10 @@ namespace ARMeilleure.Instructions switch (GetPackedId(op)) { case 0b11_011_0000_0000_001: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCtrEl0)); break; case 0b11_011_0000_0000_111: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.GetDczidEl0)); break; case 0b11_011_0100_0010_000: EmitGetNzcv(context); @@ -53,13 +53,13 @@ namespace ARMeilleure.Instructions EmitGetTpidr2El0(context); return; case 0b11_011_1110_0000_000: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntfrqEl0)); break; case 0b11_011_1110_0000_001: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntpctEl0)); break; case 0b11_011_1110_0000_010: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)); + info = NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntvctEl0)); break; default: @@ -131,7 +131,7 @@ namespace ARMeilleure.Instructions case 0b11_011_0111_0101_001: // IC IVAU Operand target = Register(op.Rt, RegisterType.Integer, OperandType.I64); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine)), target); + context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.InvalidateCacheLine)), target); break; } } diff --git a/src/ARMeilleure/Instructions/InstEmitSystem32.cs b/src/ARMeilleure/Instructions/InstEmitSystem32.cs index 74d6169c6..809362681 100644 --- a/src/ARMeilleure/Instructions/InstEmitSystem32.cs +++ b/src/ARMeilleure/Instructions/InstEmitSystem32.cs @@ -127,7 +127,7 @@ namespace ARMeilleure.Instructions // Timer. 14 => opc switch { - 0 => typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)), + 0 => NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntpctEl0)), _ => throw new NotImplementedException($"Unknown MRRC Opc1 0x{opc:X} at 0x{op.Address:X} (0x{op.RawOpCode:X})."), }, _ => throw new NotImplementedException($"Unknown MRRC 0x{op.RawOpCode:X} at 0x{op.Address:X}."), diff --git a/src/ARMeilleure/Instructions/NativeInterface.cs b/src/ARMeilleure/Instructions/NativeInterface.cs index 9d6279613..98539e49c 100644 --- a/src/ARMeilleure/Instructions/NativeInterface.cs +++ b/src/ARMeilleure/Instructions/NativeInterface.cs @@ -2,12 +2,32 @@ using ARMeilleure.Memory; using ARMeilleure.State; using ARMeilleure.Translation; using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace ARMeilleure.Instructions { static class NativeInterface { + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + public static readonly Type Type = typeof(NativeInterface); + + static NativeInterface() + { + try + { + //TODO: + // dude. this is so bad. figure out AOT's bs. + // this needs to be compiled into the AOT build but it doesn't get compiled + // under any circumstances unless directly referenced like below, not dynamically which is how it's always used. + _ = GetFunctionAddress(0); + } + catch + { + + } + } + private class ThreadContext { public ExecutionContext Context { get; } @@ -178,8 +198,7 @@ namespace ARMeilleure.Instructions { throw new InvalidAccessException(address); } - - [UnmanagedCallersOnly] + public static ulong GetFunctionAddress(ulong address) { TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode); diff --git a/src/ARMeilleure/Translation/Delegates.cs b/src/ARMeilleure/Translation/Delegates.cs index d4f46108c..d83f7ebbd 100644 --- a/src/ARMeilleure/Translation/Delegates.cs +++ b/src/ARMeilleure/Translation/Delegates.cs @@ -1,6 +1,7 @@ using ARMeilleure.Instructions; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace ARMeilleure.Translation @@ -62,7 +63,7 @@ namespace ARMeilleure.Translation } private static readonly SortedList _delegates; - + static Delegates() { _delegates = new SortedList(); @@ -79,30 +80,30 @@ namespace ARMeilleure.Translation SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Round))); SetDelegateInfo(typeof(MathHelperF).GetMethod(nameof(MathHelperF.Truncate))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Break))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.Undefined))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteByte))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt16))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt32))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.Break))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.CheckSynchronization))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.EnqueueForRejit))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntfrqEl0))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntpctEl0))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCntvctEl0))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetCtrEl0))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetDczidEl0))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetFunctionAddress))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.InvalidateCacheLine))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadByte))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt16))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt32))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadUInt64))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ReadVector128))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.SignalMemoryTracking))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.SupervisorCall))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.Undefined))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteByte))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt16))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt32))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteUInt64))); + SetDelegateInfo(NativeInterface.Type.GetMethod(nameof(NativeInterface.WriteVector128))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros))); diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index 14c80f24b..3d7826e96 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -457,7 +457,7 @@ namespace ARMeilleure.Translation context.Store(address, count); context.BranchIf(lblEnd, curCount, Const(MinsCallForRejit), Comparison.NotEqual, BasicBlockFrequency.Cold); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit)), Const(context.EntryAddress)); + context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.EnqueueForRejit)), Const(context.EntryAddress)); context.MarkLabel(lblEnd); } @@ -473,7 +473,7 @@ namespace ARMeilleure.Translation Operand count = context.Load(OperandType.I32, countAddr); context.BranchIfTrue(lblNonZero, count, BasicBlockFrequency.Cold); - Operand running = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization))); + Operand running = context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.CheckSynchronization))); context.BranchIfTrue(lblExit, running, BasicBlockFrequency.Cold); context.Return(Const(0L)); diff --git a/src/ARMeilleure/Translation/TranslatorStubs.cs b/src/ARMeilleure/Translation/TranslatorStubs.cs index 458a42434..571725a5b 100644 --- a/src/ARMeilleure/Translation/TranslatorStubs.cs +++ b/src/ARMeilleure/Translation/TranslatorStubs.cs @@ -4,6 +4,7 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation.Cache; using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; @@ -181,7 +182,7 @@ namespace ARMeilleure.Translation context.Tailcall(hostAddress, nativeContext); context.MarkLabel(lblFallback); - hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress); + hostAddress = context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress); context.Tailcall(hostAddress, nativeContext); ControlFlowGraph cfg = context.GetControlFlowGraph(); @@ -206,7 +207,7 @@ namespace ARMeilleure.Translation Operand guestAddress = context.Load(OperandType.I64, context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset()))); - Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress); + Operand hostAddress = context.Call(NativeInterface.Type.GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress); context.Tailcall(hostAddress, nativeContext); ControlFlowGraph cfg = context.GetControlFlowGraph();