From 9ea240ab82d50566185db6468676bc20356f3c27 Mon Sep 17 00:00:00 2001 From: walon Date: Mon, 17 Oct 2022 12:16:18 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Editor/ABI.meta | 8 ++ .../MethodBridgeSig.cs => ABI/MethodDesc.cs} | 16 ++- .../MethodDesc.cs.meta} | 0 Editor/{MethodBridge => ABI}/ParamInfo.cs | 2 +- .../{MethodBridge => ABI}/ParamInfo.cs.meta | 2 +- .../ParamOrReturnType.cs | 2 +- .../ParamOrReturnType.cs.meta | 2 +- Editor/{MethodBridge => ABI}/PlatformABI.cs | 2 +- .../{MethodBridge => ABI}/PlatformABI.cs.meta | 0 Editor/ABI/TypeCreatorArm64.cs | 46 ++++++++ .../TypeCreatorArm64.cs.meta} | 2 +- .../TypeCreatorBase.cs} | 109 +++--------------- Editor/ABI/TypeCreatorBase.cs.meta | 11 ++ Editor/ABI/TypeCreatorFactory.cs | 22 ++++ Editor/ABI/TypeCreatorFactory.cs.meta | 11 ++ Editor/ABI/TypeCreatorUniversal32.cs | 24 ++++ Editor/ABI/TypeCreatorUniversal32.cs.meta | 11 ++ Editor/ABI/TypeCreatorUniversal64.cs | 24 ++++ Editor/ABI/TypeCreatorUniversal64.cs.meta | 11 ++ Editor/{MethodBridge => ABI}/TypeInfo.cs | 2 +- Editor/{MethodBridge => ABI}/TypeInfo.cs.meta | 2 +- .../ValueTypeSizeAligmentCalculator.cs | 6 +- .../ValueTypeSizeAligmentCalculator.cs.meta | 2 +- Editor/AOT/ConstraintContext.cs | 4 +- Editor/Commands/LinkGeneratorCommand.cs | 2 +- .../Commands/MethodBridgeGeneratorCommand.cs | 3 +- .../ReversePInvokeWrapperGeneratorCommand.cs | 38 ++++-- Editor/EqualityUtil.cs | 49 -------- Editor/HybridCLR.Editor.asmdef | 4 +- Editor/Meta/GenericClass.cs | 2 +- Editor/Meta/GenericMethod.cs | 4 +- Editor/{ => Meta}/MetaUtil.cs | 41 ++++++- Editor/{ => Meta}/MetaUtil.cs.meta | 0 Editor/MethodBridge/Generator.cs | 59 +++++----- ...tor_Arm64.cs => PlatformGeneratorArm64.cs} | 58 +++------- ...cs.meta => PlatformGeneratorArm64.cs.meta} | 0 Editor/MethodBridge/PlatformGeneratorBase.cs | 75 ++++++++++++ ....cs.meta => PlatformGeneratorBase.cs.meta} | 0 ...l32.cs => PlatformGeneratorUniversal32.cs} | 31 ++--- ...a => PlatformGeneratorUniversal32.cs.meta} | 0 ...l64.cs => PlatformGeneratorUniversal64.cs} | 37 +++--- ...a => PlatformGeneratorUniversal64.cs.meta} | 0 Editor/ReversePInvokeWrap/Analyzer.cs | 65 +++++++++++ Editor/ReversePInvokeWrap/Analyzer.cs.meta | 11 ++ ...eversePInvokeWrapperGenerationAttribute.cs | 19 +++ ...ePInvokeWrapperGenerationAttribute.cs.meta | 11 ++ 46 files changed, 542 insertions(+), 288 deletions(-) create mode 100644 Editor/ABI.meta rename Editor/{MethodBridge/MethodBridgeSig.cs => ABI/MethodDesc.cs} (87%) rename Editor/{MethodBridge/MethodBridgeSig.cs.meta => ABI/MethodDesc.cs.meta} (100%) rename Editor/{MethodBridge => ABI}/ParamInfo.cs (96%) rename Editor/{MethodBridge => ABI}/ParamInfo.cs.meta (83%) rename Editor/{MethodBridge => ABI}/ParamOrReturnType.cs (95%) rename Editor/{MethodBridge => ABI}/ParamOrReturnType.cs.meta (83%) rename Editor/{MethodBridge => ABI}/PlatformABI.cs (70%) rename Editor/{MethodBridge => ABI}/PlatformABI.cs.meta (100%) create mode 100644 Editor/ABI/TypeCreatorArm64.cs rename Editor/{EqualityUtil.cs.meta => ABI/TypeCreatorArm64.cs.meta} (83%) rename Editor/{MethodBridge/PlatformAdaptorBase.cs => ABI/TypeCreatorBase.cs} (68%) create mode 100644 Editor/ABI/TypeCreatorBase.cs.meta create mode 100644 Editor/ABI/TypeCreatorFactory.cs create mode 100644 Editor/ABI/TypeCreatorFactory.cs.meta create mode 100644 Editor/ABI/TypeCreatorUniversal32.cs create mode 100644 Editor/ABI/TypeCreatorUniversal32.cs.meta create mode 100644 Editor/ABI/TypeCreatorUniversal64.cs create mode 100644 Editor/ABI/TypeCreatorUniversal64.cs.meta rename Editor/{MethodBridge => ABI}/TypeInfo.cs (99%) rename Editor/{MethodBridge => ABI}/TypeInfo.cs.meta (83%) rename Editor/{MethodBridge => ABI}/ValueTypeSizeAligmentCalculator.cs (94%) rename Editor/{MethodBridge => ABI}/ValueTypeSizeAligmentCalculator.cs.meta (83%) delete mode 100644 Editor/EqualityUtil.cs rename Editor/{ => Meta}/MetaUtil.cs (82%) rename Editor/{ => Meta}/MetaUtil.cs.meta (100%) rename Editor/MethodBridge/{PlatformAdaptor_Arm64.cs => PlatformGeneratorArm64.cs} (63%) rename Editor/MethodBridge/{PlatformAdaptor_Arm64.cs.meta => PlatformGeneratorArm64.cs.meta} (100%) create mode 100644 Editor/MethodBridge/PlatformGeneratorBase.cs rename Editor/MethodBridge/{PlatformAdaptorBase.cs.meta => PlatformGeneratorBase.cs.meta} (100%) rename Editor/MethodBridge/{PlatformAdaptor_Universal32.cs => PlatformGeneratorUniversal32.cs} (74%) rename Editor/MethodBridge/{PlatformAdaptor_Universal32.cs.meta => PlatformGeneratorUniversal32.cs.meta} (100%) rename Editor/MethodBridge/{PlatformAdaptor_Universal64.cs => PlatformGeneratorUniversal64.cs} (71%) rename Editor/MethodBridge/{PlatformAdaptor_Universal64.cs.meta => PlatformGeneratorUniversal64.cs.meta} (100%) create mode 100644 Editor/ReversePInvokeWrap/Analyzer.cs create mode 100644 Editor/ReversePInvokeWrap/Analyzer.cs.meta create mode 100644 Runtime/ReversePInvokeWrapperGenerationAttribute.cs create mode 100644 Runtime/ReversePInvokeWrapperGenerationAttribute.cs.meta diff --git a/Editor/ABI.meta b/Editor/ABI.meta new file mode 100644 index 0000000..0557322 --- /dev/null +++ b/Editor/ABI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d26c8b77c84f09442a05f2c67e5e09b8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/MethodBridge/MethodBridgeSig.cs b/Editor/ABI/MethodDesc.cs similarity index 87% rename from Editor/MethodBridge/MethodBridgeSig.cs rename to Editor/ABI/MethodDesc.cs index 0800b92..6a55466 100644 --- a/Editor/MethodBridge/MethodBridgeSig.cs +++ b/Editor/ABI/MethodDesc.cs @@ -7,9 +7,9 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; -namespace HybridCLR.Editor.MethodBridge +namespace HybridCLR.Editor.ABI { - public class MethodBridgeSig : IEquatable + public class MethodDesc : IEquatable { public MethodDef MethodDef { get; set; } @@ -17,6 +17,8 @@ namespace HybridCLR.Editor.MethodBridge public List ParamInfos { get; set; } + private int _hashCode; + public void Init() { for(int i = 0; i < ParamInfos.Count; i++) @@ -58,10 +60,10 @@ namespace HybridCLR.Editor.MethodBridge public override bool Equals(object obj) { - return Equals((MethodBridgeSig)obj); + return Equals((MethodDesc)obj); } - public bool Equals(MethodBridgeSig other) + public bool Equals(MethodDesc other) { if (other == null) { @@ -88,6 +90,10 @@ namespace HybridCLR.Editor.MethodBridge public override int GetHashCode() { + if (_hashCode != 0) + { + return _hashCode; + } int hash = 17; hash = hash * 23 + ReturnInfo.Type.GetHashCode(); @@ -97,7 +103,7 @@ namespace HybridCLR.Editor.MethodBridge hash = hash * 23 + p.Type.GetHashCode(); } - return hash; + return _hashCode = hash; } } } diff --git a/Editor/MethodBridge/MethodBridgeSig.cs.meta b/Editor/ABI/MethodDesc.cs.meta similarity index 100% rename from Editor/MethodBridge/MethodBridgeSig.cs.meta rename to Editor/ABI/MethodDesc.cs.meta diff --git a/Editor/MethodBridge/ParamInfo.cs b/Editor/ABI/ParamInfo.cs similarity index 96% rename from Editor/MethodBridge/ParamInfo.cs rename to Editor/ABI/ParamInfo.cs index 288d8c7..494b620 100644 --- a/Editor/MethodBridge/ParamInfo.cs +++ b/Editor/ABI/ParamInfo.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace HybridCLR.Editor.MethodBridge +namespace HybridCLR.Editor.ABI { public class ParamInfo diff --git a/Editor/MethodBridge/ParamInfo.cs.meta b/Editor/ABI/ParamInfo.cs.meta similarity index 83% rename from Editor/MethodBridge/ParamInfo.cs.meta rename to Editor/ABI/ParamInfo.cs.meta index 0bcaa0f..6b4174e 100644 --- a/Editor/MethodBridge/ParamInfo.cs.meta +++ b/Editor/ABI/ParamInfo.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f97bd67938e4a9c4b9c8ddcdad621f60 +guid: f2ba16cf4bf82374c814789b6ced3abd MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/MethodBridge/ParamOrReturnType.cs b/Editor/ABI/ParamOrReturnType.cs similarity index 95% rename from Editor/MethodBridge/ParamOrReturnType.cs rename to Editor/ABI/ParamOrReturnType.cs index d6dc66a..7e933ec 100644 --- a/Editor/MethodBridge/ParamOrReturnType.cs +++ b/Editor/ABI/ParamOrReturnType.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace HybridCLR.Editor.MethodBridge +namespace HybridCLR.Editor.ABI { public enum ParamOrReturnType { diff --git a/Editor/MethodBridge/ParamOrReturnType.cs.meta b/Editor/ABI/ParamOrReturnType.cs.meta similarity index 83% rename from Editor/MethodBridge/ParamOrReturnType.cs.meta rename to Editor/ABI/ParamOrReturnType.cs.meta index 0d0063b..12ffd4b 100644 --- a/Editor/MethodBridge/ParamOrReturnType.cs.meta +++ b/Editor/ABI/ParamOrReturnType.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6070162cd5afff74f99af129c50fda5a +guid: 80682e47c38a2f04f8af94d356688cf0 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/MethodBridge/PlatformABI.cs b/Editor/ABI/PlatformABI.cs similarity index 70% rename from Editor/MethodBridge/PlatformABI.cs rename to Editor/ABI/PlatformABI.cs index 83fdce1..9b082bb 100644 --- a/Editor/MethodBridge/PlatformABI.cs +++ b/Editor/ABI/PlatformABI.cs @@ -1,4 +1,4 @@ -namespace HybridCLR.Editor.MethodBridge +namespace HybridCLR.Editor.ABI { public enum PlatformABI { diff --git a/Editor/MethodBridge/PlatformABI.cs.meta b/Editor/ABI/PlatformABI.cs.meta similarity index 100% rename from Editor/MethodBridge/PlatformABI.cs.meta rename to Editor/ABI/PlatformABI.cs.meta diff --git a/Editor/ABI/TypeCreatorArm64.cs b/Editor/ABI/TypeCreatorArm64.cs new file mode 100644 index 0000000..6e1f83e --- /dev/null +++ b/Editor/ABI/TypeCreatorArm64.cs @@ -0,0 +1,46 @@ +using dnlib.DotNet; +using HybridCLR.Editor.Meta; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HybridCLR.Editor.ABI +{ + public class HFATypeInfo + { + public TypeSig Type { get; set; } + + public int Count { get; set; } + } + + public class TypeCreatorArm64 : TypeCreatorBase + { + public override bool IsArch32 => false; + + public override bool IsSupportHFA => true; + + protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType) + { + if (!type.IsGeneralValueType) + { + return type; + } + int typeSize = type.Size; + if (typeSize <= 8) + { + return TypeInfo.s_i8; + } + if (typeSize <= 16) + { + return TypeInfo.s_i16; + } + if (returnType) + { + return type.PorType != ParamOrReturnType.STRUCTURE_ALIGN1 ? new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN1, typeSize) : type; + } + return TypeInfo.s_ref; + } + } +} diff --git a/Editor/EqualityUtil.cs.meta b/Editor/ABI/TypeCreatorArm64.cs.meta similarity index 83% rename from Editor/EqualityUtil.cs.meta rename to Editor/ABI/TypeCreatorArm64.cs.meta index 5849f08..1778675 100644 --- a/Editor/EqualityUtil.cs.meta +++ b/Editor/ABI/TypeCreatorArm64.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 103704591750908419902643015e920a +guid: a22846b73022cb2458d1c40549ab6877 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/MethodBridge/PlatformAdaptorBase.cs b/Editor/ABI/TypeCreatorBase.cs similarity index 68% rename from Editor/MethodBridge/PlatformAdaptorBase.cs rename to Editor/ABI/TypeCreatorBase.cs index d146028..873ef7b 100644 --- a/Editor/MethodBridge/PlatformAdaptorBase.cs +++ b/Editor/ABI/TypeCreatorBase.cs @@ -3,66 +3,35 @@ using HybridCLR.Editor.Meta; using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; -using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; -using UnityEngine; -namespace HybridCLR.Editor.MethodBridge +namespace HybridCLR.Editor.ABI { - public abstract class PlatformAdaptorBase + public abstract class TypeCreatorBase { - private static readonly ValueTypeSizeAligmentCalculator s_calculator64 = new ValueTypeSizeAligmentCalculator(false); - - private static readonly ValueTypeSizeAligmentCalculator s_calculator32 = new ValueTypeSizeAligmentCalculator(true); - public abstract bool IsArch32 { get; } public virtual bool IsSupportHFA => false; public TypeInfo GetNativeIntTypeInfo() => IsArch32 ? TypeInfo.s_i4 : TypeInfo.s_i8; - public abstract void GenerateManaged2NativeMethod(MethodBridgeSig method, List lines); + public ValueTypeSizeAligmentCalculator Calculator => IsArch32 ? ValueTypeSizeAligmentCalculator.Caculator32 : ValueTypeSizeAligmentCalculator.Caculator64; - public abstract void GenerateNative2ManagedMethod(MethodBridgeSig method, List lines); - public abstract void GenerateAdjustThunkMethod(MethodBridgeSig method, List outputLines); + private readonly Dictionary _typeSizeCache = new Dictionary(TypeEqualityComparer.Instance); - protected abstract TypeInfo OptimizeSigType(TypeInfo type, bool returnType); - - public virtual void OptimizeMethod(MethodBridgeSig method) + public (int Size, int Aligment) ComputeSizeAndAligment(TypeSig t) { - method.TransfromSigTypes(OptimizeSigType); - } - - private readonly Dictionary _typeSizeCache64 = new Dictionary(TypeEqualityComparer.Instance); - - private readonly Dictionary _typeSizeCache32 = new Dictionary(TypeEqualityComparer.Instance); - - public (int Size, int Aligment) ComputeSizeAndAligmentOfArch64(TypeSig t) - { - if (_typeSizeCache64.TryGetValue(t, out var sizeAndAligment)) + if (_typeSizeCache.TryGetValue(t, out var sizeAndAligment)) { return sizeAndAligment; } - sizeAndAligment = s_calculator64.SizeAndAligmentOf(t); - _typeSizeCache64.Add(t, sizeAndAligment); + sizeAndAligment = Calculator.SizeAndAligmentOf(t); + _typeSizeCache.Add(t, sizeAndAligment); return sizeAndAligment; } - protected (int Size, int Aligment) ComputeSizeAndAligmentOfArch32(TypeSig t) - { - if (_typeSizeCache32.TryGetValue(t, out var sa)) - { - return sa; - } - // all this just to invoke one opcode with no arguments! - sa = s_calculator32.SizeAndAligmentOf(t); - _typeSizeCache32.Add(t, sa); - return sa; - } - public TypeInfo CreateTypeInfo(TypeSig type) { type = type.RemovePinnedAndModifiers(); @@ -70,7 +39,7 @@ namespace HybridCLR.Editor.MethodBridge { return GetNativeIntTypeInfo(); } - switch(type.ElementType) + switch (type.ElementType) { case ElementType.Void: return TypeInfo.s_void; case ElementType.Boolean: return TypeInfo.s_u1; @@ -87,7 +56,7 @@ namespace HybridCLR.Editor.MethodBridge case ElementType.R8: return TypeInfo.s_r8; case ElementType.U: return IsArch32 ? TypeInfo.s_u4 : TypeInfo.s_u8; case ElementType.I: - case ElementType.String: + case ElementType.String: case ElementType.Ptr: case ElementType.ByRef: case ElementType.Class: @@ -98,7 +67,7 @@ namespace HybridCLR.Editor.MethodBridge case ElementType.Module: case ElementType.Var: case ElementType.MVar: - return GetNativeIntTypeInfo(); + return GetNativeIntTypeInfo(); case ElementType.TypedByRef: return CreateValueType(type); case ElementType.ValueType: { @@ -147,7 +116,7 @@ namespace HybridCLR.Editor.MethodBridge continue; } TypeSig ftype = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType; - switch(ftype.ElementType) + switch (ftype.ElementType) { case ElementType.R4: case ElementType.R8: @@ -203,7 +172,7 @@ namespace HybridCLR.Editor.MethodBridge protected static TypeInfo CreateGeneralValueType(TypeSig type, int size, int aligment) { - Debug.Assert(size % aligment == 0); + System.Diagnostics.Debug.Assert(size % aligment == 0); switch (aligment) { case 1: return new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN1, size); @@ -216,7 +185,7 @@ namespace HybridCLR.Editor.MethodBridge protected TypeInfo CreateValueType(TypeSig type) { - (int typeSize, int typeAligment) = IsArch32 ? ComputeSizeAndAligmentOfArch32(type) : ComputeSizeAndAligmentOfArch64(type); + (int typeSize, int typeAligment) = ComputeSizeAndAligment(type); if (IsSupportHFA && ComputHFATypeInfo(type, typeSize, out HFATypeInfo hfaTypeInfo)) { bool isFloat = hfaTypeInfo.Type.ElementType == ElementType.R4; @@ -235,52 +204,12 @@ namespace HybridCLR.Editor.MethodBridge } } - public void GenerateManaged2NativeStub(List methods, List lines) + + protected abstract TypeInfo OptimizeSigType(TypeInfo type, bool returnType); + + public virtual void OptimizeMethod(MethodDesc method) { - lines.Add($@" -Managed2NativeMethodInfo hybridclr::interpreter::g_managed2nativeStub[] = -{{ -"); - - foreach (var method in methods) - { - lines.Add($"\t{{\"{method.CreateInvokeSigName()}\", __M2N_{method.CreateInvokeSigName()}}},"); - } - - lines.Add($"\t{{nullptr, nullptr}},"); - lines.Add("};"); - } - - public void GenerateNative2ManagedStub(List methods, List lines) - { - lines.Add($@" -Native2ManagedMethodInfo hybridclr::interpreter::g_native2managedStub[] = -{{ -"); - - foreach (var method in methods) - { - lines.Add($"\t{{\"{method.CreateInvokeSigName()}\", (Il2CppMethodPointer)__N2M_{method.CreateInvokeSigName()}}},"); - } - - lines.Add($"\t{{nullptr, nullptr}},"); - lines.Add("};"); - } - - public void GenerateAdjustThunkStub(List methods, List lines) - { - lines.Add($@" -NativeAdjustThunkMethodInfo hybridclr::interpreter::g_adjustThunkStub[] = -{{ -"); - - foreach (var method in methods) - { - lines.Add($"\t{{\"{method.CreateInvokeSigName()}\", (Il2CppMethodPointer)__N2M_AdjustorThunk_{method.CreateCallSigName()}}},"); - } - - lines.Add($"\t{{nullptr, nullptr}},"); - lines.Add("};"); + method.TransfromSigTypes(OptimizeSigType); } } } diff --git a/Editor/ABI/TypeCreatorBase.cs.meta b/Editor/ABI/TypeCreatorBase.cs.meta new file mode 100644 index 0000000..371fb29 --- /dev/null +++ b/Editor/ABI/TypeCreatorBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b63c5bf995a6d624dbd10d9df6cb6a7a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ABI/TypeCreatorFactory.cs b/Editor/ABI/TypeCreatorFactory.cs new file mode 100644 index 0000000..eb265c0 --- /dev/null +++ b/Editor/ABI/TypeCreatorFactory.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HybridCLR.Editor.ABI +{ + public static class TypeCreatorFactory + { + public static TypeCreatorBase CreateTypeCreator(PlatformABI abi) + { + switch(abi) + { + case PlatformABI.Arm64: return new TypeCreatorArm64(); + case PlatformABI.Universal32: return new TypeCreatorUniversal32(); + case PlatformABI.Universal64: return new TypeCreatorUniversal64(); + default: throw new NotSupportedException(abi.ToString()); + } + } + } +} diff --git a/Editor/ABI/TypeCreatorFactory.cs.meta b/Editor/ABI/TypeCreatorFactory.cs.meta new file mode 100644 index 0000000..63c123d --- /dev/null +++ b/Editor/ABI/TypeCreatorFactory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe1634f74b7ca2e42bd07233b451cd94 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ABI/TypeCreatorUniversal32.cs b/Editor/ABI/TypeCreatorUniversal32.cs new file mode 100644 index 0000000..a3ffb48 --- /dev/null +++ b/Editor/ABI/TypeCreatorUniversal32.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HybridCLR.Editor.ABI +{ + public class TypeCreatorUniversal32 : TypeCreatorBase + { + public override bool IsArch32 => true; + + public override bool IsSupportHFA => false; + + protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType) + { + if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN4) + { + return new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN1, type.Size); + } + return type; + } + } +} diff --git a/Editor/ABI/TypeCreatorUniversal32.cs.meta b/Editor/ABI/TypeCreatorUniversal32.cs.meta new file mode 100644 index 0000000..2894192 --- /dev/null +++ b/Editor/ABI/TypeCreatorUniversal32.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1eb9e19189731a344aad024a43e795bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ABI/TypeCreatorUniversal64.cs b/Editor/ABI/TypeCreatorUniversal64.cs new file mode 100644 index 0000000..c4808ae --- /dev/null +++ b/Editor/ABI/TypeCreatorUniversal64.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HybridCLR.Editor.ABI +{ + public class TypeCreatorUniversal64 : TypeCreatorBase + { + public override bool IsArch32 => false; + + public override bool IsSupportHFA => true; + + protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType) + { + if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN8) + { + return new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN1, type.Size); + } + return type; + } + } +} diff --git a/Editor/ABI/TypeCreatorUniversal64.cs.meta b/Editor/ABI/TypeCreatorUniversal64.cs.meta new file mode 100644 index 0000000..b00c970 --- /dev/null +++ b/Editor/ABI/TypeCreatorUniversal64.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7867dfe20d27e324e90bc13b9d4f05bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/MethodBridge/TypeInfo.cs b/Editor/ABI/TypeInfo.cs similarity index 99% rename from Editor/MethodBridge/TypeInfo.cs rename to Editor/ABI/TypeInfo.cs index 636c75e..ebc6d38 100644 --- a/Editor/MethodBridge/TypeInfo.cs +++ b/Editor/ABI/TypeInfo.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Reflection; using UnityEngine; -namespace HybridCLR.Editor.MethodBridge +namespace HybridCLR.Editor.ABI { public class TypeInfo : IEquatable { diff --git a/Editor/MethodBridge/TypeInfo.cs.meta b/Editor/ABI/TypeInfo.cs.meta similarity index 83% rename from Editor/MethodBridge/TypeInfo.cs.meta rename to Editor/ABI/TypeInfo.cs.meta index 9194b6b..5df8577 100644 --- a/Editor/MethodBridge/TypeInfo.cs.meta +++ b/Editor/ABI/TypeInfo.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 804237f201e1f7a4da1729e0eb11f75f +guid: ffafce7f1f0bf614d95b48ca39385377 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/MethodBridge/ValueTypeSizeAligmentCalculator.cs b/Editor/ABI/ValueTypeSizeAligmentCalculator.cs similarity index 94% rename from Editor/MethodBridge/ValueTypeSizeAligmentCalculator.cs rename to Editor/ABI/ValueTypeSizeAligmentCalculator.cs index 7fb70ba..5162271 100644 --- a/Editor/MethodBridge/ValueTypeSizeAligmentCalculator.cs +++ b/Editor/ABI/ValueTypeSizeAligmentCalculator.cs @@ -9,10 +9,14 @@ using System.Text; using System.Threading.Tasks; using UnityEngine; -namespace HybridCLR.Editor.MethodBridge +namespace HybridCLR.Editor.ABI { public class ValueTypeSizeAligmentCalculator { + public static ValueTypeSizeAligmentCalculator Caculator64 { get; } = new ValueTypeSizeAligmentCalculator(false); + + public static ValueTypeSizeAligmentCalculator Caculator32 { get; } = new ValueTypeSizeAligmentCalculator(true); + public ValueTypeSizeAligmentCalculator(bool arch32) { _referenceSize = arch32 ? 4 : 8; diff --git a/Editor/MethodBridge/ValueTypeSizeAligmentCalculator.cs.meta b/Editor/ABI/ValueTypeSizeAligmentCalculator.cs.meta similarity index 83% rename from Editor/MethodBridge/ValueTypeSizeAligmentCalculator.cs.meta rename to Editor/ABI/ValueTypeSizeAligmentCalculator.cs.meta index b08838a..4b83d63 100644 --- a/Editor/MethodBridge/ValueTypeSizeAligmentCalculator.cs.meta +++ b/Editor/ABI/ValueTypeSizeAligmentCalculator.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 40dd1d9a2278f7846a9baa2041f74858 +guid: b7af32bdf1cf55c42bfc449820d401cb MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/AOT/ConstraintContext.cs b/Editor/AOT/ConstraintContext.cs index 82477e1..4a9cd3c 100644 --- a/Editor/AOT/ConstraintContext.cs +++ b/Editor/AOT/ConstraintContext.cs @@ -32,8 +32,8 @@ namespace HybridCLR.Editor.AOT public override bool Equals(object obj) { ImplType o = (ImplType)obj; - return EqualityUtil.EqualsTypeSig(this.BaseType, o.BaseType) - && EqualityUtil.EqualsTypeSigArray(this.Interfaces, o.Interfaces) + return MetaUtil.EqualsTypeSig(this.BaseType, o.BaseType) + && MetaUtil.EqualsTypeSigArray(this.Interfaces, o.Interfaces) && this.ValueType == o.ValueType; } diff --git a/Editor/Commands/LinkGeneratorCommand.cs b/Editor/Commands/LinkGeneratorCommand.cs index 623abf5..81acaa7 100644 --- a/Editor/Commands/LinkGeneratorCommand.cs +++ b/Editor/Commands/LinkGeneratorCommand.cs @@ -45,7 +45,7 @@ namespace HybridCLR.Editor.Commands } } - var analyzer = new Analyzer(MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget), HybridCLRSettings.Instance.collectAssetReferenceTypes); + var analyzer = new Analyzer(Meta.MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget), HybridCLRSettings.Instance.collectAssetReferenceTypes); var refTypes = analyzer.CollectRefs(hotfixAssembles); Debug.Log($"[LinkGeneratorCommand] hotfix assembly count:{hotfixAssembles.Count}, ref type count:{refTypes.Count} output:{Application.dataPath}/{ls.outputLinkFile}"); diff --git a/Editor/Commands/MethodBridgeGeneratorCommand.cs b/Editor/Commands/MethodBridgeGeneratorCommand.cs index 67f793a..6823553 100644 --- a/Editor/Commands/MethodBridgeGeneratorCommand.cs +++ b/Editor/Commands/MethodBridgeGeneratorCommand.cs @@ -1,4 +1,5 @@ using HybridCLR.Editor; +using HybridCLR.Editor.ABI; using HybridCLR.Editor.Meta; using HybridCLR.Editor.MethodBridge; using System; @@ -45,7 +46,7 @@ namespace HybridCLR.Editor.Commands { var g = new Generator(new Generator.Options() { - CallConvention = platform, + PlatformABI = platform, TemplateCode = templateCode, OutputFile = outputFile, GenericMethods = analyzer.GenericMethods, diff --git a/Editor/Commands/ReversePInvokeWrapperGeneratorCommand.cs b/Editor/Commands/ReversePInvokeWrapperGeneratorCommand.cs index 36d7f2a..73d2c46 100644 --- a/Editor/Commands/ReversePInvokeWrapperGeneratorCommand.cs +++ b/Editor/Commands/ReversePInvokeWrapperGeneratorCommand.cs @@ -1,5 +1,6 @@ -using HybridCLR.Editor.Link; -using HybridCLR.Editor.ReversePInvokeWrap; +using HybridCLR.Editor.ABI; +using HybridCLR.Editor.Link; +using HybridCLR.Editor.Meta; using System; using System.Collections.Generic; using System.IO; @@ -19,13 +20,32 @@ namespace HybridCLR.Editor.Commands [MenuItem("HybridCLR/Generate/ReversePInvokeWrapper", priority = 103)] public static void GenerateReversePInvokeWrapper() { - string ReversePInvokeWrapperStubFile = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr/metadata/ReversePInvokeMethodStub.cpp"; - string wrapperTemplateStr = File.ReadAllText($"{SettingsUtil.TemplatePathInPackage}/ReversePInvokeMethodStub.cpp.txt"); - int wrapperCount = SettingsUtil.HybridCLRSettings.ReversePInvokeWrapperCount; - var generator = new Generator(); - generator.Generate(wrapperTemplateStr, wrapperCount,ReversePInvokeWrapperStubFile); - Debug.Log($"GenerateReversePInvokeWrapper. wraperCount:{wrapperCount} output:{ReversePInvokeWrapperStubFile}"); - MethodBridgeGeneratorCommand.CleanIl2CppBuildCache(); + CompileDllCommand.CompileDllActiveBuildTarget(); + using (var cache = new AssemblyCache(MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget))) + { + var analyzer = new ReversePInvokeWrap.Analyzer(cache, SettingsUtil.HotUpdateAssemblyNames); + var methods = analyzer.CollectMonoPInvokeCallbackMethods(); + foreach (var method in methods) + { + Debug.Log($"method:{method.Method}"); + } + + var generateJobs = new List<(PlatformABI, string)>() + { + (PlatformABI.Arm64, "HYBRIDCLR_ABI_ARM_64"), + (PlatformABI.Universal64, "HYBRIDCLR_ABI_UNIVERSAL_64"), + (PlatformABI.Universal32, "HYBRIDCLR_ABI_UNIVERSAL_32"), + }; + } + return; + + //string ReversePInvokeWrapperStubFile = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr/metadata/ReversePInvokeMethodStub.cpp"; + //string wrapperTemplateStr = File.ReadAllText($"{SettingsUtil.TemplatePathInPackage}/ReversePInvokeMethodStub.cpp.txt"); + //int wrapperCount = SettingsUtil.HybridCLRSettings.ReversePInvokeWrapperCount; + //var generator = new Generator(); + //generator.Generate(wrapperTemplateStr, wrapperCount,ReversePInvokeWrapperStubFile); + //Debug.Log($"GenerateReversePInvokeWrapper. wraperCount:{wrapperCount} output:{ReversePInvokeWrapperStubFile}"); + //MethodBridgeGeneratorCommand.CleanIl2CppBuildCache(); } } } diff --git a/Editor/EqualityUtil.cs b/Editor/EqualityUtil.cs deleted file mode 100644 index b4223a4..0000000 --- a/Editor/EqualityUtil.cs +++ /dev/null @@ -1,49 +0,0 @@ -using dnlib.DotNet; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace HybridCLR.Editor -{ - public static class EqualityUtil - { - public static bool EqualsTypeSig(TypeSig a, TypeSig b) - { - if (a == b) - { - return true; - } - if (a != null && b != null) - { - return TypeEqualityComparer.Instance.Equals(a, b); - } - return false; - } - - public static bool EqualsTypeSigArray(List a, List b) - { - if (a == b) - { - return true; - } - if (a != null && b != null) - { - if (a.Count != b.Count) - { - return false; - } - for (int i = 0; i < a.Count; i++) - { - if (!TypeEqualityComparer.Instance.Equals(a[i], b[i])) - { - return false; - } - } - return true; - } - return false; - } - } -} diff --git a/Editor/HybridCLR.Editor.asmdef b/Editor/HybridCLR.Editor.asmdef index 13c4cb6..4612a6d 100644 --- a/Editor/HybridCLR.Editor.asmdef +++ b/Editor/HybridCLR.Editor.asmdef @@ -1,7 +1,9 @@ { "name": "HybridCLR.Editor", "rootNamespace": "", - "references": [], + "references": [ + "HybridCLR.Runtime" + ], "includePlatforms": [ "Editor" ], diff --git a/Editor/Meta/GenericClass.cs b/Editor/Meta/GenericClass.cs index c080c1a..67853bc 100644 --- a/Editor/Meta/GenericClass.cs +++ b/Editor/Meta/GenericClass.cs @@ -29,7 +29,7 @@ namespace HybridCLR.Editor.Meta { if (obj is GenericClass gc) { - return Type == gc.Type && EqualityUtil.EqualsTypeSigArray(KlassInst, gc.KlassInst); + return Type == gc.Type && MetaUtil.EqualsTypeSigArray(KlassInst, gc.KlassInst); } return false; } diff --git a/Editor/Meta/GenericMethod.cs b/Editor/Meta/GenericMethod.cs index df0327b..a2b4d4a 100644 --- a/Editor/Meta/GenericMethod.cs +++ b/Editor/Meta/GenericMethod.cs @@ -33,8 +33,8 @@ namespace HybridCLR.Editor.Meta { GenericMethod o = (GenericMethod)obj; return Method == o.Method - && EqualityUtil.EqualsTypeSigArray(KlassInst, o.KlassInst) - && EqualityUtil.EqualsTypeSigArray(MethodInst, o.MethodInst); + && MetaUtil.EqualsTypeSigArray(KlassInst, o.KlassInst) + && MetaUtil.EqualsTypeSigArray(MethodInst, o.MethodInst); } public override int GetHashCode() diff --git a/Editor/MetaUtil.cs b/Editor/Meta/MetaUtil.cs similarity index 82% rename from Editor/MetaUtil.cs rename to Editor/Meta/MetaUtil.cs index b1ed9b6..45983ab 100644 --- a/Editor/MetaUtil.cs +++ b/Editor/Meta/MetaUtil.cs @@ -6,12 +6,49 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; -using IAssemblyResolver = HybridCLR.Editor.Meta.IAssemblyResolver; -namespace HybridCLR.Editor +namespace HybridCLR.Editor.Meta { public static class MetaUtil { + + public static bool EqualsTypeSig(TypeSig a, TypeSig b) + { + if (a == b) + { + return true; + } + if (a != null && b != null) + { + return TypeEqualityComparer.Instance.Equals(a, b); + } + return false; + } + + public static bool EqualsTypeSigArray(List a, List b) + { + if (a == b) + { + return true; + } + if (a != null && b != null) + { + if (a.Count != b.Count) + { + return false; + } + for (int i = 0; i < a.Count; i++) + { + if (!TypeEqualityComparer.Instance.Equals(a[i], b[i])) + { + return false; + } + } + return true; + } + return false; + } + public static TypeSig Inflate(TypeSig sig, GenericArgumentContext ctx) { if (!sig.ContainsGenericParameter) diff --git a/Editor/MetaUtil.cs.meta b/Editor/Meta/MetaUtil.cs.meta similarity index 100% rename from Editor/MetaUtil.cs.meta rename to Editor/Meta/MetaUtil.cs.meta diff --git a/Editor/MethodBridge/Generator.cs b/Editor/MethodBridge/Generator.cs index 3b264f3..ad6f236 100644 --- a/Editor/MethodBridge/Generator.cs +++ b/Editor/MethodBridge/Generator.cs @@ -1,4 +1,5 @@ using dnlib.DotNet; +using HybridCLR.Editor.ABI; using HybridCLR.Editor.Meta; using HybridCLR.Editor.Template; using System; @@ -10,6 +11,7 @@ using System.Text; using System.Threading.Tasks; using UnityEditor; using UnityEngine; +using TypeInfo = HybridCLR.Editor.ABI.TypeInfo; namespace HybridCLR.Editor.MethodBridge { @@ -17,7 +19,7 @@ namespace HybridCLR.Editor.MethodBridge { public class Options { - public PlatformABI CallConvention { get; set; } + public PlatformABI PlatformABI { get; set; } public string TemplateCode { get; set; } @@ -36,19 +38,21 @@ namespace HybridCLR.Editor.MethodBridge private readonly string _outputFile; - private readonly PlatformAdaptorBase _platformAdaptor; + private readonly PlatformGeneratorBase _platformAdaptor; - private readonly HashSet _managed2nativeMethodSet = new HashSet(); + private readonly TypeCreatorBase _typeCreator; - private List _managed2nativeMethodList; + private readonly HashSet _managed2nativeMethodSet = new HashSet(); - private readonly HashSet _native2managedMethodSet = new HashSet(); + private List _managed2nativeMethodList; - private List _native2managedMethodList; + private readonly HashSet _native2managedMethodSet = new HashSet(); - private readonly HashSet _adjustThunkMethodSet = new HashSet(); + private List _native2managedMethodList; - private List _adjustThunkMethodList; + private readonly HashSet _adjustThunkMethodSet = new HashSet(); + + private List _adjustThunkMethodList; public Generator(Options options) { @@ -56,21 +60,22 @@ namespace HybridCLR.Editor.MethodBridge _genericMethods = options.GenericMethods; _templateCode = options.TemplateCode; _outputFile = options.OutputFile; - _platformAdaptor = CreatePlatformAdaptor(options.CallConvention); + _platformAdaptor = CreatePlatformAdaptor(options.PlatformABI); + _typeCreator = TypeCreatorFactory.CreateTypeCreator(options.PlatformABI); } - private static PlatformAdaptorBase CreatePlatformAdaptor(PlatformABI type) + private static PlatformGeneratorBase CreatePlatformAdaptor(PlatformABI type) { switch (type) { - case PlatformABI.Universal32: return new PlatformAdaptor_Universal32(); - case PlatformABI.Universal64: return new PlatformAdaptor_Universal64(); - case PlatformABI.Arm64: return new PlatformAdaptor_Arm64(); + case PlatformABI.Universal32: return new PlatformGeneratorUniversal32(); + case PlatformABI.Universal64: return new PlatformGeneratorUniversal64(); + case PlatformABI.Arm64: return new PlatformGeneratorArm64(); default: throw new NotSupportedException(); } } - private MethodBridgeSig CreateMethodBridgeSig(MethodDef methodDef, bool forceRemoveThis, TypeSig returnType, List parameters) + private MethodDesc CreateMethodDesc(MethodDef methodDef, bool forceRemoveThis, TypeSig returnType, List parameters) { var paramInfos = new List(); if (forceRemoveThis && !methodDef.IsStatic) @@ -79,19 +84,19 @@ namespace HybridCLR.Editor.MethodBridge } foreach (var paramInfo in parameters) { - paramInfos.Add(new ParamInfo() { Type = _platformAdaptor.CreateTypeInfo(paramInfo) }); + paramInfos.Add(new ParamInfo() { Type = _typeCreator.CreateTypeInfo(paramInfo) }); } - var mbs = new MethodBridgeSig() + var mbs = new MethodDesc() { MethodDef = methodDef, - ReturnInfo = new ReturnInfo() { Type = returnType != null ? _platformAdaptor.CreateTypeInfo(returnType) : TypeInfo.s_void }, + ReturnInfo = new ReturnInfo() { Type = returnType != null ? _typeCreator.CreateTypeInfo(returnType) : TypeInfo.s_void }, ParamInfos = paramInfos, }; - _platformAdaptor.OptimizeMethod(mbs); + _typeCreator.OptimizeMethod(mbs); return mbs; } - private void AddManaged2NativeMethod(MethodBridgeSig method) + private void AddManaged2NativeMethod(MethodDesc method) { if (_managed2nativeMethodSet.Add(method)) { @@ -99,7 +104,7 @@ namespace HybridCLR.Editor.MethodBridge } } - private void AddNative2ManagedMethod(MethodBridgeSig method) + private void AddNative2ManagedMethod(MethodDesc method) { if (_native2managedMethodSet.Add(method)) { @@ -107,7 +112,7 @@ namespace HybridCLR.Editor.MethodBridge } } - private void AddAdjustThunkMethod(MethodBridgeSig method) + private void AddAdjustThunkMethod(MethodDesc method) { if (_adjustThunkMethodSet.Add(method)) { @@ -136,7 +141,7 @@ namespace HybridCLR.Editor.MethodBridge parameters = method.Parameters.Select(p => MetaUtil.Inflate(p.Type, gc)).ToList(); } - var m2nMethod = CreateMethodBridgeSig(method, false, returnType, parameters); + var m2nMethod = CreateMethodDesc(method, false, returnType, parameters); AddManaged2NativeMethod(m2nMethod); if (method.IsVirtual) @@ -145,12 +150,12 @@ namespace HybridCLR.Editor.MethodBridge { AddAdjustThunkMethod(m2nMethod); } - //var adjustThunkMethod = CreateMethodBridgeSig(method, true, returnType, parameters); + //var adjustThunkMethod = CreateMethodDesc(method, true, returnType, parameters); AddNative2ManagedMethod(m2nMethod); } if (method.Name == "Invoke" && method.DeclaringType.IsDelegate) { - var openMethod = CreateMethodBridgeSig(method, true, returnType, parameters); + var openMethod = CreateMethodDesc(method, true, returnType, parameters); AddNative2ManagedMethod(openMethod); } } @@ -168,7 +173,7 @@ namespace HybridCLR.Editor.MethodBridge } { - var sortedMethods = new SortedDictionary(); + var sortedMethods = new SortedDictionary(); foreach (var method in _managed2nativeMethodSet) { sortedMethods.Add(method.CreateCallSigName(), method); @@ -176,7 +181,7 @@ namespace HybridCLR.Editor.MethodBridge _managed2nativeMethodList = sortedMethods.Values.ToList(); } { - var sortedMethods = new SortedDictionary(); + var sortedMethods = new SortedDictionary(); foreach (var method in _native2managedMethodSet) { sortedMethods.Add(method.CreateCallSigName(), method); @@ -184,7 +189,7 @@ namespace HybridCLR.Editor.MethodBridge _native2managedMethodList = sortedMethods.Values.ToList(); } { - var sortedMethods = new SortedDictionary(); + var sortedMethods = new SortedDictionary(); foreach (var method in _adjustThunkMethodSet) { sortedMethods.Add(method.CreateCallSigName(), method); diff --git a/Editor/MethodBridge/PlatformAdaptor_Arm64.cs b/Editor/MethodBridge/PlatformGeneratorArm64.cs similarity index 63% rename from Editor/MethodBridge/PlatformAdaptor_Arm64.cs rename to Editor/MethodBridge/PlatformGeneratorArm64.cs index 84de492..1f15e3b 100644 --- a/Editor/MethodBridge/PlatformAdaptor_Arm64.cs +++ b/Editor/MethodBridge/PlatformGeneratorArm64.cs @@ -1,4 +1,5 @@ using dnlib.DotNet; +using HybridCLR.Editor.ABI; using System; using System.Collections.Generic; using System.Linq; @@ -10,48 +11,17 @@ using UnityEngine; namespace HybridCLR.Editor.MethodBridge { - public class HFATypeInfo + + + public class PlatformGeneratorArm64 : PlatformGeneratorBase { - public TypeSig Type { get; set; } + public override PlatformABI PlatformABI { get; } = PlatformABI.Universal64; - public int Count { get; set; } - } - - public class PlatformAdaptor_Arm64 : PlatformAdaptorBase - { - public PlatformABI CallConventionType { get; } = PlatformABI.Universal64; - - public override bool IsArch32 => false; - - public override bool IsSupportHFA => true; - - protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType) + public override void GenerateManaged2NativeMethod(MethodDesc method, List lines) { - if (!type.IsGeneralValueType) - { - return type; - } - int typeSize = type.Size; - if (typeSize <= 8) - { - return TypeInfo.s_i8; - } - if (typeSize <= 16) - { - return TypeInfo.s_i16; - } - if (returnType) - { - return type.PorType != ParamOrReturnType.STRUCTURE_ALIGN1 ? new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN1, typeSize) : type; - } - return TypeInfo.s_ref; - } - - public override void GenerateManaged2NativeMethod(MethodBridgeSig method, List lines) - { - int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.CallConventionType); + int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI); 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 => p.Managed2NativeParamValue(this.CallConventionType)).Concat(new string[] { "method" })); + string paramNameListStr = string.Join(", ", method.ParamInfos.Select(p => p.Managed2NativeParamValue(this.PlatformABI)).Concat(new string[] { "method" })); lines.Add($@" // {method.MethodDef} @@ -63,16 +33,16 @@ static void __M2N_{method.CreateCallSigName()}(const MethodInfo* method, uint16_ "); } - public override void GenerateNative2ManagedMethod(MethodBridgeSig method, List lines) + public override void GenerateNative2ManagedMethod(MethodDesc method, List lines) { - int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.CallConventionType); + int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI); string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" })); lines.Add($@" // {method.MethodDef} static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()}({paramListStr}) {{ - StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => p.Native2ManagedParamValue(this.CallConventionType)))} }}; + StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => p.Native2ManagedParamValue(this.PlatformABI)))} }}; StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)}; Interpreter::Execute(method, args, ret); {(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")} @@ -80,9 +50,9 @@ static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()} "); } - public override void GenerateAdjustThunkMethod(MethodBridgeSig method, List lines) + public override void GenerateAdjustThunkMethod(MethodDesc method, List lines) { - int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.CallConventionType); + int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI); string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" })); @@ -90,7 +60,7 @@ static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()} // {method.MethodDef} static {method.ReturnInfo.Type.GetTypeName()} __N2M_AdjustorThunk_{method.CreateCallSigName()}({paramListStr}) {{ - 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.CallConventionType))))} }}; + 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))))} }}; StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)}; Interpreter::Execute(method, args, ret); {(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")} diff --git a/Editor/MethodBridge/PlatformAdaptor_Arm64.cs.meta b/Editor/MethodBridge/PlatformGeneratorArm64.cs.meta similarity index 100% rename from Editor/MethodBridge/PlatformAdaptor_Arm64.cs.meta rename to Editor/MethodBridge/PlatformGeneratorArm64.cs.meta diff --git a/Editor/MethodBridge/PlatformGeneratorBase.cs b/Editor/MethodBridge/PlatformGeneratorBase.cs new file mode 100644 index 0000000..7f13732 --- /dev/null +++ b/Editor/MethodBridge/PlatformGeneratorBase.cs @@ -0,0 +1,75 @@ +using dnlib.DotNet; +using HybridCLR.Editor.ABI; +using HybridCLR.Editor.Meta; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using TypeInfo = HybridCLR.Editor.ABI.TypeInfo; + +namespace HybridCLR.Editor.MethodBridge +{ + public abstract class PlatformGeneratorBase + { + public abstract PlatformABI PlatformABI { get; } + + public abstract void GenerateManaged2NativeMethod(MethodDesc method, List lines); + + public abstract void GenerateNative2ManagedMethod(MethodDesc method, List lines); + + public abstract void GenerateAdjustThunkMethod(MethodDesc method, List outputLines); + + + public void GenerateManaged2NativeStub(List methods, List lines) + { + lines.Add($@" +Managed2NativeMethodInfo hybridclr::interpreter::g_managed2nativeStub[] = +{{ +"); + + foreach (var method in methods) + { + lines.Add($"\t{{\"{method.CreateInvokeSigName()}\", __M2N_{method.CreateInvokeSigName()}}},"); + } + + lines.Add($"\t{{nullptr, nullptr}},"); + lines.Add("};"); + } + + public void GenerateNative2ManagedStub(List methods, List lines) + { + lines.Add($@" +Native2ManagedMethodInfo hybridclr::interpreter::g_native2managedStub[] = +{{ +"); + + foreach (var method in methods) + { + lines.Add($"\t{{\"{method.CreateInvokeSigName()}\", (Il2CppMethodPointer)__N2M_{method.CreateInvokeSigName()}}},"); + } + + lines.Add($"\t{{nullptr, nullptr}},"); + lines.Add("};"); + } + + public void GenerateAdjustThunkStub(List methods, List lines) + { + lines.Add($@" +NativeAdjustThunkMethodInfo hybridclr::interpreter::g_adjustThunkStub[] = +{{ +"); + + foreach (var method in methods) + { + lines.Add($"\t{{\"{method.CreateInvokeSigName()}\", (Il2CppMethodPointer)__N2M_AdjustorThunk_{method.CreateCallSigName()}}},"); + } + + lines.Add($"\t{{nullptr, nullptr}},"); + lines.Add("};"); + } + } +} diff --git a/Editor/MethodBridge/PlatformAdaptorBase.cs.meta b/Editor/MethodBridge/PlatformGeneratorBase.cs.meta similarity index 100% rename from Editor/MethodBridge/PlatformAdaptorBase.cs.meta rename to Editor/MethodBridge/PlatformGeneratorBase.cs.meta diff --git a/Editor/MethodBridge/PlatformAdaptor_Universal32.cs b/Editor/MethodBridge/PlatformGeneratorUniversal32.cs similarity index 74% rename from Editor/MethodBridge/PlatformAdaptor_Universal32.cs rename to Editor/MethodBridge/PlatformGeneratorUniversal32.cs index bc56acc..918ae5f 100644 --- a/Editor/MethodBridge/PlatformAdaptor_Universal32.cs +++ b/Editor/MethodBridge/PlatformGeneratorUniversal32.cs @@ -1,4 +1,5 @@ using dnlib.DotNet; +using HybridCLR.Editor.ABI; using System; using System.Collections.Generic; using System.Linq; @@ -9,11 +10,9 @@ using UnityEngine; namespace HybridCLR.Editor.MethodBridge { - internal class PlatformAdaptor_Universal32 : PlatformAdaptorBase + public class PlatformGeneratorUniversal32 : PlatformGeneratorBase { - public PlatformABI CallConventionType { get; } = PlatformABI.Universal32; - - public override bool IsArch32 => true; + public override PlatformABI PlatformABI { get; } = PlatformABI.Universal32; //protected override TypeInfo CreateValueType(TypeSig type, bool returnValue) //{ @@ -22,19 +21,11 @@ namespace HybridCLR.Editor.MethodBridge // return CreateGeneralValueType(type, typeSize, actualAliment); //} - protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType) - { - if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN4) - { - return new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN1, type.Size); - } - return type; - } - public override void GenerateManaged2NativeMethod(MethodBridgeSig method, List lines) + public override void GenerateManaged2NativeMethod(MethodDesc method, List lines) { 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 => p.Managed2NativeParamValue(this.CallConventionType)).Concat(new string[] { "method" })); + string paramNameListStr = string.Join(", ", method.ParamInfos.Select(p => p.Managed2NativeParamValue(this.PlatformABI)).Concat(new string[] { "method" })); lines.Add($@" // {method.MethodDef} @@ -45,25 +36,25 @@ static void __M2N_{method.CreateCallSigName()}(const MethodInfo* method, uint16_ }} "); } - public override void GenerateNative2ManagedMethod(MethodBridgeSig method, List lines) + public override void GenerateNative2ManagedMethod(MethodDesc method, List lines) { - int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.CallConventionType); + int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI); string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" })); lines.Add($@" // {method.MethodDef} static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()}({paramListStr}) {{ - StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => p.Native2ManagedParamValue(this.CallConventionType)))} }}; + StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => p.Native2ManagedParamValue(this.PlatformABI)))} }}; StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)}; Interpreter::Execute(method, args, ret); {(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")} }} "); } - public override void GenerateAdjustThunkMethod(MethodBridgeSig method, List lines) + public override void GenerateAdjustThunkMethod(MethodDesc method, List lines) { - int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.CallConventionType); + int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI); string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" })); @@ -71,7 +62,7 @@ static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()} // {method.MethodDef} static {method.ReturnInfo.Type.GetTypeName()} __N2M_AdjustorThunk_{method.CreateCallSigName()}({paramListStr}) {{ - 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.CallConventionType))))} }}; + 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))))} }}; StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)}; Interpreter::Execute(method, args, ret); {(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")} diff --git a/Editor/MethodBridge/PlatformAdaptor_Universal32.cs.meta b/Editor/MethodBridge/PlatformGeneratorUniversal32.cs.meta similarity index 100% rename from Editor/MethodBridge/PlatformAdaptor_Universal32.cs.meta rename to Editor/MethodBridge/PlatformGeneratorUniversal32.cs.meta diff --git a/Editor/MethodBridge/PlatformAdaptor_Universal64.cs b/Editor/MethodBridge/PlatformGeneratorUniversal64.cs similarity index 71% rename from Editor/MethodBridge/PlatformAdaptor_Universal64.cs rename to Editor/MethodBridge/PlatformGeneratorUniversal64.cs index d1950e8..8ed8474 100644 --- a/Editor/MethodBridge/PlatformAdaptor_Universal64.cs +++ b/Editor/MethodBridge/PlatformGeneratorUniversal64.cs @@ -1,4 +1,5 @@ using dnlib.DotNet; +using HybridCLR.Editor.ABI; using System; using System.Collections.Generic; using System.Linq; @@ -6,33 +7,21 @@ using System.Reflection; using System.Text; using System.Threading.Tasks; using UnityEngine; +using TypeInfo = HybridCLR.Editor.ABI.TypeInfo; namespace HybridCLR.Editor.MethodBridge { - public class PlatformAdaptor_Universal64 : PlatformAdaptorBase + public class PlatformGeneratorUniversal64 : PlatformGeneratorBase { - public PlatformABI CallConventionType { get; } = PlatformABI.Universal64; + public override PlatformABI PlatformABI { get; } = PlatformABI.Universal64; - public override bool IsArch32 => false; - - public override bool IsSupportHFA => true; - - protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType) + public override void GenerateManaged2NativeMethod(MethodDesc method, List lines) { - if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN8) - { - return new TypeInfo(ParamOrReturnType.STRUCTURE_ALIGN1, type.Size); - } - return type; - } - - public override void GenerateManaged2NativeMethod(MethodBridgeSig method, List lines) - { - int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.CallConventionType); + int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI); string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" })); string paramTypeListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()}").Concat(new string[] { "const MethodInfo*" })); ; - string paramNameListStr = string.Join(", ", method.ParamInfos.Select(p => p.Managed2NativeParamValue(this.CallConventionType)).Concat(new string[] { "method" })); + string paramNameListStr = string.Join(", ", method.ParamInfos.Select(p => p.Managed2NativeParamValue(this.PlatformABI)).Concat(new string[] { "method" })); lines.Add($@" // {method.MethodDef} @@ -43,15 +32,15 @@ static void __M2N_{method.CreateCallSigName()}(const MethodInfo* method, uint16_ }} "); } - public override void GenerateNative2ManagedMethod(MethodBridgeSig method, List lines) + public override void GenerateNative2ManagedMethod(MethodDesc method, List lines) { - int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.CallConventionType); + int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI); string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" })); lines.Add($@" // {method.MethodDef} static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()}({paramListStr}) {{ - StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => p.Native2ManagedParamValue(this.CallConventionType)))} }}; + StackObject args[{Math.Max(totalQuadWordNum, 1)}] = {{{string.Join(", ", method.ParamInfos.Select(p => p.Native2ManagedParamValue(this.PlatformABI)))} }}; StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)}; Interpreter::Execute(method, args, ret); {(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")} @@ -59,15 +48,15 @@ static {method.ReturnInfo.Type.GetTypeName()} __N2M_{method.CreateCallSigName()} "); } - public override void GenerateAdjustThunkMethod(MethodBridgeSig method, List lines) + public override void GenerateAdjustThunkMethod(MethodDesc method, List lines) { - int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.CallConventionType); + int totalQuadWordNum = method.ParamInfos.Count + method.ReturnInfo.GetParamSlotNum(this.PlatformABI); string paramListStr = string.Join(", ", method.ParamInfos.Select(p => $"{p.Type.GetTypeName()} __arg{p.Index}").Concat(new string[] { "const MethodInfo* method" })); lines.Add($@" // {method.MethodDef} static {method.ReturnInfo.Type.GetTypeName()} __N2M_AdjustorThunk_{method.CreateCallSigName()}({paramListStr}) {{ - 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.CallConventionType))))} }}; + 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))))} }}; StackObject* ret = {(method.ReturnInfo.IsVoid ? "nullptr" : "args + " + method.ParamInfos.Count)}; Interpreter::Execute(method, args, ret); {(!method.ReturnInfo.IsVoid ? $"return *({method.ReturnInfo.Type.GetTypeName()}*)ret;" : "")} diff --git a/Editor/MethodBridge/PlatformAdaptor_Universal64.cs.meta b/Editor/MethodBridge/PlatformGeneratorUniversal64.cs.meta similarity index 100% rename from Editor/MethodBridge/PlatformAdaptor_Universal64.cs.meta rename to Editor/MethodBridge/PlatformGeneratorUniversal64.cs.meta diff --git a/Editor/ReversePInvokeWrap/Analyzer.cs b/Editor/ReversePInvokeWrap/Analyzer.cs new file mode 100644 index 0000000..1323c79 --- /dev/null +++ b/Editor/ReversePInvokeWrap/Analyzer.cs @@ -0,0 +1,65 @@ +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.ReversePInvokeWrap +{ + public class ReversePInvokeMethodInfo + { + public MethodDef Method { get; set; } + + public CustomAttribute GenerationAttribute { get; set; } + } + + public class Analyzer + { + + private readonly List _rootModules = new List(); + + public Analyzer(AssemblyCache cache, List assemblyNames) + { + foreach(var assemblyName in assemblyNames) + { + _rootModules.Add(cache.LoadModule(assemblyName)); + } + } + + public List CollectMonoPInvokeCallbackMethods() + { + var wrapperMethods = new List(); + 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.IsStatic || !method.HasCustomAttributes) + { + continue; + } + CustomAttribute wa = method.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.FullName == "AOT.MonoPInvokeCallbackAttribute"); + if (wa == null) + { + continue; + } + //foreach (var ca in method.CustomAttributes) + //{ + // Debug.Log($"{ca.AttributeType.FullName} {ca.TypeFullName}"); + //} + wrapperMethods.Add(new ReversePInvokeMethodInfo() + { + Method = method, + GenerationAttribute = method.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.FullName == "HybridCLR.ReversePInvokeWrapperGenerationAttribute"), + }); + } + } + return wrapperMethods; + } + } +} diff --git a/Editor/ReversePInvokeWrap/Analyzer.cs.meta b/Editor/ReversePInvokeWrap/Analyzer.cs.meta new file mode 100644 index 0000000..792b5b5 --- /dev/null +++ b/Editor/ReversePInvokeWrap/Analyzer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c172068b408c0e349b2ceee4c4635085 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ReversePInvokeWrapperGenerationAttribute.cs b/Runtime/ReversePInvokeWrapperGenerationAttribute.cs new file mode 100644 index 0000000..3308313 --- /dev/null +++ b/Runtime/ReversePInvokeWrapperGenerationAttribute.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HybridCLR +{ + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + public class ReversePInvokeWrapperGenerationAttribute : Attribute + { + public int ReserveWrapperCount { get; } + + public ReversePInvokeWrapperGenerationAttribute(int reserveWrapperCount) + { + ReserveWrapperCount = reserveWrapperCount; + } + } +} diff --git a/Runtime/ReversePInvokeWrapperGenerationAttribute.cs.meta b/Runtime/ReversePInvokeWrapperGenerationAttribute.cs.meta new file mode 100644 index 0000000..a46bd5a --- /dev/null +++ b/Runtime/ReversePInvokeWrapperGenerationAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f99dd22d9d81b2540b4663b3bcdf0a79 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: