MethodBridgeSig.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. using System.Text.RegularExpressions;
  7. using System.Threading.Tasks;
  8. namespace HybridCLR.Generators.MethodBridge
  9. {
  10. public class MethodBridgeSig : IEquatable<MethodBridgeSig>
  11. {
  12. private readonly static Regex s_sigPattern = new Regex(@"^(v|i1|i2|i4|i8|r4|r8|i16|sr|vf2|vf3|vf4|vd2|vd3|vd4|S\d+|A\d+|B\d+|C\d+)+$");
  13. public static MethodBridgeSig CreateBySignatuer(string sigName)
  14. {
  15. var re = s_sigPattern.Match(sigName);
  16. if (!re.Success)
  17. {
  18. throw new ArgumentException($"{sigName} is not valid signature");
  19. }
  20. var mbs = new MethodBridgeSig() { ParamInfos = new List<ParamInfo>()};
  21. var sigs = re.Groups[1].Captures;
  22. mbs.ReturnInfo = new ReturnInfo() { Type = CreateTypeInfoBySignature(sigs[0].Value)};
  23. for(int i = 1; i < sigs.Count; i++)
  24. {
  25. mbs.ParamInfos.Add(new ParamInfo() { Type = CreateTypeInfoBySignature(sigs[i].Value)});
  26. }
  27. return mbs;
  28. }
  29. private static TypeInfo CreateTypeInfoBySignature(string sigName)
  30. {
  31. switch(sigName)
  32. {
  33. case "v": return new TypeInfo(typeof(void), ParamOrReturnType.VOID);
  34. case "i1": return new TypeInfo(typeof(sbyte), ParamOrReturnType.I1_U1);
  35. case "i2": return new TypeInfo(typeof(short), ParamOrReturnType.I2_U2);
  36. case "i4": return new TypeInfo(typeof(int), ParamOrReturnType.I4_U4);
  37. case "i8": return new TypeInfo(typeof(long), ParamOrReturnType.I8_U8);
  38. case "r4": return new TypeInfo(typeof(float), ParamOrReturnType.R4);
  39. case "r8": return new TypeInfo(typeof(double), ParamOrReturnType.R8);
  40. case "i16": return TypeInfo.s_i16;
  41. case "sr": return TypeInfo.s_ref;
  42. case "vf2": return new TypeInfo(null, ParamOrReturnType.ARM64_HFA_FLOAT_2);
  43. case "vf3": return new TypeInfo(null, ParamOrReturnType.ARM64_HFA_FLOAT_3);
  44. case "vf4": return new TypeInfo(null, ParamOrReturnType.ARM64_HFA_FLOAT_4);
  45. case "vd2": return new TypeInfo(null, ParamOrReturnType.ARM64_HFA_DOUBLE_2);
  46. case "vd3": return new TypeInfo(null, ParamOrReturnType.ARM64_HFA_DOUBLE_3);
  47. case "vd4": return new TypeInfo(null, ParamOrReturnType.ARM64_HFA_DOUBLE_4);
  48. default:
  49. {
  50. if (sigName.StartsWith("S"))
  51. {
  52. return new TypeInfo(null, ParamOrReturnType.STRUCTURE_ALIGN1, int.Parse(sigName.Substring(1)));
  53. }
  54. if (sigName.StartsWith("A"))
  55. {
  56. return new TypeInfo(null, ParamOrReturnType.STRUCTURE_ALIGN2, int.Parse(sigName.Substring(1)));
  57. }
  58. if (sigName.StartsWith("B"))
  59. {
  60. return new TypeInfo(null, ParamOrReturnType.STRUCTURE_ALIGN4, int.Parse(sigName.Substring(1)));
  61. }
  62. if (sigName.StartsWith("C"))
  63. {
  64. return new TypeInfo(null, ParamOrReturnType.STRUCTURE_ALIGN8, int.Parse(sigName.Substring(1)));
  65. }
  66. throw new ArgumentException($"invalid signature:{sigName}");
  67. }
  68. }
  69. }
  70. public ReturnInfo ReturnInfo { get; set; }
  71. public List<ParamInfo> ParamInfos { get; set; }
  72. public void Init()
  73. {
  74. for(int i = 0; i < ParamInfos.Count; i++)
  75. {
  76. ParamInfos[i].Index = i;
  77. }
  78. }
  79. public string CreateCallSigName()
  80. {
  81. var n = new StringBuilder();
  82. n.Append(ReturnInfo.Type.CreateSigName());
  83. foreach(var param in ParamInfos)
  84. {
  85. n.Append(param.Type.CreateSigName());
  86. }
  87. return n.ToString();
  88. }
  89. public string CreateInvokeSigName()
  90. {
  91. var n = new StringBuilder();
  92. n.Append(ReturnInfo.Type.CreateSigName());
  93. foreach (var param in ParamInfos)
  94. {
  95. n.Append(param.Type.CreateSigName());
  96. }
  97. return n.ToString();
  98. }
  99. public override bool Equals(object obj)
  100. {
  101. return Equals((MethodBridgeSig)obj);
  102. }
  103. public bool Equals(MethodBridgeSig other)
  104. {
  105. if (other == null)
  106. {
  107. return false;
  108. }
  109. if (!ReturnInfo.Type.Equals(other.ReturnInfo.Type))
  110. {
  111. return false;
  112. }
  113. if (ParamInfos.Count != other.ParamInfos.Count)
  114. {
  115. return false;
  116. }
  117. for(int i = 0; i < ParamInfos.Count; i++)
  118. {
  119. if (!ParamInfos[i].Type.Equals(other.ParamInfos[i].Type))
  120. {
  121. return false;
  122. }
  123. }
  124. return true;
  125. }
  126. public override int GetHashCode()
  127. {
  128. int hash = 17;
  129. hash = hash * 23 + ReturnInfo.Type.GetHashCode();
  130. foreach(var p in ParamInfos)
  131. {
  132. hash = hash * 23 + p.Type.GetHashCode();
  133. }
  134. return hash;
  135. }
  136. }
  137. }