Permalink
Browse files

Support for not wrapping exceptions with TargetInvocationException. (#…

…13767)

* Support for not wrapping exceptions with TargetInvocationException.

For dotnet/corefx#22866.

* Respond to PR feedback.

Mainly by making "WrapExceptions" consistently positive in FCalls.

* Remove BindingFlags.DoNotWrapExceptions tests in deference to CoreFX tests.
  • Loading branch information...
AustinWise authored and AtsushiKan committed Sep 6, 2017
1 parent 8c64be6 commit 1f9aeeb7a3685bc7fd1098fc50d91ac81bae4873
@@ -46,5 +46,6 @@ public enum BindingFlags
// These are a couple of misc attributes used
IgnoreReturn = 0x01000000, // This is used in COM Interop
DoNotWrapExceptions = 0x02000000, // Disables wrapping exceptions in TargetInvocationException
}
}
@@ -51,7 +51,6 @@ private Activator()
return CreateInstance(type, bindingAttr, binder, args, culture, null);
}
[System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
static public Object CreateInstance(Type type,
BindingFlags bindingAttr,
Binder binder,
@@ -80,8 +79,7 @@ private Activator()
if (rt == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(type));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return rt.CreateInstanceImpl(bindingAttr, binder, args, culture, activationAttributes, ref stackMark);
return rt.CreateInstanceImpl(bindingAttr, binder, args, culture, activationAttributes);
}
static public Object CreateInstance(Type type, params Object[] args)
@@ -111,8 +109,12 @@ static public Object CreateInstance(Type type)
return Activator.CreateInstance(type, false);
}
[System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
static public Object CreateInstance(Type type, bool nonPublic)
{
return CreateInstance(type, nonPublic, wrapExceptions: true);
}
static internal Object CreateInstance(Type type, bool nonPublic, bool wrapExceptions)
{
if ((object)type == null)
throw new ArgumentNullException(nameof(type));
@@ -123,11 +125,9 @@ static public Object CreateInstance(Type type, bool nonPublic)
if (rt == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(type));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return rt.CreateInstanceDefaultCtor(!nonPublic, false, true, ref stackMark);
return rt.CreateInstanceDefaultCtor(!nonPublic, false, true, wrapExceptions);
}
[System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
static public T CreateInstance<T>()
{
RuntimeType rt = typeof(T) as RuntimeType;
@@ -137,10 +137,8 @@ static public T CreateInstance<T>()
if (rt.HasElementType)
throw new MissingMethodException(SR.Arg_NoDefCTor);
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
// Skip the CreateInstanceCheckThis call to avoid perf cost and to maintain compatibility with V2 (throwing the same exceptions).
return (T)rt.CreateInstanceDefaultCtor(true /*publicOnly*/, true /*skipCheckThis*/, true /*fillCache*/, ref stackMark);
return (T)rt.CreateInstanceDefaultCtor(true /*publicOnly*/, true /*skipCheckThis*/, true /*fillCache*/, true /*wrapExceptions*/);
}
}
}
@@ -487,18 +487,19 @@ public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder
throw new TargetParameterCountException(SR.Arg_ParmCnt);
// if we are here we passed all the previous checks. Time to look at the arguments
bool wrapExceptions = (invokeAttr & BindingFlags.DoNotWrapExceptions) == 0;
Object retValue = null;
if (actualCount > 0)
{
Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, false);
retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, false, wrapExceptions);
// copy out. This should be made only if ByRef are present.
for (int index = 0; index < arguments.Length; index++)
parameters[index] = arguments[index];
}
else
{
retValue = RuntimeMethodHandle.InvokeMethod(null, null, sig, false);
retValue = RuntimeMethodHandle.InvokeMethod(null, null, sig, false, wrapExceptions);
}
GC.KeepAlive(this);
@@ -363,16 +363,17 @@ internal void ThrowNoInvokeException()
throw new TargetParameterCountException(SR.Arg_ParmCnt);
// if we are here we passed all the previous checks. Time to look at the arguments
bool wrapExceptions = (invokeAttr & BindingFlags.DoNotWrapExceptions) == 0;
if (actualCount > 0)
{
Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, sig, false);
Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, sig, false, wrapExceptions);
// copy out. This should be made only if ByRef are present.
for (int index = 0; index < arguments.Length; index++)
parameters[index] = arguments[index];
return retValue;
}
return RuntimeMethodHandle.InvokeMethod(obj, null, sig, false);
return RuntimeMethodHandle.InvokeMethod(obj, null, sig, false, wrapExceptions);
}
public override MethodBody GetMethodBody()
@@ -433,16 +434,17 @@ public override Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] p
// JIT/NGen will insert the call to .cctor in the instance ctor.
// if we are here we passed all the previous checks. Time to look at the arguments
bool wrapExceptions = (invokeAttr & BindingFlags.DoNotWrapExceptions) == 0;
if (actualCount > 0)
{
Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
Object retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, true);
Object retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, true, wrapExceptions);
// copy out. This should be made only if ByRef are present.
for (int index = 0; index < arguments.Length; index++)
parameters[index] = arguments[index];
return retValue;
}
return RuntimeMethodHandle.InvokeMethod(null, null, sig, true);
return RuntimeMethodHandle.InvokeMethod(null, null, sig, true, wrapExceptions);
}
#endregion
}
@@ -466,7 +466,7 @@ public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder
{
object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
return UnsafeInvokeInternal(obj, parameters, arguments);
return UnsafeInvokeInternal(obj, invokeAttr, parameters, arguments);
}
[DebuggerStepThroughAttribute]
@@ -475,18 +475,19 @@ internal object UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder,
{
object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
return UnsafeInvokeInternal(obj, parameters, arguments);
return UnsafeInvokeInternal(obj, invokeAttr, parameters, arguments);
}
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
private object UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
private object UnsafeInvokeInternal(Object obj, BindingFlags invokeAttr, Object[] parameters, Object[] arguments)
{
bool wrapExceptions = (invokeAttr & BindingFlags.DoNotWrapExceptions) == 0;
if (arguments == null || arguments.Length == 0)
return RuntimeMethodHandle.InvokeMethod(obj, null, Signature, false);
return RuntimeMethodHandle.InvokeMethod(obj, null, Signature, false, wrapExceptions);
else
{
Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, Signature, false);
Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, Signature, false, wrapExceptions);
// copy out. This should be made only if ByRef are present.
for (int index = 0; index < arguments.Length; index++)
@@ -4629,7 +4629,7 @@ private void CreateInstanceCheckThis()
}
internal Object CreateInstanceImpl(
BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, ref StackCrawlMark stackMark)
BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
{
CreateInstanceCheckThis();
@@ -4646,10 +4646,12 @@ private void CreateInstanceCheckThis()
// deal with the __COMObject case first. It is very special because from a reflection point of view it has no ctors
// so a call to GetMemberCons would fail
bool publicOnly = (bindingAttr & BindingFlags.NonPublic) == 0;
bool wrapExceptions = (bindingAttr & BindingFlags.DoNotWrapExceptions) == 0;
if (argCnt == 0 && (bindingAttr & BindingFlags.Public) != 0 && (bindingAttr & BindingFlags.Instance) != 0
&& (IsGenericCOMObjectImpl() || IsValueType))
{
server = CreateInstanceDefaultCtor((bindingAttr & BindingFlags.NonPublic) == 0, false, true, ref stackMark);
server = CreateInstanceDefaultCtor(publicOnly, false, true, wrapExceptions);
}
else
{
@@ -4707,7 +4709,7 @@ private void CreateInstanceCheckThis()
}
// fast path??
server = Activator.CreateInstance(this, true);
server = Activator.CreateInstance(this, nonPublic: true, wrapExceptions: wrapExceptions);
}
else
{
@@ -4801,15 +4803,15 @@ internal void SetEntry(ActivatorCacheEntry ace)
private static volatile ActivatorCache s_ActivatorCache;
// the slow path of CreateInstanceDefaultCtor
internal Object CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
internal Object CreateInstanceSlow(bool publicOnly, bool wrapExceptions, bool skipCheckThis, bool fillCache)
{
RuntimeMethodHandleInternal runtime_ctor = default(RuntimeMethodHandleInternal);
bool bCanBeCached = false;
if (!skipCheckThis)
CreateInstanceCheckThis();
Object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, ref bCanBeCached, ref runtime_ctor);
Object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, wrapExceptions, ref bCanBeCached, ref runtime_ctor);
if (bCanBeCached && fillCache)
{
@@ -4833,7 +4835,7 @@ internal Object CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fil
// fillCache is set in the SL2/3 compat mode or when called from Marshal.PtrToStructure.
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
internal Object CreateInstanceDefaultCtor(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
internal Object CreateInstanceDefaultCtor(bool publicOnly, bool skipCheckThis, bool fillCache, bool wrapExceptions)
{
if (GetType() == typeof(ReflectionOnlyType))
throw new InvalidOperationException(SR.InvalidOperation_NotAllowedInReflectionOnly);
@@ -4866,15 +4868,15 @@ internal Object CreateInstanceDefaultCtor(bool publicOnly, bool skipCheckThis, b
{
ace.m_ctor(instance);
}
catch (Exception e)
catch (Exception e) when (wrapExceptions)
{
throw new TargetInvocationException(e);
}
}
return instance;
}
}
return CreateInstanceSlow(publicOnly, skipCheckThis, fillCache, ref stackMark);
return CreateInstanceSlow(publicOnly, wrapExceptions, skipCheckThis, fillCache);
}
internal void InvalidateCachedNestedType()
@@ -930,7 +930,6 @@ public static void PtrToStructure<T>(IntPtr ptr, T structure)
// Creates a new instance of "structuretype" and marshals data from a
// native memory block to it.
//====================================================================
[System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static Object PtrToStructure(IntPtr ptr, Type structureType)
{
if (ptr == IntPtr.Zero) return null;
@@ -946,9 +945,7 @@ public static Object PtrToStructure(IntPtr ptr, Type structureType)
if (rt == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(structureType));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Object structure = rt.CreateInstanceDefaultCtor(false /*publicOnly*/, false /*skipCheckThis*/, false /*fillCache*/, ref stackMark);
Object structure = rt.CreateInstanceDefaultCtor(false /*publicOnly*/, false /*skipCheckThis*/, false /*fillCache*/, true /*wrapExceptions*/);
PtrToStructureHelper(ptr, structure, true);
return structure;
}
@@ -220,7 +220,7 @@ internal static IntPtr[] CopyRuntimeTypeHandles(Type[] inHandles, out int length
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object CreateInstance(RuntimeType type, bool publicOnly, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor);
internal static extern Object CreateInstance(RuntimeType type, bool publicOnly, bool wrapExceptions, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object CreateCaInstance(RuntimeType type, IRuntimeMethodInfo ctor);
@@ -912,7 +912,7 @@ internal static Utf8String GetUtf8Name(RuntimeMethodHandleInternal method)
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static object InvokeMethod(object target, object[] arguments, Signature sig, bool constructor);
internal extern static object InvokeMethod(object target, object[] arguments, Signature sig, bool constructor, bool wrapExceptions);
#region Private Invocation Helpers
internal static INVOCATION_FLAGS GetSecurityFlags(IRuntimeMethodInfo handle)
Oops, something went wrong.

0 comments on commit 1f9aeeb

Please sign in to comment.