TestMethods.cs 2.9 KB

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