From 7067ed19102785c50268c77ee5da3a0e5e0ccedb Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Thu, 22 Nov 2018 02:56:01 -0500 Subject: [PATCH] [corlib] Refactor Type:GetName () to reduce differences with refsources and make it easier to add support for stack marks later. (#11154) * [corlib] Refactor Type:GetName () to reduce differences with refsources and make it easier to add support for stack marks later. Move the icall to RuntimeTypeHandle. Pass a unused stack mark and a unused reflectionOnly parameter. * Bump API snapshot submodule --- configure.ac | 2 +- external/api-snapshot | 2 +- mcs/class/corlib/ReferenceSources/Type.cs | 58 ---------------------- mcs/class/corlib/System/RuntimeTypeHandle.cs | 37 ++++++++++++++ mcs/class/corlib/Test/System/TypeTest.cs | 6 +-- .../referencesource/mscorlib/system/rttype.cs | 3 +- mcs/class/referencesource/mscorlib/system/type.cs | 7 ++- mono/metadata/icall-def.h | 4 +- mono/metadata/icall.c | 7 ++- 9 files changed, 55 insertions(+), 71 deletions(-) diff --git a/configure.ac b/configure.ac index 31bc6e0a60c..fc8dc0a4b33 100644 --- a/configure.ac +++ b/configure.ac @@ -48,7 +48,7 @@ MONO_VERSION_BUILD=`echo $VERSION | cut -d . -f 3` # There is no ordering of corlib versions, no old or new, # the runtime expects an exact match. # -MONO_CORLIB_VERSION=5FEF1218-A70A-4752-9D8E-0A73E497190B +MONO_CORLIB_VERSION=9E44EF5E-26C3-4EF6-8EE5-582372D0CA0A # # Put a quoted #define in config.h. diff --git a/external/api-snapshot b/external/api-snapshot index ab81df74c13..b7f2f0f0b32 160000 --- a/external/api-snapshot +++ b/external/api-snapshot @@ -1 +1 @@ -Subproject commit ab81df74c13e4329ec7b600efe76e8bbb5e76efa +Subproject commit b7f2f0f0b328bb82bb75366a5de18328a69fcd2f diff --git a/mcs/class/corlib/ReferenceSources/Type.cs b/mcs/class/corlib/ReferenceSources/Type.cs index 8514a0fe765..c518c185aa9 100644 --- a/mcs/class/corlib/ReferenceSources/Type.cs +++ b/mcs/class/corlib/ReferenceSources/Type.cs @@ -41,64 +41,6 @@ namespace System public virtual bool IsGenericMethodParameter => IsGenericParameter && DeclaringMethod != null; public virtual bool IsByRefLike => throw new NotSupportedException(SR.NotSupported_SubclassOverride); - #region Requires stack backtracing fixes in unmanaged type_from_name - - [MethodImplAttribute(MethodImplOptions.InternalCall)] - static extern Type internal_from_name (string name, bool throwOnError, bool ignoreCase); - - public static Type GetType(string typeName) - { - return GetType (typeName, false, false); - } - - public static Type GetType(string typeName, bool throwOnError) - { - return GetType (typeName, throwOnError, false); - } - - public static Type GetType(string typeName, bool throwOnError, bool ignoreCase) - { - if (typeName == null) - throw new ArgumentNullException ("TypeName"); - - if (typeName == String.Empty) - if (throwOnError) - throw new TypeLoadException ("A null or zero length string does not represent a valid Type."); - else - return null; - Type t = internal_from_name (typeName, throwOnError, ignoreCase); - if (throwOnError && t == null) - throw new TypeLoadException ("Error loading '" + typeName + "'"); - - return t; - } - - #endregion - - // TODO: Merge with internal_from_name - public static Type ReflectionOnlyGetType (string typeName, - bool throwIfNotFound, - bool ignoreCase) - { - if (typeName == null) - throw new ArgumentNullException ("typeName"); - if (typeName == String.Empty && throwIfNotFound) - throw new TypeLoadException ("A null or zero length string does not represent a valid Type"); - int idx = typeName.IndexOf (','); - if (idx < 0 || idx == 0 || idx == typeName.Length - 1) - throw new ArgumentException ("Assembly qualifed type name is required", "typeName"); - string an = typeName.Substring (idx + 1); - Assembly a; - try { - a = Assembly.ReflectionOnlyLoad (an); - } catch { - if (throwIfNotFound) - throw; - return null; - } - return a.GetType (typeName.Substring (0, idx), throwIfNotFound, ignoreCase); - } - internal virtual Type InternalResolve () { return UnderlyingSystemType; diff --git a/mcs/class/corlib/System/RuntimeTypeHandle.cs b/mcs/class/corlib/System/RuntimeTypeHandle.cs index 15d412eed73..2c3ea5ff559 100644 --- a/mcs/class/corlib/System/RuntimeTypeHandle.cs +++ b/mcs/class/corlib/System/RuntimeTypeHandle.cs @@ -261,5 +261,42 @@ namespace System [PreserveDependency (".ctor()", "System.Runtime.CompilerServices.IsByRefLikeAttribute")] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern static bool IsByRefLike (RuntimeType type); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + static extern RuntimeType internal_from_name (string name, ref StackCrawlMark stackMark, Assembly callerAssembly, bool throwOnError, bool ignoreCase, bool reflectionOnly); + + internal static RuntimeType GetTypeByName(string typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly, ref StackCrawlMark stackMark, + bool loadTypeFromPartialName) + { + if (typeName == null) + throw new ArgumentNullException ("typeName"); + + if (typeName == String.Empty) + if (throwOnError) + throw new TypeLoadException ("A null or zero length string does not represent a valid Type."); + else + return null; + + if (reflectionOnly) { + int idx = typeName.IndexOf (','); + if (idx < 0 || idx == 0 || idx == typeName.Length - 1) + throw new ArgumentException ("Assembly qualifed type name is required", "typeName"); + string an = typeName.Substring (idx + 1); + Assembly a; + try { + a = Assembly.ReflectionOnlyLoad (an); + } catch { + if (throwOnError) + throw; + return null; + } + return (RuntimeType)a.GetType (typeName.Substring (0, idx), throwOnError, ignoreCase); + } + + var t = internal_from_name (typeName, ref stackMark, null, throwOnError, ignoreCase, false); + if (throwOnError && t == null) + throw new TypeLoadException ("Error loading '" + typeName + "'"); + return t; + } } } diff --git a/mcs/class/corlib/Test/System/TypeTest.cs b/mcs/class/corlib/Test/System/TypeTest.cs index 5ca72d91b6d..95ad1cebbb9 100644 --- a/mcs/class/corlib/Test/System/TypeTest.cs +++ b/mcs/class/corlib/Test/System/TypeTest.cs @@ -2792,7 +2792,7 @@ namespace MonoTests.System Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); Assert.IsNull (ex.InnerException, "#3"); Assert.IsNotNull (ex.Message, "#4"); - Assert.AreEqual ("TypeName", ex.ParamName, "#5"); + Assert.AreEqual ("typeName", ex.ParamName, "#5"); } } @@ -2806,7 +2806,7 @@ namespace MonoTests.System Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); Assert.IsNull (ex.InnerException, "#3"); Assert.IsNotNull (ex.Message, "#4"); - Assert.AreEqual ("TypeName", ex.ParamName, "#5"); + Assert.AreEqual ("typeName", ex.ParamName, "#5"); } } @@ -2820,7 +2820,7 @@ namespace MonoTests.System Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); Assert.IsNull (ex.InnerException, "#3"); Assert.IsNotNull (ex.Message, "#4"); - Assert.AreEqual ("TypeName", ex.ParamName, "#5"); + Assert.AreEqual ("typeName", ex.ParamName, "#5"); } } diff --git a/mcs/class/referencesource/mscorlib/system/rttype.cs b/mcs/class/referencesource/mscorlib/system/rttype.cs index 685731f0df1..3af60533452 100644 --- a/mcs/class/referencesource/mscorlib/system/rttype.cs +++ b/mcs/class/referencesource/mscorlib/system/rttype.cs @@ -1972,7 +1972,7 @@ namespace System #region Static Members #region Internal -#if !MONO + internal static RuntimeType GetType(String typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly, ref StackCrawlMark stackMark) { @@ -1989,6 +1989,7 @@ namespace System typeName, throwOnError, ignoreCase, reflectionOnly, ref stackMark, false); } +#if !MONO internal static MethodBase GetMethodBase(RuntimeModule scope, int typeMetadataToken) { return GetMethodBase(ModuleHandle.ResolveMethodHandleInternal(scope, typeMetadataToken)); diff --git a/mcs/class/referencesource/mscorlib/system/type.cs b/mcs/class/referencesource/mscorlib/system/type.cs index d483626dae5..cef9cac275c 100644 --- a/mcs/class/referencesource/mscorlib/system/type.cs +++ b/mcs/class/referencesource/mscorlib/system/type.cs @@ -87,7 +87,6 @@ namespace System { // case-sensitive by default). //// -#if !MONO [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static Type GetType(String typeName, bool throwOnError, bool ignoreCase) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; @@ -106,7 +105,7 @@ namespace System { return RuntimeType.GetType(typeName, false, false, false, ref stackMark); } -#endif + #if !FEATURE_CORECLR [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static Type GetType( @@ -141,14 +140,14 @@ namespace System { return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark); } #endif //!FEATURE_CORECLR -#if !MONO + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable public static Type ReflectionOnlyGetType(String typeName, bool throwIfNotFound, bool ignoreCase) { StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; return RuntimeType.GetType(typeName, throwIfNotFound, ignoreCase, true /*reflectionOnly*/, ref stackMark); } -#endif + public virtual Type MakePointerType() { throw new NotSupportedException(); } public virtual StructLayoutAttribute StructLayoutAttribute { get { throw new NotSupportedException(); } } public virtual Type MakeByRefType() { throw new NotSupportedException(); } diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index e84e1397404..4d1d5cf3949 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -920,7 +920,8 @@ HANDLES(RTH_15, "IsInstanceOfType", ves_icall_RuntimeTypeHandle_IsInstanceOfType HANDLES(RTH_16, "IsPointer", ves_icall_RuntimeTypeHandle_IsPointer, MonoBoolean, 1, (MonoReflectionType)) HANDLES(RTH_17, "IsPrimitive", ves_icall_RuntimeTypeHandle_IsPrimitive, MonoBoolean, 1, (MonoReflectionType)) //HANDLES(RTH_17a, "is_subclass_of", ves_icall_RuntimeTypeHandle_is_subclass_of, MonoBoolean, 2, (MonoType_ptr, MonoType_ptr)) -NOHANDLES(ICALL(RTH_17a, "is_subclass_of", ves_icall_RuntimeTypeHandle_is_subclass_of)) +HANDLES(RTH_17a, "internal_from_name", ves_icall_System_RuntimeTypeHandle_internal_from_name, MonoReflectionType, 6, (MonoString, gpointer, MonoReflectionAssembly, MonoBoolean, MonoBoolean, MonoBoolean)) +NOHANDLES(ICALL(RTH_17b, "is_subclass_of", ves_icall_RuntimeTypeHandle_is_subclass_of)) HANDLES(RTH_18, "type_is_assignable_from", ves_icall_RuntimeTypeHandle_type_is_assignable_from, guint32, 2, (MonoReflectionType, MonoReflectionType)) ICALL_TYPE(RNG, "System.Security.Cryptography.RNGCryptoServiceProvider", RNG_1) @@ -1148,7 +1149,6 @@ HANDLES(WAITH_2, "Wait_internal", ves_icall_System_Threading_WaitHandle_Wait_int ICALL_TYPE(TYPE, "System.Type", TYPE_1) HANDLES(TYPE_1, "internal_from_handle", ves_icall_System_Type_internal_from_handle, MonoReflectionType, 1, (MonoType_ref)) -HANDLES(TYPE_2, "internal_from_name", ves_icall_System_Type_internal_from_name, MonoReflectionType, 3, (MonoString, MonoBoolean, MonoBoolean)) ICALL_TYPE(TYPEDR, "System.TypedReference", TYPEDR_1) HANDLES(TYPEDR_1, "InternalToObject", mono_TypedReference_ToObject, MonoObject, 1, (MonoTypedRef_ptr)) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 644ae85158e..67bde5a6d54 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -1480,9 +1480,12 @@ fail: } MonoReflectionTypeHandle -ves_icall_System_Type_internal_from_name (MonoStringHandle name, +ves_icall_System_RuntimeTypeHandle_internal_from_name (MonoStringHandle name, + gpointer stack_mark, + MonoReflectionAssemblyHandle callerAssembly, MonoBoolean throwOnError, MonoBoolean ignoreCase, + MonoBoolean reflectionOnly, MonoError *error) { MonoTypeNameParse info; @@ -1490,6 +1493,8 @@ ves_icall_System_Type_internal_from_name (MonoStringHandle name, MonoAssembly *caller_assembly; MonoReflectionTypeHandle type = MONO_HANDLE_NEW (MonoReflectionType, NULL); + /* The callerAssembly argument is unused for now */ + char *str = mono_string_handle_to_utf8 (name, error); goto_if_nok (error, leave); -- 2.11.4.GIT