/ src / ARMeilleure / Signal / TestMethods.cs
TestMethods.cs
 1  using ARMeilleure.IntermediateRepresentation;
 2  using ARMeilleure.Translation;
 3  using System;
 4  using System.Runtime.InteropServices;
 5  using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
 6  
 7  namespace ARMeilleure.Signal
 8  {
 9      public struct NativeWriteLoopState
10      {
11          public int Running;
12          public int Error;
13      }
14  
15      public static class TestMethods
16      {
17          public delegate bool DebugPartialUnmap();
18          public delegate int DebugThreadLocalMapGetOrReserve(int threadId, int initialState);
19          public delegate void DebugNativeWriteLoop(IntPtr nativeWriteLoopPtr, IntPtr writePtr);
20  
21          public static DebugPartialUnmap GenerateDebugPartialUnmap()
22          {
23              EmitterContext context = new();
24  
25              var result = WindowsPartialUnmapHandler.EmitRetryFromAccessViolation(context);
26  
27              context.Return(result);
28  
29              // Compile and return the function.
30  
31              ControlFlowGraph cfg = context.GetControlFlowGraph();
32  
33              OperandType[] argTypes = new OperandType[] { OperandType.I64 };
34  
35              return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugPartialUnmap>();
36          }
37  
38          public static DebugThreadLocalMapGetOrReserve GenerateDebugThreadLocalMapGetOrReserve(IntPtr structPtr)
39          {
40              EmitterContext context = new();
41  
42              var result = WindowsPartialUnmapHandler.EmitThreadLocalMapIntGetOrReserve(context, structPtr, context.LoadArgument(OperandType.I32, 0), context.LoadArgument(OperandType.I32, 1));
43  
44              context.Return(result);
45  
46              // Compile and return the function.
47  
48              ControlFlowGraph cfg = context.GetControlFlowGraph();
49  
50              OperandType[] argTypes = new OperandType[] { OperandType.I64 };
51  
52              return Compiler.Compile(cfg, argTypes, OperandType.I32, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugThreadLocalMapGetOrReserve>();
53          }
54  
55          public static DebugNativeWriteLoop GenerateDebugNativeWriteLoop()
56          {
57              EmitterContext context = new();
58  
59              // Loop a write to the target address until "running" is false.
60  
61              Operand structPtr = context.Copy(context.LoadArgument(OperandType.I64, 0));
62              Operand writePtr = context.Copy(context.LoadArgument(OperandType.I64, 1));
63  
64              Operand loopLabel = Label();
65              context.MarkLabel(loopLabel);
66  
67              context.Store(writePtr, Const(12345));
68  
69              Operand running = context.Load(OperandType.I32, structPtr);
70  
71              context.BranchIfTrue(loopLabel, running);
72  
73              context.Return();
74  
75              // Compile and return the function.
76  
77              ControlFlowGraph cfg = context.GetControlFlowGraph();
78  
79              OperandType[] argTypes = new OperandType[] { OperandType.I64 };
80  
81              return Compiler.Compile(cfg, argTypes, OperandType.None, CompilerOptions.HighCq, RuntimeInformation.ProcessArchitecture).Map<DebugNativeWriteLoop>();
82          }
83      }
84  }