Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Support for not wrapping exceptions with TargetInvocationException. (#…
Browse files Browse the repository at this point in the history
…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 1f9aeeb
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 83 deletions.
1 change: 1 addition & 0 deletions src/mscorlib/shared/System/Reflection/BindingFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
18 changes: 8 additions & 10 deletions src/mscorlib/src/System/Activator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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));
Expand All @@ -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;
Expand All @@ -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*/);
}
}
}
5 changes: 3 additions & 2 deletions src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 6 additions & 4 deletions src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
}
Expand Down
11 changes: 6 additions & 5 deletions src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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++)
Expand Down
18 changes: 10 additions & 8 deletions src/mscorlib/src/System/RtType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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
{
Expand Down Expand Up @@ -4707,7 +4709,7 @@ private void CreateInstanceCheckThis()
}

// fast path??
server = Activator.CreateInstance(this, true);
server = Activator.CreateInstance(this, nonPublic: true, wrapExceptions: wrapExceptions);
}
else
{
Expand Down Expand Up @@ -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)
{
Expand All @@ -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);
Expand Down Expand Up @@ -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()
Expand Down
5 changes: 1 addition & 4 deletions src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions src/mscorlib/src/System/RuntimeHandles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 1f9aeeb

Please sign in to comment.