diff options
author | Michal Strehovsky <michals@microsoft.com> | 2018-03-20 10:12:25 +0300 |
---|---|---|
committer | Michal Strehovsky <michals@microsoft.com> | 2018-03-20 10:12:25 +0300 |
commit | a669542d5f10ff79df7e127a4229cfe5775ddd28 (patch) | |
tree | 08ba68bad0ff6fca5333b2d8ea67e6b1702a9b80 /src/System.Private.Reflection.Execution | |
parent | 611aec1781d1998fbe1dc1562eafba42853a25de (diff) |
Add pointer type unwrapping for return values
In my change to add support for System.Reflection.Pointer I missed unwrapping pointers in return type signatures. I wrote a test for it, but it seems like the test lucks out on Windows (and only fails on OSX/Linux in CoreRT).
[tfs-changeset: 1692590]
Diffstat (limited to 'src/System.Private.Reflection.Execution')
-rw-r--r-- | src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs | 59 |
1 files changed, 25 insertions, 34 deletions
diff --git a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs index d3f56469c..ad2675351 100644 --- a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs +++ b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs @@ -471,27 +471,17 @@ namespace Internal.Reflection.Execution } } - private IntPtr GetDynamicMethodInvokerThunk(RuntimeTypeHandle[] argHandles, MethodBase methodInfo) + private IntPtr GetDynamicMethodInvokerThunk(MethodBase methodInfo) { - ParameterInfo[] parameters = methodInfo.GetParametersNoCopy(); - // last entry in argHandles is the return type if the type is not typeof(void) - Debug.Assert(parameters.Length == argHandles.Length || parameters.Length == (argHandles.Length - 1)); - - bool[] byRefParameters = new bool[parameters.Length + 1]; - RuntimeTypeHandle[] parameterTypeHandles = new RuntimeTypeHandle[parameters.Length + 1]; - - // This is either a constructor ("returns" void) or an instance method - MethodInfo reflectionMethodInfo = methodInfo as MethodInfo; - parameterTypeHandles[0] = (reflectionMethodInfo != null ? reflectionMethodInfo.ReturnType.TypeHandle : CommonRuntimeTypes.Void.TypeHandle); - byRefParameters[0] = false; - - for (int i = 0; i < parameters.Length; i++) - { - parameterTypeHandles[i + 1] = argHandles[i]; - byRefParameters[i + 1] = parameters[i].ParameterType.IsByRef; - } - - return CallConverterThunk.MakeThunk(ThunkKind.ReflectionDynamicInvokeThunk, IntPtr.Zero, IntPtr.Zero, false, parameterTypeHandles, byRefParameters, null); + MethodParametersInfo methodParamsInfo = new MethodParametersInfo(methodInfo); + return CallConverterThunk.MakeThunk( + ThunkKind.ReflectionDynamicInvokeThunk, + IntPtr.Zero, + IntPtr.Zero, + false, + methodParamsInfo.ReturnTypeAndParameterTypeHandles.ToArray(), + methodParamsInfo.ReturnTypeAndParametersByRefFlags, + null); } private RuntimeTypeHandle[] GetDynamicInvokeInstantiationArguments(MethodBase reflectionMethodBase) @@ -510,6 +500,17 @@ namespace Internal.Reflection.Execution if (!returnType.Equals(CommonRuntimeTypes.Void)) dynamicInvokeMethodGenArguments.Add(returnType.TypeHandle); + for (int i = 0; i < dynamicInvokeMethodGenArguments.Count; i++) + { + // We can't instantiate over pointer types, so the DynamicInvoke method compensates for it already. + RuntimeTypeHandle type = dynamicInvokeMethodGenArguments[i]; + while (RuntimeAugments.IsUnmanagedPointerType(type)) + { + type = RuntimeAugments.GetRelatedParameterTypeHandle(type); + } + dynamicInvokeMethodGenArguments[i] = type; + } + return dynamicInvokeMethodGenArguments.ToArray(); } @@ -599,17 +600,17 @@ namespace Internal.Reflection.Execution methodHandle.NativeFormatHandle); } - RuntimeTypeHandle[] dynInvokeMethodArgs = GetDynamicInvokeInstantiationArguments(methodInfo); - IntPtr dynamicInvokeMethod; IntPtr dynamicInvokeMethodGenericDictionary; if ((methodInvokeMetadata.InvokeTableFlags & InvokeTableFlags.NeedsParameterInterpretation) != 0) { - dynamicInvokeMethod = GetDynamicMethodInvokerThunk(dynInvokeMethodArgs, methodInfo); + dynamicInvokeMethod = GetDynamicMethodInvokerThunk(methodInfo); dynamicInvokeMethodGenericDictionary = IntPtr.Zero; } else { + RuntimeTypeHandle[] dynInvokeMethodArgs = GetDynamicInvokeInstantiationArguments(methodInfo); + GetDynamicMethodInvokeMethodInfo( methodInvokeMetadata.MappingTableModule, methodInvokeMetadata.DynamicInvokeCookie, @@ -1451,17 +1452,7 @@ namespace Internal.Reflection.Execution { Type parameterType = parameters[i].ParameterType; - // If the parameter is a pointer type, we unwrap it. - if (parameterType.IsPointer) - { - do - { - parameterType = parameterType.GetElementType(); - } while (parameterType.IsPointer); - - result.Add(parameterType.TypeHandle); - } - else if (parameterType.IsByRef) + if (parameterType.IsByRef) result.Add(parameterType.GetElementType().TypeHandle); else if (parameterType.GetTypeInfo().IsEnum && !parameters[i].HasDefaultValue) result.Add(Enum.GetUnderlyingType(parameterType).TypeHandle); |