[new] add Managed2NativeFunctionPointer MethodBridge functions
parent
b176d63d93
commit
45749ffb5c
|
|
@ -31,7 +31,7 @@ namespace HybridCLR.Editor.Commands
|
||||||
Directory.Delete(il2cppBuildCachePath, true);
|
Directory.Delete(il2cppBuildCachePath, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateMethodBridgeCppFile(IReadOnlyCollection<GenericMethod> genericMethods, List<RawReversePInvokeMethodInfo> reversePInvokeMethods, string outputFile)
|
private static void GenerateMethodBridgeCppFile(IReadOnlyCollection<GenericMethod> genericMethods, List<RawReversePInvokeMethodInfo> reversePInvokeMethods, IReadOnlyCollection<RawCalliMethodSignatureInfo> calliMethodSignatures, string outputFile)
|
||||||
{
|
{
|
||||||
string templateCode = File.ReadAllText(outputFile, Encoding.UTF8);
|
string templateCode = File.ReadAllText(outputFile, Encoding.UTF8);
|
||||||
var g = new Generator(new Generator.Options()
|
var g = new Generator(new Generator.Options()
|
||||||
|
|
@ -40,6 +40,7 @@ namespace HybridCLR.Editor.Commands
|
||||||
OutputFile = outputFile,
|
OutputFile = outputFile,
|
||||||
GenericMethods = genericMethods,
|
GenericMethods = genericMethods,
|
||||||
ReversePInvokeMethods = reversePInvokeMethods,
|
ReversePInvokeMethods = reversePInvokeMethods,
|
||||||
|
CalliMethodSignatures = calliMethodSignatures,
|
||||||
Development = EditorUserBuildSettings.development,
|
Development = EditorUserBuildSettings.development,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -80,9 +81,12 @@ namespace HybridCLR.Editor.Commands
|
||||||
var reversePInvokeAnalyzer = new ReversePInvokeWrap.Analyzer(cache, hotUpdateDlls);
|
var reversePInvokeAnalyzer = new ReversePInvokeWrap.Analyzer(cache, hotUpdateDlls);
|
||||||
reversePInvokeAnalyzer.Run();
|
reversePInvokeAnalyzer.Run();
|
||||||
|
|
||||||
|
var calliAnalyzer = new CalliAnalyzer(cache, hotUpdateDlls);
|
||||||
|
calliAnalyzer.Run();
|
||||||
|
|
||||||
string outputFile = $"{SettingsUtil.GeneratedCppDir}/MethodBridge.cpp";
|
string outputFile = $"{SettingsUtil.GeneratedCppDir}/MethodBridge.cpp";
|
||||||
|
|
||||||
GenerateMethodBridgeCppFile(methodBridgeAnalyzer.GenericMethods, reversePInvokeAnalyzer.ReversePInvokeMethods, outputFile);
|
GenerateMethodBridgeCppFile(methodBridgeAnalyzer.GenericMethods, reversePInvokeAnalyzer.ReversePInvokeMethods, calliAnalyzer.CalliMethodSignatures, outputFile);
|
||||||
|
|
||||||
CleanIl2CppBuildCache();
|
CleanIl2CppBuildCache();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
using dnlib.DotNet;
|
||||||
|
using HybridCLR.Editor.Meta;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace HybridCLR.Editor.MethodBridge
|
||||||
|
{
|
||||||
|
|
||||||
|
public class RawCalliMethodSignatureInfo
|
||||||
|
{
|
||||||
|
public MethodSig MethodSig { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CalliAnalyzer
|
||||||
|
{
|
||||||
|
private readonly List<ModuleDefMD> _rootModules = new List<ModuleDefMD>();
|
||||||
|
|
||||||
|
private readonly List<RawCalliMethodSignatureInfo> _calliMethodSignatures = new List<RawCalliMethodSignatureInfo>();
|
||||||
|
|
||||||
|
public List<RawCalliMethodSignatureInfo> CalliMethodSignatures => _calliMethodSignatures;
|
||||||
|
|
||||||
|
public CalliAnalyzer(AssemblyCache cache, List<string> assemblyNames)
|
||||||
|
{
|
||||||
|
foreach (var assemblyName in assemblyNames)
|
||||||
|
{
|
||||||
|
_rootModules.Add(cache.LoadModule(assemblyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CollectCalli()
|
||||||
|
{
|
||||||
|
foreach (var mod in _rootModules)
|
||||||
|
{
|
||||||
|
Debug.Log($"ass:{mod.FullName} methodcount:{mod.Metadata.TablesStream.MethodTable.Rows}");
|
||||||
|
for (uint rid = 1, n = mod.Metadata.TablesStream.MethodTable.Rows; rid <= n; rid++)
|
||||||
|
{
|
||||||
|
var method = mod.ResolveMethod(rid);
|
||||||
|
//Debug.Log($"method:{method}");
|
||||||
|
if (!method.HasBody)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var il in method.Body.Instructions)
|
||||||
|
{
|
||||||
|
if (il.OpCode.Code == dnlib.DotNet.Emit.Code.Calli)
|
||||||
|
{
|
||||||
|
MethodSig methodSig = (MethodSig)il.Operand;
|
||||||
|
|
||||||
|
_calliMethodSignatures.Add(new RawCalliMethodSignatureInfo()
|
||||||
|
{
|
||||||
|
MethodSig = methodSig,
|
||||||
|
});
|
||||||
|
Debug.Log($"method:{method} calli method signature:{methodSig}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
CollectCalli();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6ce33c8e48da5a649b261ba3a60fd3b9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -15,7 +15,6 @@ using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using TypeInfo = HybridCLR.Editor.ABI.TypeInfo;
|
using TypeInfo = HybridCLR.Editor.ABI.TypeInfo;
|
||||||
using CallingConvention = System.Runtime.InteropServices.CallingConvention;
|
using CallingConvention = System.Runtime.InteropServices.CallingConvention;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using TypeAttributes = dnlib.DotNet.TypeAttributes;
|
using TypeAttributes = dnlib.DotNet.TypeAttributes;
|
||||||
|
|
||||||
namespace HybridCLR.Editor.MethodBridge
|
namespace HybridCLR.Editor.MethodBridge
|
||||||
|
|
@ -32,13 +31,37 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
|
|
||||||
public List<RawReversePInvokeMethodInfo> ReversePInvokeMethods { get; set; }
|
public List<RawReversePInvokeMethodInfo> ReversePInvokeMethods { get; set; }
|
||||||
|
|
||||||
|
public IReadOnlyCollection<RawCalliMethodSignatureInfo> CalliMethodSignatures { get; set; }
|
||||||
|
|
||||||
public bool Development { get; set; }
|
public bool Development { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ABIReversePInvokeMethodInfo
|
||||||
|
{
|
||||||
|
public MethodDesc Method { get; set; }
|
||||||
|
|
||||||
|
public CallingConvention Callvention { get; set; }
|
||||||
|
|
||||||
|
public int Count { get; set; }
|
||||||
|
|
||||||
|
public string Signature { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CalliMethodInfo
|
||||||
|
{
|
||||||
|
public MethodDesc Method { get; set; }
|
||||||
|
|
||||||
|
public CallingConvention Callvention { get; set; }
|
||||||
|
|
||||||
|
public string Signature { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
private readonly List<GenericMethod> _genericMethods;
|
private readonly List<GenericMethod> _genericMethods;
|
||||||
|
|
||||||
private readonly List<RawReversePInvokeMethodInfo> _originalReversePInvokeMethods;
|
private readonly List<RawReversePInvokeMethodInfo> _originalReversePInvokeMethods;
|
||||||
|
|
||||||
|
private readonly List<RawCalliMethodSignatureInfo> _originalCalliMethodSignatures;
|
||||||
|
|
||||||
private readonly string _templateCode;
|
private readonly string _templateCode;
|
||||||
|
|
||||||
private readonly string _outputFile;
|
private readonly string _outputFile;
|
||||||
|
|
@ -55,12 +78,15 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
|
|
||||||
private List<ABIReversePInvokeMethodInfo> _reversePInvokeMethods;
|
private List<ABIReversePInvokeMethodInfo> _reversePInvokeMethods;
|
||||||
|
|
||||||
|
private List<CalliMethodInfo> _callidMethods;
|
||||||
|
|
||||||
public Generator(Options options)
|
public Generator(Options options)
|
||||||
{
|
{
|
||||||
List<(GenericMethod, string)> genericMethodInfo = options.GenericMethods.Select(m => (m, m.ToString())).ToList();
|
List<(GenericMethod, string)> genericMethodInfo = options.GenericMethods.Select(m => (m, m.ToString())).ToList();
|
||||||
genericMethodInfo.Sort((a, b) => string.CompareOrdinal(a.Item2, b.Item2));
|
genericMethodInfo.Sort((a, b) => string.CompareOrdinal(a.Item2, b.Item2));
|
||||||
_genericMethods = genericMethodInfo.Select(m => m.Item1).ToList();
|
_genericMethods = genericMethodInfo.Select(m => m.Item1).ToList();
|
||||||
_originalReversePInvokeMethods = options.ReversePInvokeMethods;
|
_originalReversePInvokeMethods = options.ReversePInvokeMethods;
|
||||||
|
_originalCalliMethodSignatures = options.CalliMethodSignatures.ToList();
|
||||||
|
|
||||||
_templateCode = options.TemplateCode;
|
_templateCode = options.TemplateCode;
|
||||||
_outputFile = options.OutputFile;
|
_outputFile = options.OutputFile;
|
||||||
|
|
@ -114,6 +140,30 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
return mbs;
|
return mbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MethodDesc CreateMethodDesc(TypeSig returnType, List<TypeSig> parameters)
|
||||||
|
{
|
||||||
|
var paramInfos = new List<ParamInfo>();
|
||||||
|
if (returnType.ContainsGenericParameter)
|
||||||
|
{
|
||||||
|
throw new Exception($"[PreservedMethod] method has generic parameters");
|
||||||
|
}
|
||||||
|
foreach (var paramInfo in parameters)
|
||||||
|
{
|
||||||
|
if (paramInfo.ContainsGenericParameter)
|
||||||
|
{
|
||||||
|
throw new Exception($"[PreservedMethod] method has generic parameters");
|
||||||
|
}
|
||||||
|
paramInfos.Add(new ParamInfo() { Type = GetSharedTypeInfo(paramInfo) });
|
||||||
|
}
|
||||||
|
var mbs = new MethodDesc()
|
||||||
|
{
|
||||||
|
MethodDef = null,
|
||||||
|
ReturnInfo = new ReturnInfo() { Type = returnType != null ? GetSharedTypeInfo(returnType) : TypeInfo.s_void },
|
||||||
|
ParamInfos = paramInfos,
|
||||||
|
};
|
||||||
|
return mbs;
|
||||||
|
}
|
||||||
|
|
||||||
private void AddManaged2NativeMethod(MethodDesc method)
|
private void AddManaged2NativeMethod(MethodDesc method)
|
||||||
{
|
{
|
||||||
method.Init();
|
method.Init();
|
||||||
|
|
@ -422,11 +472,16 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static string MakeSignature(MethodDesc desc, CallingConvention CallingConventionention)
|
private static string MakeReversePInvokeSignature(MethodDesc desc, CallingConvention CallingConventionention)
|
||||||
{
|
{
|
||||||
string convStr = ((char)('A' + (int)CallingConventionention - 1)).ToString();
|
string convStr = ((char)('A' + (int)CallingConventionention - 1)).ToString();
|
||||||
return $"{convStr}{desc.Sig}";
|
return $"{convStr}{desc.Sig}";
|
||||||
}
|
}
|
||||||
|
private static string MakeCalliSignature(MethodDesc desc, CallingConvention CallingConventionention)
|
||||||
|
{
|
||||||
|
string convStr = ((char)('A' + Math.Max((int)CallingConventionention - 1, 0))).ToString();
|
||||||
|
return $"{convStr}{desc.Sig}";
|
||||||
|
}
|
||||||
|
|
||||||
private static CallingConvention GetCallingConvention(MethodDef method)
|
private static CallingConvention GetCallingConvention(MethodDef method)
|
||||||
{
|
{
|
||||||
|
|
@ -479,7 +534,7 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
sharedMethod = ToIsomorphicMethod(sharedMethod);
|
sharedMethod = ToIsomorphicMethod(sharedMethod);
|
||||||
|
|
||||||
CallingConvention callingConv = GetCallingConvention(method.Method);
|
CallingConvention callingConv = GetCallingConvention(method.Method);
|
||||||
string signature = MakeSignature(sharedMethod, callingConv);
|
string signature = MakeReversePInvokeSignature(sharedMethod, callingConv);
|
||||||
|
|
||||||
if (!methodsBySig.TryGetValue(signature, out var arm))
|
if (!methodsBySig.TryGetValue(signature, out var arm))
|
||||||
{
|
{
|
||||||
|
|
@ -500,12 +555,46 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
return newMethods;
|
return newMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<CalliMethodInfo> BuildCalliMethods(List<RawCalliMethodSignatureInfo> rawMethods)
|
||||||
|
{
|
||||||
|
var methodsBySig = new Dictionary<string, CalliMethodInfo>();
|
||||||
|
foreach (var method in rawMethods)
|
||||||
|
{
|
||||||
|
var sharedMethod = new MethodDesc
|
||||||
|
{
|
||||||
|
MethodDef = null,
|
||||||
|
ReturnInfo = new ReturnInfo { Type = _typeCreator.CreateTypeInfo(method.MethodSig.RetType) },
|
||||||
|
ParamInfos = method.MethodSig.Params.Select(p => new ParamInfo { Type = _typeCreator.CreateTypeInfo(p) }).ToList(),
|
||||||
|
};
|
||||||
|
sharedMethod.Init();
|
||||||
|
sharedMethod = ToIsomorphicMethod(sharedMethod);
|
||||||
|
|
||||||
|
CallingConvention callingConv = (CallingConvention)(method.MethodSig.CallingConvention);
|
||||||
|
string signature = MakeCalliSignature(sharedMethod, callingConv);
|
||||||
|
|
||||||
|
if (!methodsBySig.TryGetValue(signature, out var arm))
|
||||||
|
{
|
||||||
|
arm = new CalliMethodInfo()
|
||||||
|
{
|
||||||
|
Method = sharedMethod,
|
||||||
|
Signature = signature,
|
||||||
|
Callvention = callingConv,
|
||||||
|
};
|
||||||
|
methodsBySig.Add(signature, arm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var newMethods = methodsBySig.Values.ToList();
|
||||||
|
newMethods.Sort((a, b) => string.CompareOrdinal(a.Signature, b.Signature));
|
||||||
|
return newMethods;
|
||||||
|
}
|
||||||
|
|
||||||
private void BuildOptimizedMethods()
|
private void BuildOptimizedMethods()
|
||||||
{
|
{
|
||||||
_managed2NativeMethodList = ToUniqueOrderedList(_managed2NativeMethodList0);
|
_managed2NativeMethodList = ToUniqueOrderedList(_managed2NativeMethodList0);
|
||||||
_native2ManagedMethodList = ToUniqueOrderedList(_native2ManagedMethodList0);
|
_native2ManagedMethodList = ToUniqueOrderedList(_native2ManagedMethodList0);
|
||||||
_adjustThunkMethodList = ToUniqueOrderedList(_adjustThunkMethodList0);
|
_adjustThunkMethodList = ToUniqueOrderedList(_adjustThunkMethodList0);
|
||||||
_reversePInvokeMethods = BuildABIMethods(_originalReversePInvokeMethods);
|
_reversePInvokeMethods = BuildABIMethods(_originalReversePInvokeMethods);
|
||||||
|
_callidMethods = BuildCalliMethods(_originalCalliMethodSignatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OptimizationTypesAndMethods()
|
private void OptimizationTypesAndMethods()
|
||||||
|
|
@ -562,6 +651,13 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
|
|
||||||
GenerateReversePInvokeWrappers(_reversePInvokeMethods, lines);
|
GenerateReversePInvokeWrappers(_reversePInvokeMethods, lines);
|
||||||
|
|
||||||
|
foreach (var method in _callidMethods)
|
||||||
|
{
|
||||||
|
GenerateManaged2NativeFunctionPointerMethod(method, lines);
|
||||||
|
}
|
||||||
|
GenerateManaged2NativeFunctionPointerMethodStub(_callidMethods, lines);
|
||||||
|
|
||||||
|
|
||||||
frr.Replace("CODE", string.Join("\n", lines));
|
frr.Replace("CODE", string.Join("\n", lines));
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(_outputFile));
|
Directory.CreateDirectory(Path.GetDirectoryName(_outputFile));
|
||||||
|
|
@ -778,9 +874,9 @@ const ReversePInvokeMethodData hybridclr::interpreter::g_reversePInvokeMethodStu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public const string SigOfObj = "u";
|
private const string SigOfObj = "u";
|
||||||
|
|
||||||
public static string ToFullName(TypeSig type)
|
private static string ToFullName(TypeSig type)
|
||||||
{
|
{
|
||||||
type = type.RemovePinnedAndModifiers();
|
type = type.RemovePinnedAndModifiers();
|
||||||
switch (type.ElementType)
|
switch (type.ElementType)
|
||||||
|
|
@ -875,7 +971,7 @@ const ReversePInvokeMethodData hybridclr::interpreter::g_reversePInvokeMethodStu
|
||||||
return $"{Path.GetFileNameWithoutExtension(typeDef.Module.Name)}:{typeDef.FullName}";
|
return $"{Path.GetFileNameWithoutExtension(typeDef.Module.Name)}:{typeDef.FullName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateStructureSignatureStub(List<TypeInfo> types, List<string> lines)
|
private void GenerateStructureSignatureStub(List<TypeInfo> types, List<string> lines)
|
||||||
{
|
{
|
||||||
lines.Add("const FullName2Signature hybridclr::interpreter::g_fullName2SignatureStub[] = {");
|
lines.Add("const FullName2Signature hybridclr::interpreter::g_fullName2SignatureStub[] = {");
|
||||||
foreach (var type in types)
|
foreach (var type in types)
|
||||||
|
|
@ -887,7 +983,7 @@ const ReversePInvokeMethodData hybridclr::interpreter::g_reversePInvokeMethodStu
|
||||||
lines.Add("};");
|
lines.Add("};");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateManaged2NativeStub(List<MethodDesc> methods, List<string> lines)
|
private void GenerateManaged2NativeStub(List<MethodDesc> methods, List<string> lines)
|
||||||
{
|
{
|
||||||
lines.Add($@"
|
lines.Add($@"
|
||||||
const Managed2NativeMethodInfo hybridclr::interpreter::g_managed2nativeStub[] =
|
const Managed2NativeMethodInfo hybridclr::interpreter::g_managed2nativeStub[] =
|
||||||
|
|
@ -903,7 +999,7 @@ const Managed2NativeMethodInfo hybridclr::interpreter::g_managed2nativeStub[] =
|
||||||
lines.Add("};");
|
lines.Add("};");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateNative2ManagedStub(List<MethodDesc> methods, List<string> lines)
|
private void GenerateNative2ManagedStub(List<MethodDesc> methods, List<string> lines)
|
||||||
{
|
{
|
||||||
lines.Add($@"
|
lines.Add($@"
|
||||||
const Native2ManagedMethodInfo hybridclr::interpreter::g_native2managedStub[] =
|
const Native2ManagedMethodInfo hybridclr::interpreter::g_native2managedStub[] =
|
||||||
|
|
@ -919,7 +1015,7 @@ const Native2ManagedMethodInfo hybridclr::interpreter::g_native2managedStub[] =
|
||||||
lines.Add("};");
|
lines.Add("};");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateAdjustThunkStub(List<MethodDesc> methods, List<string> lines)
|
private void GenerateAdjustThunkStub(List<MethodDesc> methods, List<string> lines)
|
||||||
{
|
{
|
||||||
lines.Add($@"
|
lines.Add($@"
|
||||||
const NativeAdjustThunkMethodInfo hybridclr::interpreter::g_adjustThunkStub[] =
|
const NativeAdjustThunkMethodInfo hybridclr::interpreter::g_adjustThunkStub[] =
|
||||||
|
|
@ -945,7 +1041,7 @@ const NativeAdjustThunkMethodInfo hybridclr::interpreter::g_adjustThunkStub[] =
|
||||||
return type.NeedExpandValue() ? $"(uint64_t)({varName})" : $"N2MAsUint64ValueOrAddress<{type.GetTypeName()}>({varName})";
|
return type.NeedExpandValue() ? $"(uint64_t)({varName})" : $"N2MAsUint64ValueOrAddress<{type.GetTypeName()}>({varName})";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateManaged2NativeMethod(MethodDesc method, List<string> lines)
|
private void GenerateManaged2NativeMethod(MethodDesc method, List<string> lines)
|
||||||
{
|
{
|
||||||
string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
|
string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" }));
|
||||||
string paramNameListStr = string.Join(", ", method.ParamInfos.Select(p => GetManaged2NativePassParam(p.Type, $"localVarBase+argVarIndexs[{p.Index}]")).Concat(new string[] { "method" }));
|
string paramNameListStr = string.Join(", ", method.ParamInfos.Select(p => GetManaged2NativePassParam(p.Type, $"localVarBase+argVarIndexs[{p.Index}]")).Concat(new string[] { "method" }));
|
||||||
|
|
@ -959,7 +1055,7 @@ static void __M2N_{method.CreateCallSigName()}(const MethodInfo* method, uint16_
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GenerateArgumentSizeAndOffset(List<ParamInfo> paramInfos)
|
private string GenerateArgumentSizeAndOffset(List<ParamInfo> paramInfos)
|
||||||
{
|
{
|
||||||
StringBuilder s = new StringBuilder();
|
StringBuilder s = new StringBuilder();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
@ -973,7 +1069,7 @@ static void __M2N_{method.CreateCallSigName()}(const MethodInfo* method, uint16_
|
||||||
return s.ToString();
|
return s.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GenerateCopyArgumentToInterpreterStack(List<ParamInfo> paramInfos)
|
private string GenerateCopyArgumentToInterpreterStack(List<ParamInfo> paramInfos)
|
||||||
{
|
{
|
||||||
StringBuilder s = new StringBuilder();
|
StringBuilder s = new StringBuilder();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
@ -1014,14 +1110,46 @@ static {method.ReturnInfo.Type.GetTypeName()} __N2M_{(adjustorThunk ? "AdjustorT
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateNative2ManagedMethod(MethodDesc method, List<string> lines)
|
private void GenerateNative2ManagedMethod(MethodDesc method, List<string> lines)
|
||||||
{
|
{
|
||||||
GenerateNative2ManagedMethod0(method, false, lines);
|
GenerateNative2ManagedMethod0(method, false, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateAdjustThunkMethod(MethodDesc method, List<string> lines)
|
private void GenerateAdjustThunkMethod(MethodDesc method, List<string> lines)
|
||||||
{
|
{
|
||||||
GenerateNative2ManagedMethod0(method, true, lines);
|
GenerateNative2ManagedMethod0(method, true, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GenerateManaged2NativeFunctionPointerMethod(CalliMethodInfo methodInfo, List<string> lines)
|
||||||
|
{
|
||||||
|
MethodDesc method = methodInfo.Method;
|
||||||
|
string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}"));
|
||||||
|
string paramNameListStr = string.Join(", ", method.ParamInfos.Select(p => GetManaged2NativePassParam(p.Type, $"localVarBase+argVarIndexs[{p.Index}]")));
|
||||||
|
string il2cppCallConventionName = GetIl2cppCallConventionName(methodInfo.Callvention);
|
||||||
|
lines.Add($@"
|
||||||
|
static void __M2NF_{methodInfo.Signature}(const void* methodPointer, uint16_t* argVarIndexs, StackObject* localVarBase, void* ret)
|
||||||
|
{{
|
||||||
|
typedef {method.ReturnInfo.Type.GetTypeName()} ({il2cppCallConventionName} *NativeMethod)({paramListStr});
|
||||||
|
{(!method.ReturnInfo.IsVoid ? $"*({method.ReturnInfo.Type.GetTypeName()}*)ret = " : "")}((NativeMethod)(methodPointer))({paramNameListStr});
|
||||||
|
}}
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateManaged2NativeFunctionPointerMethodStub(List<CalliMethodInfo> calliMethodSignatures, List<string> lines)
|
||||||
|
{
|
||||||
|
lines.Add(@"
|
||||||
|
const Managed2NativeFunctionPointerCallData hybridclr::interpreter::g_managed2NativeFunctionPointerCallStub[]
|
||||||
|
{
|
||||||
|
");
|
||||||
|
foreach (var method in calliMethodSignatures)
|
||||||
|
{
|
||||||
|
lines.Add($"\t{{\"{method.Signature}\", __M2NF_{method.Signature}}},");
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.Add(@"
|
||||||
|
{nullptr, nullptr},
|
||||||
|
};
|
||||||
|
");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,6 @@ namespace HybridCLR.Editor.ReversePInvokeWrap
|
||||||
public CustomAttribute GenerationAttribute { get; set; }
|
public CustomAttribute GenerationAttribute { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ABIReversePInvokeMethodInfo
|
|
||||||
{
|
|
||||||
public MethodDesc Method { get; set; }
|
|
||||||
|
|
||||||
public CallingConvention Callvention { get; set; }
|
|
||||||
|
|
||||||
public int Count { get; set; }
|
|
||||||
|
|
||||||
public string Signature { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Analyzer
|
public class Analyzer
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue