From 415b68aa6a7d1f29788b363cf6f57386b077199f Mon Sep 17 00:00:00 2001 From: johnche Date: Fri, 10 Jan 2025 20:40:51 +0800 Subject: [PATCH] =?UTF-8?q?[unity]=E6=9C=AA=E5=AE=8C=E5=96=84=E7=9A=84?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E5=87=BD=E6=95=B0=E6=94=AF=E6=8C=81=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E5=BA=9F=E4=BB=A3=E7=A0=81=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/extension_methods_gen.tpl.mjs | 4 +- .../puerts/xil2cpp/Puerts_il2cpp.cpp.txt | 41 +- .../ExtensionMethodInfos_Gen_Internal.cs | 30 +- .../core/upm/Runtime/Src/IL2Cpp/JsEnv.cs | 8 +- .../Runtime/Src/IL2Cpp/Native/NativeAPI.cs | 2 +- .../upm/Runtime/Src/IL2Cpp/TypeRegister.cs | 355 ------------------ .../core/upm/Runtime/Src/IL2Cpp/TypeUtils.cs | 17 +- 7 files changed, 63 insertions(+), 394 deletions(-) diff --git a/unity/Assets/core/upm/Editor/Resources/puerts/templates/extension_methods_gen.tpl.mjs b/unity/Assets/core/upm/Editor/Resources/puerts/templates/extension_methods_gen.tpl.mjs index 70f5891429..eb93e91816 100644 --- a/unity/Assets/core/upm/Editor/Resources/puerts/templates/extension_methods_gen.tpl.mjs +++ b/unity/Assets/core/upm/Editor/Resources/puerts/templates/extension_methods_gen.tpl.mjs @@ -17,10 +17,10 @@ namespace PuertsIl2cpp public static class ExtensionMethodInfos_Gen { [UnityEngine.Scripting.Preserve] - public static IEnumerable TryLoadExtensionMethod(Type type) + public static MethodInfo[] TryLoadExtensionMethod(string assemblyQualifiedName) { if (false) {}${FOR(getExtendedTypeToExtensionTypeInfo(rawInfo), e => ` - else if (type == typeof(${e.extendedType})) + else if (typeof(${e.extendedType}).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(${e.extendedType})${FOR(e.extensionTypes, extensionType => `, typeof(${extensionType})`)}); }`)} diff --git a/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/Puerts_il2cpp.cpp.txt b/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/Puerts_il2cpp.cpp.txt index 5f9161e749..5714769a79 100644 --- a/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/Puerts_il2cpp.cpp.txt +++ b/unity/Assets/core/upm/Editor/Resources/puerts/xil2cpp/Puerts_il2cpp.cpp.txt @@ -153,7 +153,7 @@ static Il2CppClass *g_typeofPersistentObjectInfo; static Il2CppClass *g_typeofArrayBuffer; static Il2CppClass *g_typeofTypedValue; -static MethodInfoHelper g_RegisterNoThrowHelper; +static MethodInfoHelper g_ExtensionMethodGetHelper; static void RegisterType(Il2CppClass* klass); static bool ClassNotFoundCallback(const void* typeId) @@ -163,10 +163,9 @@ static bool ClassNotFoundCallback(const void* typeId) return true; } -static void SetRegisterNoThrow(Il2CppReflectionMethod* method) +static void SetExtensionMethodGet(Il2CppReflectionMethod* method) { - g_RegisterNoThrowHelper = MethodInfoHelper(method); - pesapi_on_class_not_found(ClassNotFoundCallback); + g_ExtensionMethodGetHelper = MethodInfoHelper(method); } static std::string GetTypeSignature(const Il2CppType* type); @@ -519,7 +518,8 @@ static void RegisterType(Il2CppClass* klass) return true; }; - try { + try + { if (isDelegate) { MethodInfo* invoke = (MethodInfo*)il2cpp::vm::Class::GetMethodFromName(klass, "Invoke", -1); @@ -578,6 +578,26 @@ static void RegisterType(Il2CppClass* klass) classInfo->Fields.push_back({ std::string(field->name), isStatic, fieldData }); } + + std::string assemblyQualifiedName(Type::GetName(&klass->byval_arg, IL2CPP_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED)); + if (!assemblyQualifiedName.empty()) + { + Il2CppArray* extensionMethods = g_ExtensionMethodGetHelper.Call(il2cpp::vm::String::NewWrapper(assemblyQualifiedName.c_str())); + if (extensionMethods) + { + uint32_t len = Array::GetLength(extensionMethods); + PLog("%s extensionMethods count: %d", klass->name, len); + if (len == 2) //TODO: for test only + { + Il2CppReflectionMethod** arr = reinterpret_cast(il2cpp::vm::Array::GetFirstElementAddress(extensionMethods)); + for (uint32_t i = 0; i < len; ++i) + { + PLog("add extension %d %s", i, arr[i]->method->name); + AddMethod(arr[i]->method, false, false, arr[i]->method->name); + } + } + } + } } } catch (Il2CppExceptionWrapper& exception) @@ -2599,8 +2619,12 @@ static WrapData* CreateOverloadData(const MethodInfo* method) std::string signature = GetMethodSignature(method, false); auto wrap = FindWrapFunc(signature.c_str()); overloadData->Wrap = wrap ? wrap: &ReflectionWrapper; - overloadData->IsStatic = isStatic; - overloadData->IsExtensionMethod = false; + overloadData->IsExtensionMethod = IsExtensionMethod(method); + overloadData->IsStatic = isStatic && !overloadData->IsExtensionMethod; + if (overloadData->IsExtensionMethod) + { + PLog("CreateOverloadData IsExtensionMethod %s , static:%d", method->name, overloadData->IsStatic); + } memcpy(overloadData->TypeInfos, usedTypes.data(), sizeof(void*) * usedTypes.size()); return overloadData; } @@ -2667,6 +2691,7 @@ puerts::JsEnvPrivate* InitialPapiEnvRef(struct pesapi_ffi* apis, pesapi_env_ref { apis->set_property(env, global, "loadType", loadType); apis->set_property(env, global, "createFunction", createFunction); + pesapi_on_class_not_found(ClassNotFoundCallback); return jsEnvPrivate; } } @@ -2723,7 +2748,7 @@ void InitialPuerts(pesapi_func_ptr* func_array) InternalCalls::Add("Puerts.NativeAPI::CleanupPapiEnvRef(System.IntPtr,System.IntPtr)", (Il2CppMethodPointer)puerts::CleanupPapiEnvRef); InternalCalls::Add("Puerts.NativeAPI::DestroyJSEnvPrivate(System.IntPtr)", (Il2CppMethodPointer)puerts::DestroyJSEnvPrivate); InternalCalls::Add("Puerts.JSObject::GetJSObjectValue(System.IntPtr,System.String,System.Type)", (Il2CppMethodPointer)puerts::GetJSObjectValue); - InternalCalls::Add("Puerts.NativeAPI::SetRegisterNoThrow(System.Reflection.MethodBase)", (Il2CppMethodPointer)puerts::SetRegisterNoThrow); + InternalCalls::Add("Puerts.NativeAPI::SetExtensionMethodGet(System.Reflection.MethodBase)", (Il2CppMethodPointer)puerts::SetExtensionMethodGet); InternalCalls::Add("Puerts.NativeAPI::CppGetMethodSignature(System.Reflection.MethodBase,System.Boolean,System.Boolean)", (Il2CppMethodPointer)puerts::CppGetMethodSignature); pesapi_init(func_array); } diff --git a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/ExtensionMethodInfos_Gen_Internal.cs b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/ExtensionMethodInfos_Gen_Internal.cs index 4ac693b087..5ad0e72646 100644 --- a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/ExtensionMethodInfos_Gen_Internal.cs +++ b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/ExtensionMethodInfos_Gen_Internal.cs @@ -15,62 +15,62 @@ namespace PuertsIl2cpp public static class ExtensionMethodInfos_Gen_Internal { [UnityEngine.Scripting.Preserve] - public static IEnumerable TryLoadExtensionMethod(Type type) + public static MethodInfo[] TryLoadExtensionMethod(string assemblyQualifiedName) { if (false) {} - else if (type == typeof(System.Int32[])) + else if (typeof(System.Int32[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.Int32[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.Single[])) + else if (typeof(System.Single[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.Single[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.Double[])) + else if (typeof(System.Double[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.Double[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.Boolean[])) + else if (typeof(System.Boolean[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.Boolean[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.Int64[])) + else if (typeof(System.Int64[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.Int64[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.UInt64[])) + else if (typeof(System.UInt64[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.UInt64[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.SByte[])) + else if (typeof(System.SByte[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.SByte[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.Byte[])) + else if (typeof(System.Byte[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.Byte[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.UInt16[])) + else if (typeof(System.UInt16[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.UInt16[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.Int16[])) + else if (typeof(System.Int16[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.Int16[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.Char[])) + else if (typeof(System.Char[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.Char[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.UInt32[])) + else if (typeof(System.UInt32[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.UInt32[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.String[])) + else if (typeof(System.String[]).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.String[]), typeof(PuertsIl2cpp.ArrayExtension)); } - else if (type == typeof(System.Array)) + else if (typeof(System.Array).AssemblyQualifiedName == assemblyQualifiedName) { return ExtensionMethodInfo.GetExtensionMethods(typeof(System.Array), typeof(PuertsIl2cpp.ArrayExtension)); } diff --git a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs index 37f20854c3..ccaadbe44f 100644 --- a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs +++ b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/JsEnv.cs @@ -32,9 +32,7 @@ public class JsEnv : IDisposable // TypeRegister TypeRegister; Type persistentObjectInfoType; - MethodInfo objectPoolAddMethodInfo; - MethodInfo objectPoolRemoveMethodInfo; - MethodInfo tryLoadTypeMethodInfo; + MethodInfo extensionMethodGetMethodInfo; private Func moduleExecutor; @@ -66,8 +64,8 @@ public JsEnv(ILoader loader, int debugPort = -1) Puerts.NativeAPI.SetLogCallback(LogCallback, LogWarningCallback, LogErrorCallback); Puerts.NativeAPI.InitialPuerts(Puerts.NativeAPI.GetRegsterApi()); apis = Puerts.NativeAPI.GetFFIApi(); - tryLoadTypeMethodInfo = typeof(TypeRegister).GetMethod("RegisterNoThrow"); - Puerts.NativeAPI.SetRegisterNoThrow(tryLoadTypeMethodInfo); + extensionMethodGetMethodInfo = typeof(PuertsIl2cpp.ExtensionMethodInfo).GetMethod("Get"); + Puerts.NativeAPI.SetExtensionMethodGet(extensionMethodGetMethodInfo); persistentObjectInfoType = typeof(Puerts.JSObject); Puerts.NativeAPI.SetGlobalType_TypedValue(typeof(TypedValue)); diff --git a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/Native/NativeAPI.cs b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/Native/NativeAPI.cs index d499c45c21..add40fa073 100644 --- a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/Native/NativeAPI.cs +++ b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/Native/NativeAPI.cs @@ -86,7 +86,7 @@ public static void DestroyJSEnvPrivate(IntPtr jsEnvPrivate) } [MethodImpl(MethodImplOptions.InternalCall)] - public static void SetRegisterNoThrow(MethodBase methodInfo) + public static void SetExtensionMethodGet(MethodBase methodInfo) { } diff --git a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/TypeRegister.cs b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/TypeRegister.cs index 4f6a55a1e0..94b193ec13 100644 --- a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/TypeRegister.cs +++ b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/TypeRegister.cs @@ -26,362 +26,7 @@ internal static void AddRegisterInfoGetter(Type type, Func getter) RegisterInfoManager.Add(type, getter); } - private static IntPtr ReflectionWrapperFunc = IntPtr.Zero; - private static IntPtr ReflectionGetFieldWrapper = IntPtr.Zero; - private static IntPtr ReflectionSetFieldWrapper = IntPtr.Zero; - private static BindingMode GetBindingMode(RegisterInfo info, string name, bool isStatic) - { - var _name = name + (isStatic ? "_static": ""); - if (info == null || !info.Members.ContainsKey(_name)) return RegisterInfoManager.DefaultBindingMode; - return info.Members[_name].UseBindingMode; - } - private static IntPtr GetWrapperFunc(RegisterInfo registerInfo, MemberInfo member, string signature) - { - string name = member.Name; - bool isMethod = member is MethodInfo; - if (isMethod) - { - var method = (MethodInfo)member; - if (method.IsSpecialName && method.Name != "get_Item" && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))) - { - name = member.Name.Substring(4); - } - } - BindingMode bindingMode = GetBindingMode(registerInfo, name, isMethod ? ((MethodInfo)member).IsStatic : false); - IntPtr wrapper = IntPtr.Zero; - if (bindingMode == BindingMode.FastBinding) - { - wrapper = NativeAPI.FindWrapFunc(signature); - } - -#if NOT_GEN_WARNING - if (member is MethodBase && wrapper == IntPtr.Zero) - { - UnityEngine.Debug.LogWarning(string.Format("can't get static method wrapper for {0} declare in {1}, signature:{2}", member, member.DeclaringType, signature)); - } -#endif - - if (wrapper == IntPtr.Zero && bindingMode != BindingMode.DontBinding) - { - wrapper = ReflectionWrapperFunc; - } - - return wrapper; - } - private static void GetFieldWrapper(RegisterInfo registerInfo, string name, bool isStatic, string signature, out IntPtr getter, out IntPtr setter) - { - BindingMode bindingMode = GetBindingMode(registerInfo, name, isStatic); - getter = IntPtr.Zero; - setter = IntPtr.Zero; - if (bindingMode == BindingMode.FastBinding) - { - NativeAPI.FindFieldWrap(signature, out getter, out setter); - } - -#if NOT_GEN_WARNING - if (getter == IntPtr.Zero && setter == IntPtr.Zero) - { - UnityEngine.Debug.LogWarning(string.Format("can't get static field wrapper for {0}, signature:{1}", name, signature)); - } -#endif - - if (getter == IntPtr.Zero && setter == IntPtr.Zero && bindingMode != BindingMode.DontBinding) - { - getter = ReflectionGetFieldWrapper; - setter = ReflectionSetFieldWrapper; - } - } - - //call by native, do not throw!! - public static void RegisterNoThrow(IntPtr typeId, bool includeNonPublic) - { - if (ReflectionWrapperFunc == IntPtr.Zero) ReflectionWrapperFunc = NativeAPI.FindWrapFunc(null); - if (ReflectionGetFieldWrapper == IntPtr.Zero) - { - NativeAPI.FindFieldWrap(null, out ReflectionGetFieldWrapper, out ReflectionSetFieldWrapper); - } - if (RegisterInfoManager == null) RegisterInfoManager = new RegisterInfoManager(); - - try - { - Type type = NativeAPI.TypeIdToType(typeId); - if (type == null) return; - //UnityEngine.Debug.Log(string.Format("try load type {0}", type)); - Register(type, includeNonPublic); - } - catch (Exception e) - { - UnityEngine.Debug.LogError(string.Format("try load type throw {0}", e)); - } - } - - private static void Register(Type type, bool includeNonPublic, bool throwIfMemberFail = false) - { - BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public; - if (includeNonPublic) - { - flag = flag | BindingFlags.NonPublic; - } - - BindingFlags nonPublicInstance = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly; - Register(type, type.GetConstructors(flag), type.GetMethods(flag), type.GetProperties(flag), type.GetProperties(nonPublicInstance), type.GetFields(flag), throwIfMemberFail); - } - - private static void Register(Type type, MethodBase[] ctors = null, MethodBase[] methods = null, PropertyInfo[] properties = null, PropertyInfo[] nonpublic_properties = null, FieldInfo[] fields = null, bool throwIfMemberFail = false) - { - IntPtr typeInfo = IntPtr.Zero; - try - { - bool isDelegate = typeof(MulticastDelegate).IsAssignableFrom(type) && type != typeof(MulticastDelegate); - var typeId = NativeAPI.GetTypeId(type); - //UnityEngine.Debug.Log(string.Format("{0} typeId is {1}", type, typeId)); - var superTypeId = (isDelegate || type == typeof(object) || type.BaseType == null) ? IntPtr.Zero : NativeAPI.GetTypeId(type.BaseType); - - Func getRegisterInfoFunc; - bool hasRegisterInfo = RegisterInfoManager.TryGetValue(type, out getRegisterInfoFunc); - RegisterInfo registerInfo = null; - if (hasRegisterInfo) registerInfo = getRegisterInfoFunc(); - - typeInfo = NativeAPI.CreateCSharpTypeInfo(type.ToString(), typeId, superTypeId, type.IsValueType, isDelegate, isDelegate ? TypeUtils.GetMethodSignature(type.GetMethod("Invoke"), true) : ""); - if (typeInfo == IntPtr.Zero) - { - if (isDelegate) throw new Exception(string.Format("create TypeInfo for {0} fail. maybe the Bridge of delegate is not found!", type)); - throw new Exception(string.Format("create TypeInfo for {0} fail", type)); - } - if (!isDelegate) - { - if (ctors != null && ctors.Length > 0 && (!type.IsArray || type == typeof(System.Array))) - { - foreach (var ctor in ctors) - { - if (ctor.IsGenericMethodDefinition) continue; - List usedTypes = TypeUtils.GetUsedTypes(ctor); - var signature = TypeUtils.GetMethodSignature(ctor); - - var wrapper = GetWrapperFunc(registerInfo, ctor, signature); - if (wrapper == IntPtr.Zero) - { - UnityEngine.Debug.LogWarning(string.Format("wrapper is null for {0}", type)); - continue; - } - //UnityEngine.Debug.Log(string.Format("add ctor {0}, usedTypes count: {1}", ctor, usedTypes.Count)); - - var methodInfoPointer = NativeAPI.GetMethodInfoPointer(ctor); - var methodPointer = NativeAPI.GetMethodPointer(ctor); - if (methodInfoPointer == IntPtr.Zero) - { - UnityEngine.Debug.LogWarning(string.Format("cannot get method info for {0}:{1}, signature:{2}", type, ctor, TypeUtils.GetMethodSignature(ctor))); - continue; - } - if (methodPointer == IntPtr.Zero) - { - UnityEngine.Debug.LogWarning(string.Format("cannot get method pointer for {0}:{1}, signature:{2}", type, ctor, TypeUtils.GetMethodSignature(ctor))); - continue; - } - var wrapData = NativeAPI.AddConstructor( - typeInfo, - signature, - wrapper, - methodInfoPointer, - methodPointer, - usedTypes.Count - ); - if (wrapData == IntPtr.Zero) - { - if (!throwIfMemberFail) - { -#if WARNING_IF_MEMBERFAIL - UnityEngine.Debug.LogWarning(string.Format("add constructor for {0} fail, signature:{1}", type, TypeUtils.GetMethodSignature(ctor))); -#endif - continue; - } - throw new Exception(string.Format("add constructor for {0} fail, signature:{1}", type, TypeUtils.GetMethodSignature(ctor))); - } - for (int i = 0; i < usedTypes.Count; ++i) - { - var usedTypeId = NativeAPI.GetTypeId(usedTypes[i]); - //UnityEngine.Debug.Log(string.Format("set used type for ctor {0}: {1}={2}, typeId:{3}", ctor, i, usedTypes[i], usedTypeId)); - NativeAPI.SetTypeInfo(wrapData, i, usedTypeId); - } - } - } - } - - Action AddMethodToType = (string name, MethodInfo method, bool isGetter, bool isSetter, bool isExtensionMethod) => - { - method = TypeUtils.HandleMaybeGenericMethod(method); - if (method == null) return; - List usedTypes = TypeUtils.GetUsedTypes(method, isExtensionMethod); - var signature = TypeUtils.GetMethodSignature(method, false, isExtensionMethod); - // UnityEngine.Debug.Log(string.Format("add method {0}, usedTypes count: {1}", method, usedTypes.Count)); - - var wrapper = GetWrapperFunc(registerInfo, method, signature); - if (wrapper == IntPtr.Zero) - { - UnityEngine.Debug.LogWarning(string.Format("wrapper is null for {0}:{1}, signature:{2}", type, method, TypeUtils.GetMethodSignature(method, false, isExtensionMethod))); - return; - } - - var methodInfoPointer = NativeAPI.GetMethodInfoPointer(method); - var methodPointer = NativeAPI.GetMethodPointer(method); - if (methodInfoPointer == IntPtr.Zero) - { - UnityEngine.Debug.LogWarning(string.Format("cannot get method info for {0}:{1}, signature:{2}", type, method, TypeUtils.GetMethodSignature(method, false, isExtensionMethod))); - return; - } - if (methodPointer == IntPtr.Zero) - { - UnityEngine.Debug.LogWarning(string.Format("cannot get method pointer for {0}:{1}, signature:{2}", type, method, TypeUtils.GetMethodSignature(method, false, isExtensionMethod))); - return; - } - var wrapData = NativeAPI.AddMethod( - typeInfo, - signature, - wrapper, - name, - !isExtensionMethod && method.IsStatic, - isExtensionMethod, - isGetter, - isSetter, - methodInfoPointer, - methodPointer, - usedTypes.Count - ); - if (wrapData == IntPtr.Zero) - { - if (throwIfMemberFail) - { - throw new Exception(string.Format("add method for {0}:{1} fail, signature:{2}", type, method, TypeUtils.GetMethodSignature(method, false, isExtensionMethod))); - } - else - { -#if WARNING_IF_MEMBERFAIL - UnityEngine.Debug.LogWarning(string.Format("add method for {0}:{1} fail, signature:{2}", type, method, TypeUtils.GetMethodSignature(method, false, isExtensionMethod))); -#endif - return; - } - } - for (int i = 0; i < usedTypes.Count; ++i) - { - var usedTypeId = NativeAPI.GetTypeId(usedTypes[i]); - //UnityEngine.Debug.Log(string.Format("set used type for method {0}: {1}={2}, typeId:{3}", method, i, usedTypes[i], usedTypeId)); - NativeAPI.SetTypeInfo(wrapData, i, usedTypeId); - } - }; - - if (methods != null && (!type.IsArray || type == typeof(System.Array))) - { - foreach (var method in methods) - { - if (method.IsAbstract) continue; - AddMethodToType(method.Name, method as MethodInfo, false, false, false); - } - } - - if (!isDelegate) - { - var extensionMethods = ExtensionMethodInfo.Get(type); - if (extensionMethods != null) - { - foreach (var method in extensionMethods) - { - AddMethodToType(method.Name, method as MethodInfo, false, false, true); - } - } - - if (properties != null) - { - foreach (var prop in properties) - { - var getter = prop.GetGetMethod(); - if (getter != null && !getter.IsGenericMethodDefinition && !getter.IsAbstract) - { - AddMethodToType(prop.Name, getter, true, false, false); - } - var setter = prop.GetSetMethod(); - if (setter != null && !setter.IsGenericMethodDefinition && !setter.IsAbstract) - { - AddMethodToType(prop.Name, setter, false, true, false); - } - } - } - - if (nonpublic_properties != null) - { - foreach (var prop in nonpublic_properties) - { - int dotPos = prop.Name.LastIndexOf('.'); - if (prop.Attributes == PropertyAttributes.None && dotPos != -1) - { - var typeNameWithDot = prop.Name.Substring(0, dotPos + 1); - var propName = prop.Name.Substring(dotPos + 1); - var getter = type.GetMethod(typeNameWithDot + "get_" + propName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); - if (getter != null && !getter.IsGenericMethodDefinition && !getter.IsAbstract) - { - AddMethodToType(propName, getter, true, false, false); - } - var setter = type.GetMethod(typeNameWithDot + "set_" + propName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); - if (setter != null && !setter.IsGenericMethodDefinition && !setter.IsAbstract) - { - AddMethodToType(propName, setter, false, true, false); - } - } - } - } - - if (fields != null) - { - foreach (var field in fields) - { - string signature = (field.IsStatic ? "" : "t") + TypeUtils.GetTypeSignature(field.FieldType); - var name = field.Name; - - IntPtr getter; - IntPtr setter; - GetFieldWrapper(registerInfo, name, field.IsStatic, signature, out getter, out setter); - if (getter == IntPtr.Zero && setter == IntPtr.Zero) - { - UnityEngine.Debug.LogWarning(string.Format("wrapper is null for {0}:{1}, signature:{2}", type, name, signature)); - continue; - } - - if (!NativeAPI.AddField( - typeInfo, - getter, - setter, - name, - field.IsStatic, - NativeAPI.GetFieldInfoPointer(field), - NativeAPI.GetFieldOffset(field, type.IsValueType), - NativeAPI.GetTypeId(field.FieldType)) - ) - { - if (!throwIfMemberFail) - { -#if WARNING_IF_MEMBERFAIL - UnityEngine.Debug.LogWarning(string.Format("add field for {0}:{1} fail, signature:{2}", type, field, signature)); -#endif - continue; - } - throw new Exception(string.Format("add field for {0}:{1} fail, signature:{2}", type, field, signature)); - } - //UnityEngine.Debug.Log(string.Format("AddField {0} of {1} ok offset={2}", field, type, GetFieldOffset(field, type.IsValueType))); - } - } - } - - if (!NativeAPI.RegisterCSharpType(typeInfo)) - { - throw new Exception(string.Format("Register for {0} fail", type)); - } - } - catch(Exception e) - { - NativeAPI.ReleaseCSharpTypeInfo(typeInfo); - throw e; - } - } } } #endif diff --git a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/TypeUtils.cs b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/TypeUtils.cs index 4be36a5352..5a2e2c1d74 100644 --- a/unity/Assets/core/upm/Runtime/Src/IL2Cpp/TypeUtils.cs +++ b/unity/Assets/core/upm/Runtime/Src/IL2Cpp/TypeUtils.cs @@ -46,20 +46,21 @@ private static Type GetExtendedType(MethodInfo method) } // Call By Gen Code - public static IEnumerable GetExtensionMethods(Type type, params Type[] extensions) + public static MethodInfo[] GetExtensionMethods(Type type, params Type[] extensions) { - return from e in extensions from m in e.GetMethods(BindingFlags.Static | BindingFlags.Public) - where !m.IsSpecialName && GetExtendedType(m) == type select m; + return (from e in extensions from m in e.GetMethods(BindingFlags.Static | BindingFlags.Public) + where !m.IsSpecialName && GetExtendedType(m) == type select m).ToArray(); } - public static IEnumerable Get(Type type) + [UnityEngine.Scripting.Preserve] + public static MethodInfo[] Get(string assemblyQualifiedName) { if (LoadExtensionMethod != null) - return LoadExtensionMethod(type); + return LoadExtensionMethod(assemblyQualifiedName); return null; } - public static Func> LoadExtensionMethod; + public static Func LoadExtensionMethod; public static bool LoadExtensionMethodInfo() { var ExtensionMethodInfos_Gen = (from assembly in AppDomain.CurrentDomain.GetAssemblies() @@ -69,8 +70,8 @@ public static bool LoadExtensionMethodInfo() { select assembly.GetType("PuertsIl2cpp.ExtensionMethodInfos_Gen_Internal")).FirstOrDefault(x => x != null); var TryLoadExtensionMethod = ExtensionMethodInfos_Gen.GetMethod("TryLoadExtensionMethod"); if (TryLoadExtensionMethod == null) return false; - LoadExtensionMethod = (Func>)Delegate.CreateDelegate( - typeof(Func>), null, TryLoadExtensionMethod); + LoadExtensionMethod = (Func)Delegate.CreateDelegate( + typeof(Func), null, TryLoadExtensionMethod); return true; } }