PlatformGeneratorUniversal64.cs 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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. using TypeInfo = HybridCLR.Editor.ABI.TypeInfo;
  11. namespace HybridCLR.Editor.MethodBridge
  12. {
  13. public class PlatformGeneratorUniversal64 : PlatformGeneratorBase
  14. {
  15. public override PlatformABI PlatformABI { get; } = PlatformABI.Universal64;
  16. public override void GenerateManaged2NativeMethod(MethodDesc method, List<string> lines)
  17. {
  18. int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI);
  19. string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
  20. string paramTypeListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()}").Concat(new string[] { "const MethodInfo*" })); ;
  21. string paramNameListStr = string.Join(", ", method.ParamInfos.Select(p => p.Managed2NativeParamValue(this.PlatformABI)).Concat(new string[] { "method" }));
  22. lines.Add($@"
  23. // {method.MethodDef}
  24. static void __M2N_{method.CreateCallSigName()}(const MethodInfo* method, uint16_t* argVarIndexs, StackObject* localVarBase, void* ret)
  25. {{
  26. typedef {method.ReturnInfo.Type.GetTypeName()} (*NativeMethod)({paramListStr});
  27. {(!method.ReturnInfo.IsVoid ? $"*({method.ReturnInfo.Type.GetTypeName()}*)ret = " : "")}((NativeMethod)(method->methodPointerCallByInterp))({paramNameListStr});
  28. }}
  29. ");
  30. }
  31. public override void GenerateNative2ManagedMethod(MethodDesc method, List<string> lines)
  32. {
  33. int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI);
  34. string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
  35. lines.Add($@"
  36. // {method.MethodDef}
  37. static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()}({paramListStr})
  38. {{
  39. StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => p.Native2ManagedParamValue(this.PlatformABI)))} }};
  40. StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)};
  41. Interpreter::Execute(method, args, ret);
  42. {(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")}
  43. }}
  44. ");
  45. }
  46. public override void GenerateAdjustThunkMethod(MethodDesc method, List<string> lines)
  47. {
  48. int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI);
  49. string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
  50. lines.Add($@"
  51. // {method.MethodDef}
  52. static {method.ReturnInfo.Type.GetTypeName()} __N2M_AdjustorThunk_{method.CreateCallSigName()}({paramListStr})
  53. {{
  54. 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))))} }};
  55. StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)};
  56. Interpreter::Execute(method, args, ret);
  57. {(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")}
  58. }}
  59. ");
  60. }
  61. }
  62. }