diff options
-rw-r--r-- | src/System.Private.CoreLib/Resources/Strings.resx | 2 | ||||
-rw-r--r-- | src/System.Private.CoreLib/src/System/Activator.cs | 2 | ||||
-rw-r--r-- | src/System.Private.CoreLib/src/System/RtType.cs | 9 | ||||
-rw-r--r-- | src/System.Private.CoreLib/src/System/RuntimeHandles.cs | 2 | ||||
-rw-r--r-- | src/vm/reflectioninvocation.cpp | 24 | ||||
-rw-r--r-- | src/vm/runtimehandles.h | 5 |
6 files changed, 29 insertions, 15 deletions
diff --git a/src/System.Private.CoreLib/Resources/Strings.resx b/src/System.Private.CoreLib/Resources/Strings.resx index de7eb5ba00..fe7ea71be3 100644 --- a/src/System.Private.CoreLib/Resources/Strings.resx +++ b/src/System.Private.CoreLib/Resources/Strings.resx @@ -584,7 +584,7 @@ <value>Must specify binding flags describing the invoke operation required (BindingFlags.InvokeMethod CreateInstance GetField SetField GetProperty SetProperty).</value> </data> <data name="Arg_NoDefCTor" xml:space="preserve"> - <value>No parameterless constructor defined for this object.</value> + <value>No parameterless constructor defined for type '{0}'.</value> </data> <data name="Arg_NoITypeInfo" xml:space="preserve"> <value>Specified TypeInfo was invalid because it did not support the ITypeInfo interface.</value> diff --git a/src/System.Private.CoreLib/src/System/Activator.cs b/src/System.Private.CoreLib/src/System/Activator.cs index c2197d4c3b..88c7e60a11 100644 --- a/src/System.Private.CoreLib/src/System/Activator.cs +++ b/src/System.Private.CoreLib/src/System/Activator.cs @@ -221,7 +221,7 @@ namespace System // This is a workaround to maintain compatibility with V2. Without this we would throw a NotSupportedException for void[]. // Array, Ref, and Pointer types don't have default constructors. if (rt.HasElementType) - throw new MissingMethodException(SR.Arg_NoDefCTor); + throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, rt)); // Skip the CreateInstanceCheckThis call to avoid perf cost and to maintain compatibility with V2 (throwing the same exceptions). return (T)rt.CreateInstanceDefaultCtor(publicOnly: true, skipCheckThis: true, fillCache: true, wrapExceptions: true); diff --git a/src/System.Private.CoreLib/src/System/RtType.cs b/src/System.Private.CoreLib/src/System/RtType.cs index 3bab50597e..743e2291e5 100644 --- a/src/System.Private.CoreLib/src/System/RtType.cs +++ b/src/System.Private.CoreLib/src/System/RtType.cs @@ -4768,11 +4768,16 @@ namespace System { RuntimeMethodHandleInternal runtime_ctor = default; bool bCanBeCached = false; + bool bHasNoDefaultCtor = false; if (!skipCheckThis) CreateInstanceCheckThis(); - object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, wrapExceptions, ref bCanBeCached, ref runtime_ctor); + object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, wrapExceptions, ref bCanBeCached, ref runtime_ctor, ref bHasNoDefaultCtor); + if (bHasNoDefaultCtor) + { + throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, this)); + } if (bCanBeCached && fillCache) { @@ -4809,7 +4814,7 @@ namespace System if (ace.m_ctor != null && (ace.m_ctorAttributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) { - throw new MissingMethodException(SR.Arg_NoDefCTor); + throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, this)); } } diff --git a/src/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/System.Private.CoreLib/src/System/RuntimeHandles.cs index 03d9233f59..030b9abaf8 100644 --- a/src/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -219,7 +219,7 @@ namespace System } [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object CreateInstance(RuntimeType type, bool publicOnly, bool wrapExceptions, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor); + internal static extern object CreateInstance(RuntimeType type, bool publicOnly, bool wrapExceptions, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor, ref bool hasNoDefaultCtor); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern object CreateCaInstance(RuntimeType type, IRuntimeMethodInfo ctor); diff --git a/src/vm/reflectioninvocation.cpp b/src/vm/reflectioninvocation.cpp index d9ed5fb98b..dd112ebf0a 100644 --- a/src/vm/reflectioninvocation.cpp +++ b/src/vm/reflectioninvocation.cpp @@ -372,18 +372,21 @@ FCIMPL1(Object*, RuntimeTypeHandle::Allocate, ReflectClassBaseObject* pTypeUNSAF }//Allocate FCIMPLEND -FCIMPL5(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refThisUNSAFE, +FCIMPL6(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refThisUNSAFE, CLR_BOOL publicOnly, CLR_BOOL wrapExceptions, CLR_BOOL* pbCanBeCached, - MethodDesc** pConstructor) { + MethodDesc** pConstructor, + CLR_BOOL* pbHasNoDefaultCtor) { CONTRACTL { FCALL_CHECK; PRECONDITION(CheckPointer(refThisUNSAFE)); PRECONDITION(CheckPointer(pbCanBeCached)); PRECONDITION(CheckPointer(pConstructor)); + PRECONDITION(CheckPointer(pbHasNoDefaultCtor)); PRECONDITION(*pbCanBeCached == false); PRECONDITION(*pConstructor == NULL); + PRECONDITION(*pbHasNoDefaultCtor == false); } CONTRACTL_END; @@ -406,8 +409,10 @@ FCIMPL5(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT MethodTable* pVMT; // Get the type information associated with refThis - if (thisTH.IsNull() || thisTH.IsTypeDesc()) - COMPlusThrow(kMissingMethodException,W("Arg_NoDefCTor")); + if (thisTH.IsNull() || thisTH.IsTypeDesc()) { + *pbHasNoDefaultCtor = true; + goto DoneCreateInstance; + } pVMT = thisTH.AsMethodTable(); @@ -458,7 +463,8 @@ FCIMPL5(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT // if this is a Value class we can simply allocate one and return it if (!pVMT->IsValueType()) { - COMPlusThrow(kMissingMethodException,W("Arg_NoDefCTor")); + *pbHasNoDefaultCtor = true; + goto DoneCreateInstance; } // Handle the nullable<T> special case @@ -480,8 +486,10 @@ FCIMPL5(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT // Validate the method can be called by this caller DWORD attr = pMeth->GetAttrs(); - if (!IsMdPublic(attr) && publicOnly) - COMPlusThrow(kMissingMethodException, W("Arg_NoDefCTor")); + if (!IsMdPublic(attr) && publicOnly) { + *pbHasNoDefaultCtor = true; + goto DoneCreateInstance; + } // We've got the class, lets allocate it and call the constructor OBJECTREF o; @@ -515,7 +523,7 @@ FCIMPL5(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT } } } - +DoneCreateInstance: HELPER_METHOD_FRAME_END(); return OBJECTREFToObject(rv); } diff --git a/src/vm/runtimehandles.h b/src/vm/runtimehandles.h index dc379d827e..e1f265d36e 100644 --- a/src/vm/runtimehandles.h +++ b/src/vm/runtimehandles.h @@ -126,11 +126,12 @@ public: // Static method on RuntimeTypeHandle static FCDECL1(Object*, Allocate, ReflectClassBaseObject *refType) ; //A.CI work - static FCDECL5(Object*, CreateInstance, ReflectClassBaseObject* refThisUNSAFE, + static FCDECL6(Object*, CreateInstance, ReflectClassBaseObject* refThisUNSAFE, CLR_BOOL publicOnly, CLR_BOOL wrapExceptions, CLR_BOOL *pbCanBeCached, - MethodDesc** pConstructor); + MethodDesc** pConstructor, + CLR_BOOL *pbHasNoDefaultCtor); static FCDECL2(Object*, CreateCaInstance, ReflectClassBaseObject* refCaType, ReflectMethodObject* pCtorUNSAFE); |