PlatformGeneratorArm64.cs 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. using dnlib.DotNet;
  2. using HybridCLR.Editor.ABI;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using UnityEngine;
  10. namespace HybridCLR.Editor.MethodBridge
  11. {
  12. public class PlatformGeneratorArm64 : PlatformGeneratorBase
  13. {
  14. public override PlatformABI PlatformABI { get; } = PlatformABI.Universal64;
  15. public override void GenerateManaged2NativeMethod(MethodDesc method, List<string> lines)
  16. {
  17. int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI);
  18. string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
  19. string paramNameListStr = string.Join(", ", method.ParamInfos.Select(p => p.Managed2NativeParamValue(this.PlatformABI)).Concat(new string[] { "method" }));
  20. lines.Add($@"
  21. // {method.MethodDef}
  22. static void __M2N_{method.CreateCallSigName()}(const MethodInfo* method, uint16_t* argVarIndexs, StackObject* localVarBase, void* ret)
  23. {{
  24. typedef {method.ReturnInfo.Type.GetTypeName()} (*NativeMethod)({paramListStr});
  25. {(!method.ReturnInfo.IsVoid ? $"*({method.ReturnInfo.Type.GetTypeName()}*)ret = " : "")}((NativeMethod)(method->methodPointerCallByInterp))({paramNameListStr});
  26. }}
  27. ");
  28. }
  29. public override void GenerateNative2ManagedMethod(MethodDesc method, List<string> lines)
  30. {
  31. int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI);
  32. string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
  33. lines.Add($@"
  34. // {method.MethodDef}
  35. static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()}({paramListStr})
  36. {{
  37. StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => p.Native2ManagedParamValue(this.PlatformABI)))} }};
  38. StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)};
  39. Interpreter::Execute(method, args, ret);
  40. {(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")}
  41. }}
  42. ");
  43. }
  44. public override void GenerateAdjustThunkMethod(MethodDesc method, List<string> lines)
  45. {
  46. int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI);
  47. string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
  48. lines.Add($@"
  49. // {method.MethodDef}
  50. static {method.ReturnInfo.Type.GetTypeName()} __N2M_AdjustorThunk_{method.CreateCallSigName()}({paramListStr})
  51. {{
  52. StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => (p.Index == 0 ? $"(uint64_t)(*(uint8_t**)&__arg{p.Index} + sizeof(Il2CppObject))" : p.Native2ManagedParamValue(this.PlatformABI))))} }};
  53. StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)};
  54. Interpreter::Execute(method, args, ret);
  55. {(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")}
  56. }}
  57. ");
  58. }
  59. }
  60. }