Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>2018-03-28 09:35:28 +0300
committerGitHub <noreply@github.com>2018-03-28 09:35:28 +0300
commitdfcd12f92c37d7533dcf7a48e9ab16295d84cf31 (patch)
tree36f98cf44ba75e41d27729edc1ecf763e93f5652 /src
parente0b0120beb94f211664e2c9f71a680b8ba926d0b (diff)
Use a shared DynamicInvoke for delegates and reflection (#5615)
When I did the `System.Reflection.Pointer` support for reflection invoke and delegate `DynamicInvoke`, I found these two thunks do pretty much the same thing. They got implemented separately because I was just porting Project N IL2IL code, but there's no reason why we need two. With this change, Delegate.DynamicInvoke will just call into the shared helper that is also used for reflection invoke. This is a bigger diff due to bunch of mechanical changes: * The set of generated helpers had to be moved to a place from where both delegate and reflection infrastructure can see it. A type system context dot file did the trick. (Contributes to #3873.) * The generated assembly got moved to the type system context so that the thunks can stay homed in it. * Fix to CppCodegen name mangling so that these can be still referenced in CppCodegen.
Diffstat (limited to 'src')
-rw-r--r--src/Common/src/TypeSystem/IL/DelegateInfo.cs48
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/DelegateThunks.Sorting.cs11
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/DelegateThunks.cs246
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/DynamicInvokeMethodThunk.Sorting.cs8
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/DynamicInvokeMethodThunk.cs138
-rw-r--r--src/Common/src/TypeSystem/IL/TypeSystemContext.DelegateInfo.cs18
-rw-r--r--src/Common/src/TypeSystem/IL/TypeSystemContext.DynamicInvoke.cs31
-rw-r--r--src/Common/src/TypeSystem/IL/TypeSystemContext.GeneratedAssembly.Sorting.cs23
-rw-r--r--src/Common/src/TypeSystem/IL/TypeSystemContext.GeneratedAssembly.cs252
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/AnalysisBasedMetadataManager.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/Compilation.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/CompilationModuleGroup.cs47
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.Sorting.cs22
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.cs198
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/CoreRTNameMangler.cs6
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/GeneratingMetadataManager.cs26
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/ILScannerBuilder.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/MetadataManager.cs112
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/MultiFileCompilationModuleGroup.cs3
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/SingleFileCompilationModuleGroup.cs5
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/SingleMethodCompilationModuleGroup.cs1
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs4
-rw-r--r--src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj8
-rw-r--r--src/ILCompiler.Compiler/tests/DependencyGraphTests.cs2
-rw-r--r--src/ILCompiler.Compiler/tests/DevirtualizationTests.cs2
-rw-r--r--src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilationBuilder.cs2
-rw-r--r--src/ILCompiler.TypeSystem/src/ILCompiler.TypeSystem.csproj15
-rw-r--r--src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyCodegenNodeFactory.cs2
-rw-r--r--src/ILCompiler.WebAssembly/src/Compiler/WebAssemblyCodegenCompilationBuilder.cs2
-rw-r--r--src/ILCompiler/src/Program.cs12
-rw-r--r--src/System.Private.CoreLib/src/System/Delegate.cs17
-rw-r--r--src/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj3
35 files changed, 587 insertions, 690 deletions
diff --git a/src/Common/src/TypeSystem/IL/DelegateInfo.cs b/src/Common/src/TypeSystem/IL/DelegateInfo.cs
index 8da4a6d58..8b5fc4dfb 100644
--- a/src/Common/src/TypeSystem/IL/DelegateInfo.cs
+++ b/src/Common/src/TypeSystem/IL/DelegateInfo.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.Collections.Generic;
using Internal.IL.Stubs;
@@ -17,13 +18,19 @@ namespace Internal.IL
/// </summary>
public class DelegateInfo
{
- private TypeDesc _delegateType;
+ private readonly TypeDesc _delegateType;
+ private readonly DelegateFeature _supportedFeatures;
private MethodSignature _signature;
private MethodDesc _getThunkMethod;
private DelegateThunkCollection _thunks;
+ public static bool SupportsDynamicInvoke(TypeSystemContext context)
+ {
+ return DynamicInvokeMethodThunk.SupportsDynamicInvoke(context);
+ }
+
/// <summary>
/// Gets the synthetic methods that support this delegate type.
/// </summary>
@@ -78,6 +85,14 @@ namespace Internal.IL
}
}
+ public DelegateFeature SupportedFeatures
+ {
+ get
+ {
+ return _supportedFeatures;
+ }
+ }
+
/// <summary>
/// Gets the type of the delegate.
/// </summary>
@@ -89,12 +104,13 @@ namespace Internal.IL
}
}
- public DelegateInfo(TypeDesc delegateType)
+ public DelegateInfo(TypeDesc delegateType, DelegateFeature features)
{
Debug.Assert(delegateType.IsDelegate);
Debug.Assert(delegateType.IsTypeDefinition);
_delegateType = delegateType;
+ _supportedFeatures = features;
}
}
@@ -119,7 +135,6 @@ namespace Internal.IL
_openStaticThunk = new DelegateInvokeOpenStaticThunk(owningDelegate);
_multicastThunk = new DelegateInvokeMulticastThunk(owningDelegate);
_closedStaticThunk = new DelegateInvokeClosedStaticThunk(owningDelegate);
- _invokeThunk = new DelegateDynamicInvokeThunk(owningDelegate);
_closedInstanceOverGeneric = new DelegateInvokeInstanceClosedOverGenericMethodThunk(owningDelegate);
// Methods that have a byref-like type in the signature cannot be invoked with the object array thunk.
@@ -151,12 +166,20 @@ namespace Internal.IL
if (normalizedReturnType.IsPointer || normalizedReturnType.IsFunctionPointer)
generateObjectArrayThunk = false;
- if (generateObjectArrayThunk)
+ if ((owningDelegate.SupportedFeatures & DelegateFeature.ObjectArrayThunk) != 0 && generateObjectArrayThunk)
_invokeObjectArrayThunk = new DelegateInvokeObjectArrayThunk(owningDelegate);
+ //
+ // Check whether we have a reverse p/invoke thunk
+ //
+
if (!owningDelegate.Type.HasInstantiation && IsNativeCallingConventionCompatible(delegateSignature))
_reversePInvokeThunk = new DelegateReversePInvokeThunk(owningDelegate);
+ //
+ // Check whether we have an open instance thunk
+ //
+
if (delegateSignature.Length > 0)
{
TypeDesc firstParam = delegateSignature[0];
@@ -193,6 +216,16 @@ namespace Internal.IL
}
}
+ //
+ // Check whether we have a dynamic invoke stub
+ //
+
+ if ((owningDelegate.SupportedFeatures & DelegateFeature.DynamicInvoke) != 0 &&
+ DynamicInvokeMethodThunk.SupportsSignature(delegateSignature))
+ {
+ var sig = new DynamicInvokeMethodSignature(delegateSignature);
+ _invokeThunk = owningDelegate.Type.Context.GetDynamicInvokeThunk(sig);
+ }
}
#region Temporary interop logic
@@ -285,4 +318,11 @@ namespace Internal.IL
ReversePinvokeThunk = 6, // This may not exist
ObjectArrayThunk = 7, // This may not exist
}
+
+ [Flags]
+ public enum DelegateFeature
+ {
+ DynamicInvoke = 0x1,
+ ObjectArrayThunk = 0x2,
+ }
}
diff --git a/src/Common/src/TypeSystem/IL/Stubs/DelegateThunks.Sorting.cs b/src/Common/src/TypeSystem/IL/Stubs/DelegateThunks.Sorting.cs
index f30a11c9c..d921c9c3b 100644
--- a/src/Common/src/TypeSystem/IL/Stubs/DelegateThunks.Sorting.cs
+++ b/src/Common/src/TypeSystem/IL/Stubs/DelegateThunks.Sorting.cs
@@ -51,17 +51,6 @@ namespace Internal.IL.Stubs
protected internal override int ClassCode => 1993292344;
}
- partial class DelegateDynamicInvokeThunk
- {
- protected internal override int ClassCode => -1127289330;
-
- protected internal override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
- {
- var otherMethod = (DelegateDynamicInvokeThunk)other;
- return comparer.Compare(_delegateInfo.Type, otherMethod._delegateInfo.Type);
- }
- }
-
partial class DelegateGetThunkMethodOverride
{
protected internal override int ClassCode => -321263379;
diff --git a/src/Common/src/TypeSystem/IL/Stubs/DelegateThunks.cs b/src/Common/src/TypeSystem/IL/Stubs/DelegateThunks.cs
index ed29e211f..a4e4b8896 100644
--- a/src/Common/src/TypeSystem/IL/Stubs/DelegateThunks.cs
+++ b/src/Common/src/TypeSystem/IL/Stubs/DelegateThunks.cs
@@ -661,232 +661,6 @@ namespace Internal.IL.Stubs
}
/// <summary>
- /// Delegate thunk that supports Delegate.DynamicInvoke. This thunk has heavy dependencies on the
- /// general dynamic invocation infrastructure in System.InvokeUtils and gets called from there
- /// at runtime. See comments in System.InvokeUtils for a more thorough explanation.
- /// </summary>
- public sealed partial class DelegateDynamicInvokeThunk : ILStubMethod
- {
- private DelegateInfo _delegateInfo;
- private MethodSignature _signature;
-
- public DelegateDynamicInvokeThunk(DelegateInfo delegateInfo)
- {
- _delegateInfo = delegateInfo;
- }
-
- public override TypeSystemContext Context
- {
- get
- {
- return _delegateInfo.Type.Context;
- }
- }
-
- public override TypeDesc OwningType
- {
- get
- {
- return _delegateInfo.Type;
- }
- }
-
- public override MethodSignature Signature
- {
- get
- {
- if (_signature == null)
- {
- _signature = new MethodSignature(0, 0,
- Context.GetWellKnownType(WellKnownType.Object),
- new TypeDesc[] {
- Context.GetWellKnownType(WellKnownType.Object),
- Context.GetWellKnownType(WellKnownType.IntPtr),
- ArgSetupStateType.MakeByRefType() });
- }
- return _signature;
- }
- }
-
- public override Instantiation Instantiation
- {
- get
- {
- return Instantiation.Empty;
- }
- }
-
- public override string Name
- {
- get
- {
- return "DynamicInvokeImpl";
- }
- }
-
- private MetadataType InvokeUtilsType
- {
- get
- {
- return Context.SystemModule.GetKnownType("System", "InvokeUtils");
- }
- }
-
- private MetadataType ArgSetupStateType
- {
- get
- {
- return InvokeUtilsType.GetNestedType("ArgSetupState");
- }
- }
-
- public override MethodIL EmitIL()
- {
- ILEmitter emitter = new ILEmitter();
- ILCodeStream argSetupStream = emitter.NewCodeStream();
- ILCodeStream callSiteSetupStream = emitter.NewCodeStream();
-
- // This function will look like
- //
- // !For each parameter to the delegate
- // !if (parameter is In Parameter)
- // localX is TypeOfParameterX&
- // ldtoken TypeOfParameterX
- // call DynamicInvokeParamHelperIn(RuntimeTypeHandle)
- // stloc localX
- // !else
- // localX is TypeOfParameter
- // ldtoken TypeOfParameterX
- // call DynamicInvokeParamHelperRef(RuntimeTypeHandle)
- // stloc localX
-
- // ldarg.3
- // call DynamicInvokeArgSetupComplete(ref ArgSetupState)
-
- // *** Second instruction stream starts here ***
-
- // ldarg.1 // Load this pointer
- // !For each parameter
- // !if (parameter is In Parameter)
- // ldloc localX
- // ldobj TypeOfParameterX
- // !else
- // ldloc localX
- // ldarg.1
- // calli ReturnType thiscall(TypeOfParameter1, ...)
- // !if ((ReturnType == void)
- // ldnull
- // !else if (ReturnType is pointer)
- // System.Reflection.Pointer.Box(ReturnType)
- // !else if (ReturnType is a byref)
- // ldobj StripByRef(ReturnType)
- // box StripByRef(ReturnType)
- // !else
- // box ReturnType
- // ret
-
- callSiteSetupStream.EmitLdArg(1);
-
- MethodSignature delegateSignature = _delegateInfo.Signature;
-
- TypeDesc[] targetMethodParameters = new TypeDesc[delegateSignature.Length];
-
- for (int paramIndex = 0; paramIndex < delegateSignature.Length; paramIndex++)
- {
- TypeDesc paramType = delegateSignature[paramIndex];
- TypeDesc localType = paramType;
-
- targetMethodParameters[paramIndex] = paramType;
-
- if (localType.IsByRef)
- {
- // Strip ByRef
- localType = ((ByRefType)localType).ParameterType;
- }
- else
- {
- // Only if this is not a ByRef, convert the parameter type to something boxable.
- // Everything but pointer types are boxable.
- localType = ConvertToBoxableType(localType);
- }
-
- ILLocalVariable local = emitter.NewLocal(localType.MakeByRefType());
-
- callSiteSetupStream.EmitLdLoc(local);
-
- argSetupStream.Emit(ILOpcode.ldtoken, emitter.NewToken(localType));
-
- if (paramType.IsByRef)
- {
- argSetupStream.Emit(ILOpcode.call, emitter.NewToken(InvokeUtilsType.GetKnownMethod("DynamicInvokeParamHelperRef", null)));
- }
- else
- {
- argSetupStream.Emit(ILOpcode.call, emitter.NewToken(InvokeUtilsType.GetKnownMethod("DynamicInvokeParamHelperIn", null)));
-
- callSiteSetupStream.Emit(ILOpcode.ldobj, emitter.NewToken(paramType));
- }
- argSetupStream.EmitStLoc(local);
- }
-
- argSetupStream.EmitLdArg(3);
- argSetupStream.Emit(ILOpcode.call, emitter.NewToken(InvokeUtilsType.GetKnownMethod("DynamicInvokeArgSetupComplete", null)));
-
- callSiteSetupStream.EmitLdArg(2);
-
- TypeDesc returnType = delegateSignature.ReturnType;
- MethodSignature targetMethodSig = new MethodSignature(0, 0, returnType, targetMethodParameters);
-
- callSiteSetupStream.Emit(ILOpcode.calli, emitter.NewToken(targetMethodSig));
-
-
- if (returnType.IsVoid)
- {
- callSiteSetupStream.Emit(ILOpcode.ldnull);
- }
- else if (returnType.IsByRef)
- {
- TypeDesc targetType = ((ByRefType)returnType).ParameterType;
- callSiteSetupStream.Emit(ILOpcode.ldobj, emitter.NewToken(targetType));
- callSiteSetupStream.Emit(ILOpcode.box, emitter.NewToken(targetType));
- }
- else if (returnType.IsPointer)
- {
- callSiteSetupStream.Emit(ILOpcode.ldtoken, emitter.NewToken(returnType));
- MethodDesc getTypeFromHandleMethod =
- Context.SystemModule.GetKnownType("System", "Type").GetKnownMethod("GetTypeFromHandle", null);
- callSiteSetupStream.Emit(ILOpcode.call, emitter.NewToken(getTypeFromHandleMethod));
-
- MethodDesc pointerBoxMethod =
- Context.SystemModule.GetKnownType("System.Reflection", "Pointer").GetKnownMethod("Box", null);
- callSiteSetupStream.Emit(ILOpcode.call, emitter.NewToken(pointerBoxMethod));
- }
- else if (returnType.IsFunctionPointer)
- {
- callSiteSetupStream.Emit(ILOpcode.box, emitter.NewToken(Context.GetWellKnownType(WellKnownType.IntPtr)));
- }
- else
- {
- callSiteSetupStream.Emit(ILOpcode.box, emitter.NewToken(returnType));
- }
-
- callSiteSetupStream.Emit(ILOpcode.ret);
-
- return emitter.Link(this);
- }
-
- internal static TypeDesc ConvertToBoxableType(TypeDesc type)
- {
- if (type.IsFunctionPointer)
- {
- return type.Context.GetWellKnownType(WellKnownType.IntPtr);
- }
-
- return type;
- }
- }
-
- /// <summary>
/// Synthetic method override of "IntPtr Delegate.GetThunk(Int32)". This method is injected
/// into all delegate types and provides means for System.Delegate to access the various thunks
/// generated by the compiler.
@@ -964,7 +738,25 @@ namespace Internal.IL.Stubs
{
codeStream.EmitLabel(labels[(int)i]);
- codeStream.Emit(ILOpcode.ldftn, emitter.NewToken(thunk.InstantiateAsOpen()));
+ if (i == DelegateThunkKind.DelegateInvokeThunk)
+ {
+ // Dynamic invoke thunk is special since we're calling into a shared helper
+ MethodDesc targetMethod;
+ if (thunk.HasInstantiation)
+ {
+ TypeDesc[] inst = DynamicInvokeMethodThunk.GetThunkInstantiationForMethod(_delegateInfo.Type.InstantiateAsOpen().GetMethod("Invoke", null));
+ targetMethod = Context.GetInstantiatedMethod(thunk, new Instantiation(inst));
+ }
+ else
+ {
+ targetMethod = thunk;
+ }
+ codeStream.Emit(ILOpcode.ldftn, emitter.NewToken(targetMethod));
+ }
+ else
+ {
+ codeStream.Emit(ILOpcode.ldftn, emitter.NewToken(thunk.InstantiateAsOpen()));
+ }
codeStream.Emit(ILOpcode.ret);
}
}
diff --git a/src/Common/src/TypeSystem/IL/Stubs/DynamicInvokeMethodThunk.Sorting.cs b/src/Common/src/TypeSystem/IL/Stubs/DynamicInvokeMethodThunk.Sorting.cs
index 4fc9fcfba..041d3fa3e 100644
--- a/src/Common/src/TypeSystem/IL/Stubs/DynamicInvokeMethodThunk.Sorting.cs
+++ b/src/Common/src/TypeSystem/IL/Stubs/DynamicInvokeMethodThunk.Sorting.cs
@@ -12,9 +12,9 @@ namespace Internal.IL.Stubs
// Functionality related to determinstic ordering of types
partial class DynamicInvokeMethodThunk
{
- protected override int ClassCode => -1980933220;
+ protected internal override int ClassCode => -1980933220;
- protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
+ protected internal override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
{
return CompareTo((DynamicInvokeMethodThunk)other);
}
@@ -58,9 +58,9 @@ namespace Internal.IL.Stubs
partial class DynamicInvokeThunkGenericParameter
{
- protected override int ClassCode => -234393261;
+ protected internal override int ClassCode => -234393261;
- protected override int CompareToImpl(TypeDesc other, TypeSystemComparer comparer)
+ protected internal override int CompareToImpl(TypeDesc other, TypeSystemComparer comparer)
{
var otherType = (DynamicInvokeThunkGenericParameter)other;
int result = Index - otherType.Index;
diff --git a/src/Common/src/TypeSystem/IL/Stubs/DynamicInvokeMethodThunk.cs b/src/Common/src/TypeSystem/IL/Stubs/DynamicInvokeMethodThunk.cs
index 23698813f..e10aac6c2 100644
--- a/src/Common/src/TypeSystem/IL/Stubs/DynamicInvokeMethodThunk.cs
+++ b/src/Common/src/TypeSystem/IL/Stubs/DynamicInvokeMethodThunk.cs
@@ -18,7 +18,7 @@ namespace Internal.IL.Stubs
/// dependencies on the general dynamic invocation infrastructure in System.InvokeUtils and gets called from there
/// at runtime. See comments in System.InvokeUtils for a more thorough explanation.
/// </summary>
- internal partial class DynamicInvokeMethodThunk : ILStubMethod
+ public partial class DynamicInvokeMethodThunk : ILStubMethod
{
private TypeDesc _owningType;
private DynamicInvokeMethodSignature _targetSignature;
@@ -32,11 +32,125 @@ namespace Internal.IL.Stubs
_targetSignature = signature;
}
- public static bool SupportsThunks(TypeSystemContext context)
+ internal static bool SupportsDynamicInvoke(TypeSystemContext context)
{
return context.SystemModule.GetType("System", "InvokeUtils", false) != null;
}
+ public static bool SupportsSignature(MethodSignature signature)
+ {
+ for (int i = 0; i < signature.Length; i++)
+ if (signature[i].IsByRef && ((ByRefType)signature[i]).ParameterType.IsPointer)
+ return false;
+
+ // ----------------------------------------------------------------
+ // TODO: function pointer types are odd: https://github.com/dotnet/corert/issues/1929
+ // ----------------------------------------------------------------
+
+ if (signature.ReturnType.IsFunctionPointer)
+ return false;
+
+ for (int i = 0; i < signature.Length; i++)
+ if (signature[i].IsFunctionPointer)
+ return false;
+
+ // ----------------------------------------------------------------
+ // Methods with ByRef returns can't be reflection invoked
+ // ----------------------------------------------------------------
+
+ if (signature.ReturnType.IsByRef)
+ return false;
+
+ // ----------------------------------------------------------------
+ // Methods that return ByRef-like types or take them by reference can't be reflection invoked
+ // ----------------------------------------------------------------
+
+ if (!signature.ReturnType.IsSignatureVariable && signature.ReturnType.IsByRefLike)
+ return false;
+
+ for (int i = 0; i < signature.Length; i++)
+ {
+ ByRefType paramType = signature[i] as ByRefType;
+ if (paramType != null && !paramType.ParameterType.IsSignatureVariable && paramType.ParameterType.IsByRefLike)
+ return false;
+ }
+
+ return true;
+ }
+
+ public static TypeDesc[] GetThunkInstantiationForMethod(MethodDesc method)
+ {
+ MethodSignature sig = method.Signature;
+
+ ParameterMetadata[] paramMetadata = null;
+ TypeDesc[] instantiation = new TypeDesc[sig.ReturnType.IsVoid ? sig.Length : sig.Length + 1];
+
+ for (int i = 0; i < sig.Length; i++)
+ {
+ TypeDesc parameterType = sig[i];
+ if (parameterType.IsByRef)
+ {
+ // strip ByRefType off the parameter (the method already has ByRef in the signature)
+ parameterType = ((ByRefType)parameterType).ParameterType;
+
+ Debug.Assert(!parameterType.IsPointer); // TODO: support for methods returning pointer types - https://github.com/dotnet/corert/issues/2113
+ }
+ else if (parameterType.IsPointer)
+ {
+ // Strip off all the pointers. Pointers are not valid instantiation arguments and the thunk compensates for that
+ // by being specialized for the specific pointer depth.
+ while (parameterType.IsPointer)
+ parameterType = ((PointerType)parameterType).ParameterType;
+ }
+ else if (parameterType.IsEnum)
+ {
+ // If the invoke method takes an enum as an input parameter and there is no default value for
+ // that paramter, we don't need to specialize on the exact enum type (we only need to specialize
+ // on the underlying integral type of the enum.)
+ if (paramMetadata == null)
+ paramMetadata = method.GetParameterMetadata();
+
+ bool hasDefaultValue = false;
+ foreach (var p in paramMetadata)
+ {
+ // Parameter metadata indexes are 1-based (0 is reserved for return "parameter")
+ if (p.Index == (i + 1) && p.HasDefault)
+ {
+ hasDefaultValue = true;
+ break;
+ }
+ }
+
+ if (!hasDefaultValue)
+ parameterType = parameterType.UnderlyingType;
+ }
+
+ instantiation[i] = parameterType;
+ }
+
+ if (!sig.ReturnType.IsVoid)
+ {
+ TypeDesc returnType = sig.ReturnType;
+ Debug.Assert(!returnType.IsByRef);
+
+ // If the invoke method return an object reference, we don't need to specialize on the
+ // exact type of the object reference, as the behavior is not different.
+ if ((returnType.IsDefType && !returnType.IsValueType) || returnType.IsArray)
+ {
+ returnType = method.Context.GetWellKnownType(WellKnownType.Object);
+ }
+
+ // Strip off all the pointers. Pointers are not valid instantiation arguments and the thunk compensates for that
+ // by being specialized for the specific pointer depth.
+ while (returnType.IsPointer)
+ returnType = ((PointerType)returnType).ParameterType;
+
+ instantiation[sig.Length] = returnType;
+ }
+
+ return instantiation;
+ }
+
public override TypeSystemContext Context
{
get
@@ -69,6 +183,14 @@ namespace Internal.IL.Stubs
}
}
+ public DynamicInvokeMethodSignature TargetSignature
+ {
+ get
+ {
+ return _targetSignature;
+ }
+ }
+
public override MethodSignature Signature
{
get
@@ -380,10 +502,12 @@ namespace Internal.IL.Stubs
/// <summary>
/// Wraps a <see cref="MethodSignature"/> to reduce it's fidelity.
/// </summary>
- internal struct DynamicInvokeMethodSignature : IEquatable<DynamicInvokeMethodSignature>
+ public struct DynamicInvokeMethodSignature : IEquatable<DynamicInvokeMethodSignature>
{
private MethodSignature _signature;
+ public TypeSystemContext Context => _signature.ReturnType.Context;
+
public bool HasReturnValue
{
get
@@ -400,7 +524,7 @@ namespace Internal.IL.Stubs
}
}
- public DynamicInvokeMethodParameterKind this[int index]
+ internal DynamicInvokeMethodParameterKind this[int index]
{
get
{
@@ -437,7 +561,7 @@ namespace Internal.IL.Stubs
return GetNumberOfIndirections(_signature.ReturnType);
}
- public DynamicInvokeMethodParameterKind ReturnType
+ internal DynamicInvokeMethodParameterKind ReturnType
{
get
{
@@ -455,9 +579,7 @@ namespace Internal.IL.Stubs
public DynamicInvokeMethodSignature(MethodSignature concreteSignature)
{
- // ByRef returns should have been filtered out elsewhere. We don't handle them
- // because reflection can't invoke such methods.
- Debug.Assert(!concreteSignature.ReturnType.IsByRef);
+ Debug.Assert(DynamicInvokeMethodThunk.SupportsSignature(concreteSignature));
_signature = concreteSignature;
}
diff --git a/src/Common/src/TypeSystem/IL/TypeSystemContext.DelegateInfo.cs b/src/Common/src/TypeSystem/IL/TypeSystemContext.DelegateInfo.cs
index 4f186e219..a835b47d0 100644
--- a/src/Common/src/TypeSystem/IL/TypeSystemContext.DelegateInfo.cs
+++ b/src/Common/src/TypeSystem/IL/TypeSystemContext.DelegateInfo.cs
@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Collections.Generic;
using Internal.IL;
@@ -13,6 +12,10 @@ namespace Internal.TypeSystem
{
private class DelegateInfoHashtable : LockFreeReaderHashtable<TypeDesc, DelegateInfo>
{
+ private enum CoreLibSupportLevel { Unknown, Supported, Unsupported }
+
+ private CoreLibSupportLevel _supportLevel;
+
protected override int GetKeyHashCode(TypeDesc key)
{
return key.GetHashCode();
@@ -31,7 +34,18 @@ namespace Internal.TypeSystem
}
protected override DelegateInfo CreateValueFromKey(TypeDesc key)
{
- return new DelegateInfo(key);
+ if (_supportLevel == CoreLibSupportLevel.Unknown)
+ {
+ // Check if the core library supports dynamic invoke.
+ _supportLevel = DelegateInfo.SupportsDynamicInvoke(key.Context) ?
+ CoreLibSupportLevel.Supported : CoreLibSupportLevel.Unsupported;
+ }
+
+ DelegateFeature supportedFeatures = _supportLevel == CoreLibSupportLevel.Supported ?
+ DelegateFeature.DynamicInvoke | DelegateFeature.ObjectArrayThunk : 0;
+
+
+ return new DelegateInfo(key, supportedFeatures);
}
}
diff --git a/src/Common/src/TypeSystem/IL/TypeSystemContext.DynamicInvoke.cs b/src/Common/src/TypeSystem/IL/TypeSystemContext.DynamicInvoke.cs
new file mode 100644
index 000000000..cdad3d9ef
--- /dev/null
+++ b/src/Common/src/TypeSystem/IL/TypeSystemContext.DynamicInvoke.cs
@@ -0,0 +1,31 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Internal.IL.Stubs;
+
+using Debug = System.Diagnostics.Debug;
+
+namespace Internal.TypeSystem
+{
+ partial class TypeSystemContext
+ {
+ private class DynamicInvokeThunkHashtable : LockFreeReaderHashtable<DynamicInvokeMethodSignature, DynamicInvokeMethodThunk>
+ {
+ protected override bool CompareKeyToValue(DynamicInvokeMethodSignature key, DynamicInvokeMethodThunk value) => key.Equals(value.TargetSignature);
+ protected override bool CompareValueToValue(DynamicInvokeMethodThunk value1, DynamicInvokeMethodThunk value2) => value1.TargetSignature.Equals(value2.TargetSignature) && value1.OwningType == value2.OwningType;
+ protected override int GetKeyHashCode(DynamicInvokeMethodSignature key) => key.GetHashCode();
+ protected override int GetValueHashCode(DynamicInvokeMethodThunk value) => value.TargetSignature.GetHashCode();
+ protected override DynamicInvokeMethodThunk CreateValueFromKey(DynamicInvokeMethodSignature key)
+ {
+ return new DynamicInvokeMethodThunk(key.Context.GeneratedAssembly.GetGlobalModuleType(), key);
+ }
+ }
+ DynamicInvokeThunkHashtable _dynamicInvokeThunks = new DynamicInvokeThunkHashtable();
+
+ public MethodDesc GetDynamicInvokeThunk(DynamicInvokeMethodSignature signature)
+ {
+ return _dynamicInvokeThunks.GetOrCreateValue(signature);
+ }
+ }
+}
diff --git a/src/Common/src/TypeSystem/IL/TypeSystemContext.GeneratedAssembly.Sorting.cs b/src/Common/src/TypeSystem/IL/TypeSystemContext.GeneratedAssembly.Sorting.cs
new file mode 100644
index 000000000..5c3301262
--- /dev/null
+++ b/src/Common/src/TypeSystem/IL/TypeSystemContext.GeneratedAssembly.Sorting.cs
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+namespace Internal.TypeSystem
+{
+ partial class TypeSystemContext
+ {
+ // Functionality related to determinstic ordering of types and members
+ partial class CompilerGeneratedType : MetadataType
+ {
+ protected internal override int ClassCode => -1036681447;
+
+ protected internal override int CompareToImpl(TypeDesc other, TypeSystemComparer comparer)
+ {
+ // Should be a singleton
+ throw new NotSupportedException();
+ }
+ }
+ }
+}
diff --git a/src/Common/src/TypeSystem/IL/TypeSystemContext.GeneratedAssembly.cs b/src/Common/src/TypeSystem/IL/TypeSystemContext.GeneratedAssembly.cs
new file mode 100644
index 000000000..5b3e59616
--- /dev/null
+++ b/src/Common/src/TypeSystem/IL/TypeSystemContext.GeneratedAssembly.cs
@@ -0,0 +1,252 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+
+using TypeHashingAlgorithms = Internal.NativeFormat.TypeHashingAlgorithms;
+using Interlocked = System.Threading.Interlocked;
+using AssemblyName = System.Reflection.AssemblyName;
+using Debug = System.Diagnostics.Debug;
+
+namespace Internal.TypeSystem
+{
+ partial class TypeSystemContext
+ {
+ private ModuleDesc _generatedAssembly;
+
+ public ModuleDesc GeneratedAssembly
+ {
+ get
+ {
+ if (_generatedAssembly == null)
+ {
+ Interlocked.CompareExchange(ref _generatedAssembly, new CompilerGeneratedAssembly(this), null);
+ }
+
+ return _generatedAssembly;
+ }
+ }
+
+ private class CompilerGeneratedAssembly : ModuleDesc, IAssemblyDesc
+ {
+ private MetadataType _globalModuleType;
+
+ public CompilerGeneratedAssembly(TypeSystemContext context)
+ : base(context)
+ {
+ _globalModuleType = new CompilerGeneratedType(this, "<Module>");
+ }
+
+ public override IEnumerable<MetadataType> GetAllTypes()
+ {
+ return Array.Empty<MetadataType>();
+ }
+
+ public override MetadataType GetGlobalModuleType()
+ {
+ return _globalModuleType;
+ }
+
+ public AssemblyName GetName()
+ {
+ return new AssemblyName("System.Private.CompilerGenerated");
+ }
+
+ public override MetadataType GetType(string nameSpace, string name, bool throwIfNotFound = true)
+ {
+ Debug.Fail("Resolving a TypeRef in the compiler generated assembly?");
+
+ if (throwIfNotFound)
+ ThrowHelper.ThrowTypeLoadException(nameSpace, name, this);
+
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// A pseudo-type that owns helper methods generated by the compiler.
+ /// This type should never be allocated (we should never see an EEType for it).
+ /// </summary>
+ internal sealed partial class CompilerGeneratedType : MetadataType
+ {
+ private int _hashcode;
+
+ public CompilerGeneratedType(ModuleDesc module, string name)
+ {
+ Module = module;
+ Name = name;
+ }
+
+ public override TypeSystemContext Context
+ {
+ get
+ {
+ return Module.Context;
+ }
+ }
+
+ public override string Name
+ {
+ get;
+ }
+
+ public override string Namespace
+ {
+ get
+ {
+ return "Internal.CompilerGenerated";
+ }
+ }
+
+ public override int GetHashCode()
+ {
+ if (_hashcode != 0)
+ return _hashcode;
+ return InitializeHashCode();
+ }
+
+ private int InitializeHashCode()
+ {
+ string ns = Namespace;
+ var hashCodeBuilder = new TypeHashingAlgorithms.HashCodeBuilder(ns);
+ if (ns.Length > 0)
+ hashCodeBuilder.Append(".");
+ hashCodeBuilder.Append(Name);
+ _hashcode = hashCodeBuilder.ToHashCode();
+
+ return _hashcode;
+ }
+
+ public override bool IsCanonicalSubtype(CanonicalFormKind policy)
+ {
+ Debug.Assert(!HasInstantiation, "Why is this generic?");
+ return false;
+ }
+
+ protected override TypeFlags ComputeTypeFlags(TypeFlags mask)
+ {
+ return TypeFlags.Class |
+ TypeFlags.HasGenericVarianceComputed |
+ TypeFlags.HasStaticConstructorComputed |
+ TypeFlags.HasFinalizerComputed |
+ TypeFlags.AttributeCacheComputed;
+ }
+
+ public override ClassLayoutMetadata GetClassLayout()
+ {
+ return new ClassLayoutMetadata
+ {
+ Offsets = null,
+ PackingSize = 0,
+ Size = 0,
+ };
+ }
+
+ public override bool HasCustomAttribute(string attributeNamespace, string attributeName)
+ {
+ return false;
+ }
+
+ public override IEnumerable<MetadataType> GetNestedTypes()
+ {
+ return Array.Empty<MetadataType>();
+ }
+
+ public override MetadataType GetNestedType(string name)
+ {
+ return null;
+ }
+
+ protected override MethodImplRecord[] ComputeVirtualMethodImplsForType()
+ {
+ return Array.Empty<MethodImplRecord>();
+ }
+
+ public override MethodImplRecord[] FindMethodsImplWithMatchingDeclName(string name)
+ {
+ return Array.Empty<MethodImplRecord>();
+ }
+
+ public override ModuleDesc Module
+ {
+ get;
+ }
+
+ public override PInvokeStringFormat PInvokeStringFormat
+ {
+ get
+ {
+ return PInvokeStringFormat.AutoClass;
+ }
+ }
+
+ public override bool IsExplicitLayout
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public override bool IsSequentialLayout
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public override bool IsBeforeFieldInit
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public override MetadataType MetadataBaseType
+ {
+ get
+ {
+ // Since this type should never be allocated and only serves the purpose of grouping things,
+ // it can act like a <Module> type and have no base type.
+ return null;
+ }
+ }
+
+ public override bool IsSealed
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ public override bool IsAbstract
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public override DefType ContainingType
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ public override DefType[] ExplicitlyImplementedInterfaces
+ {
+ get
+ {
+ return Array.Empty<DefType>();
+ }
+ }
+ }
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/Compiler/AnalysisBasedMetadataManager.cs b/src/ILCompiler.Compiler/src/Compiler/AnalysisBasedMetadataManager.cs
index 3a51c070d..64b2b33ad 100644
--- a/src/ILCompiler.Compiler/src/Compiler/AnalysisBasedMetadataManager.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/AnalysisBasedMetadataManager.cs
@@ -25,7 +25,6 @@ namespace ILCompiler
private readonly Dictionary<FieldDesc, MetadataCategory> _reflectableFields = new Dictionary<FieldDesc, MetadataCategory>();
public AnalysisBasedMetadataManager(
- ModuleDesc generatedAssembly,
CompilerTypeSystemContext typeSystemContext,
MetadataBlockingPolicy blockingPolicy,
string logFile,
@@ -34,7 +33,7 @@ namespace ILCompiler
IEnumerable<ReflectableEntity<TypeDesc>> reflectableTypes,
IEnumerable<ReflectableEntity<MethodDesc>> reflectableMethods,
IEnumerable<ReflectableEntity<FieldDesc>> reflectableFields)
- : base(generatedAssembly, typeSystemContext, blockingPolicy, logFile, stackTracePolicy)
+ : base(typeSystemContext, blockingPolicy, logFile, stackTracePolicy)
{
_modulesWithMetadata = new List<ModuleDesc>(modulesWithMetadata);
diff --git a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs
index d686a0d7b..634a1c097 100644
--- a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs
@@ -58,7 +58,7 @@ namespace ILCompiler
foreach (var rootProvider in compilationRoots)
rootProvider.AddCompilationRoots(rootingService);
- MetadataType globalModuleGeneratedType = nodeFactory.CompilationModuleGroup.GeneratedAssembly.GetGlobalModuleType();
+ MetadataType globalModuleGeneratedType = nodeFactory.TypeSystemContext.GeneratedAssembly.GetGlobalModuleType();
_typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(globalModuleGeneratedType);
_assemblyGetExecutingAssemblyMethodThunks = new AssemblyGetExecutingAssemblyMethodThunkCache(globalModuleGeneratedType);
_methodBaseGetCurrentMethodThunks = new MethodBaseGetCurrentMethodThunkCache();
diff --git a/src/ILCompiler.Compiler/src/Compiler/CompilationModuleGroup.cs b/src/ILCompiler.Compiler/src/Compiler/CompilationModuleGroup.cs
index 8fa73ff20..92354badb 100644
--- a/src/ILCompiler.Compiler/src/Compiler/CompilationModuleGroup.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/CompilationModuleGroup.cs
@@ -22,17 +22,6 @@ namespace ILCompiler
public abstract class CompilationModuleGroup
{
/// <summary>
- /// Gets the synthetic assembly that holds types generated by the compiler as part of the compilation process.
- /// Types and members that declare this module as their owning module are always generated.
- /// </summary>
- public ModuleDesc GeneratedAssembly { get; }
-
- public CompilationModuleGroup(TypeSystemContext context)
- {
- GeneratedAssembly = new CompilerGeneratedAssembly(context);
- }
-
- /// <summary>
/// If true, "type" is in the set of input assemblies being compiled
/// </summary>
public abstract bool ContainsType(TypeDesc type);
@@ -94,41 +83,5 @@ namespace ILCompiler
/// accessed through the target platform's import mechanism (ie, Import Address Table on Windows)
/// </summary>
public abstract bool CanHaveReferenceThroughImportTable { get; }
-
- private class CompilerGeneratedAssembly : ModuleDesc, IAssemblyDesc
- {
- private MetadataType _globalModuleType;
-
- public CompilerGeneratedAssembly(TypeSystemContext context)
- : base(context)
- {
- _globalModuleType = new CompilerGeneratedType(this, "<Module>");
- }
-
- public override IEnumerable<MetadataType> GetAllTypes()
- {
- return Array.Empty<MetadataType>();
- }
-
- public override MetadataType GetGlobalModuleType()
- {
- return _globalModuleType;
- }
-
- public AssemblyName GetName()
- {
- return new AssemblyName("System.Private.CompilerGenerated");
- }
-
- public override MetadataType GetType(string nameSpace, string name, bool throwIfNotFound = true)
- {
- Debug.Fail("Resolving a TypeRef in the compiler generated assembly?");
-
- if (throwIfNotFound)
- ThrowHelper.ThrowTypeLoadException(nameSpace, name, this);
-
- return null;
- }
- }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.Sorting.cs b/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.Sorting.cs
deleted file mode 100644
index 99457b98f..000000000
--- a/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.Sorting.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-
-using Internal.TypeSystem;
-
-namespace ILCompiler
-{
- // Functionality related to determinstic ordering of types and members
- internal sealed partial class CompilerGeneratedType : MetadataType
- {
- protected override int ClassCode => -1036681447;
-
- protected override int CompareToImpl(TypeDesc other, TypeSystemComparer comparer)
- {
- // Should be a singleton
- throw new NotSupportedException();
- }
- }
-}
diff --git a/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.cs b/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.cs
deleted file mode 100644
index e562d9500..000000000
--- a/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.cs
+++ /dev/null
@@ -1,198 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Collections.Generic;
-
-using Internal.TypeSystem;
-
-using Debug = System.Diagnostics.Debug;
-using TypeHashingAlgorithms = Internal.NativeFormat.TypeHashingAlgorithms;
-
-namespace ILCompiler
-{
- /// <summary>
- /// A pseudo-type that owns helper methods generated by the compiler.
- /// This type should never be allocated (we should never see an EEType for it).
- /// </summary>
- internal sealed partial class CompilerGeneratedType : MetadataType
- {
- private int _hashcode;
-
- public CompilerGeneratedType(ModuleDesc module, string name)
- {
- Module = module;
- Name = name;
- }
-
- public override TypeSystemContext Context
- {
- get
- {
- return Module.Context;
- }
- }
-
- public override string Name
- {
- get;
- }
-
- public override string Namespace
- {
- get
- {
- return "Internal.CompilerGenerated";
- }
- }
-
- public override int GetHashCode()
- {
- if (_hashcode != 0)
- return _hashcode;
- return InitializeHashCode();
- }
-
- private int InitializeHashCode()
- {
- string ns = Namespace;
- var hashCodeBuilder = new TypeHashingAlgorithms.HashCodeBuilder(ns);
- if (ns.Length > 0)
- hashCodeBuilder.Append(".");
- hashCodeBuilder.Append(Name);
- _hashcode = hashCodeBuilder.ToHashCode();
-
- return _hashcode;
- }
-
- public override bool IsCanonicalSubtype(CanonicalFormKind policy)
- {
- Debug.Assert(!HasInstantiation, "Why is this generic?");
- return false;
- }
-
- protected override TypeFlags ComputeTypeFlags(TypeFlags mask)
- {
- return TypeFlags.Class |
- TypeFlags.HasGenericVarianceComputed |
- TypeFlags.HasStaticConstructorComputed |
- TypeFlags.HasFinalizerComputed |
- TypeFlags.AttributeCacheComputed;
- }
-
- public override ClassLayoutMetadata GetClassLayout()
- {
- return new ClassLayoutMetadata
- {
- Offsets = null,
- PackingSize = 0,
- Size = 0,
- };
- }
-
- public override bool HasCustomAttribute(string attributeNamespace, string attributeName)
- {
- return false;
- }
-
- public override IEnumerable<MetadataType> GetNestedTypes()
- {
- return Array.Empty<MetadataType>();
- }
-
- public override MetadataType GetNestedType(string name)
- {
- return null;
- }
-
- protected override MethodImplRecord[] ComputeVirtualMethodImplsForType()
- {
- return Array.Empty<MethodImplRecord>();
- }
-
- public override MethodImplRecord[] FindMethodsImplWithMatchingDeclName(string name)
- {
- return Array.Empty<MethodImplRecord>();
- }
-
- public override ModuleDesc Module
- {
- get;
- }
-
- public override PInvokeStringFormat PInvokeStringFormat
- {
- get
- {
- return PInvokeStringFormat.AutoClass;
- }
- }
-
- public override bool IsExplicitLayout
- {
- get
- {
- return false;
- }
- }
-
- public override bool IsSequentialLayout
- {
- get
- {
- return false;
- }
- }
-
- public override bool IsBeforeFieldInit
- {
- get
- {
- return false;
- }
- }
-
- public override MetadataType MetadataBaseType
- {
- get
- {
- // Since this type should never be allocated and only serves the purpose of grouping things,
- // it can act like a <Module> type and have no base type.
- return null;
- }
- }
-
- public override bool IsSealed
- {
- get
- {
- return true;
- }
- }
-
- public override bool IsAbstract
- {
- get
- {
- return false;
- }
- }
-
- public override DefType ContainingType
- {
- get
- {
- return null;
- }
- }
-
- public override DefType[] ExplicitlyImplementedInterfaces
- {
- get
- {
- return Array.Empty<DefType>();
- }
- }
- }
-}
diff --git a/src/ILCompiler.Compiler/src/Compiler/CoreRTNameMangler.cs b/src/ILCompiler.Compiler/src/Compiler/CoreRTNameMangler.cs
index 86cac8dc0..5c292f87f 100644
--- a/src/ILCompiler.Compiler/src/Compiler/CoreRTNameMangler.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/CoreRTNameMangler.cs
@@ -331,7 +331,13 @@ namespace ILCompiler
}
else
{
+ // This is a type definition. Since we didn't fall in the `is EcmaType` case above,
+ // it's likely a compiler-generated type.
mangledName = SanitizeName(((DefType)type).GetFullName(), true);
+
+ // Always generate a fully qualified name
+ if (_mangleForCplusPlus)
+ mangledName = "::" + mangledName;
}
break;
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs
index 6f061c02f..3069c5f53 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ILScanNodeFactory.cs
@@ -63,7 +63,7 @@ namespace ILCompiler.DependencyAnalysis
// 'this' and also provides an instantiation argument (we do a calling convention conversion).
// We don't do this for generic instance methods though because they don't use the EEType
// for the generic context anyway.
- return new ScannedMethodNode(TypeSystemContext.GetSpecialUnboxingThunk(method, CompilationModuleGroup.GeneratedAssembly));
+ return new ScannedMethodNode(TypeSystemContext.GetSpecialUnboxingThunk(method, TypeSystemContext.GeneratedAssembly));
}
else
{
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs
index cce88f810..1db0a5948 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RyuJitNodeFactory.cs
@@ -60,7 +60,7 @@ namespace ILCompiler.DependencyAnalysis
// 'this' and also provides an instantiation argument (we do a calling convention conversion).
// We don't do this for generic instance methods though because they don't use the EEType
// for the generic context anyway.
- return new MethodCodeNode(TypeSystemContext.GetSpecialUnboxingThunk(method, CompilationModuleGroup.GeneratedAssembly));
+ return new MethodCodeNode(TypeSystemContext.GetSpecialUnboxingThunk(method, TypeSystemContext.GeneratedAssembly));
}
else
{
diff --git a/src/ILCompiler.Compiler/src/Compiler/GeneratingMetadataManager.cs b/src/ILCompiler.Compiler/src/Compiler/GeneratingMetadataManager.cs
index b01a4bb5f..c4216775c 100644
--- a/src/ILCompiler.Compiler/src/Compiler/GeneratingMetadataManager.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/GeneratingMetadataManager.cs
@@ -9,7 +9,6 @@ using System.Text;
using Internal.IL.Stubs;
using Internal.TypeSystem;
-using Internal.TypeSystem.Ecma;
using Internal.Metadata.NativeFormat.Writer;
using ILCompiler.Metadata;
@@ -26,20 +25,14 @@ namespace ILCompiler
{
protected readonly string _metadataLogFile;
protected readonly StackTraceEmissionPolicy _stackTraceEmissionPolicy;
- private readonly Dictionary<DynamicInvokeMethodSignature, MethodDesc> _dynamicInvokeThunks;
private readonly ModuleDesc _generatedAssembly;
- public GeneratingMetadataManager(ModuleDesc generatedAssembly, CompilerTypeSystemContext typeSystemContext, MetadataBlockingPolicy blockingPolicy, string logFile, StackTraceEmissionPolicy stackTracePolicy)
+ public GeneratingMetadataManager(CompilerTypeSystemContext typeSystemContext, MetadataBlockingPolicy blockingPolicy, string logFile, StackTraceEmissionPolicy stackTracePolicy)
: base(typeSystemContext, blockingPolicy)
{
_metadataLogFile = logFile;
_stackTraceEmissionPolicy = stackTracePolicy;
- _generatedAssembly = generatedAssembly;
-
- if (DynamicInvokeMethodThunk.SupportsThunks(typeSystemContext))
- {
- _dynamicInvokeThunks = new Dictionary<DynamicInvokeMethodSignature, MethodDesc>();
- }
+ _generatedAssembly = typeSystemContext.GeneratedAssembly;
}
public sealed override bool WillUseMetadataTokenToReferenceMethod(MethodDesc method)
@@ -182,9 +175,6 @@ namespace ILCompiler
{
Debug.Assert(IsReflectionInvokable(method));
- if (_dynamicInvokeThunks == null)
- return false;
-
// Place an upper limit on how many parameters a method can have to still get a static stub.
// From the past experience, methods taking 8000+ parameters get a stub that can hit various limitations
// in the codegen. On Project N, we were limited to 256 parameters because of MDIL limitations.
@@ -199,17 +189,9 @@ namespace ILCompiler
/// </summary>
public sealed override MethodDesc GetCanonicalReflectionInvokeStub(MethodDesc method)
{
- TypeSystemContext context = method.Context;
- var sig = method.Signature;
-
// Get a generic method that can be used to invoke method with this shape.
- MethodDesc thunk;
- var lookupSig = new DynamicInvokeMethodSignature(sig);
- if (!_dynamicInvokeThunks.TryGetValue(lookupSig, out thunk))
- {
- thunk = new DynamicInvokeMethodThunk(_generatedAssembly.GetGlobalModuleType(), lookupSig);
- _dynamicInvokeThunks.Add(lookupSig, thunk);
- }
+ var lookupSig = new DynamicInvokeMethodSignature(method.Signature);
+ MethodDesc thunk = _typeSystemContext.GetDynamicInvokeThunk(lookupSig);
return InstantiateCanonicalDynamicInvokeMethodForMethod(thunk, method);
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/ILScannerBuilder.cs b/src/ILCompiler.Compiler/src/Compiler/ILScannerBuilder.cs
index 340c5603a..2202f93d6 100644
--- a/src/ILCompiler.Compiler/src/Compiler/ILScannerBuilder.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/ILScannerBuilder.cs
@@ -53,7 +53,7 @@ namespace ILCompiler
public IILScanner ToILScanner()
{
- var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_compilationGroup.GeneratedAssembly));
+ var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_context.GeneratedAssembly));
var nodeFactory = new ILScanNodeFactory(_context, _compilationGroup, _metadataManager, interopStubManager, _nameMangler);
DependencyAnalyzerBase<NodeFactory> graph = _dependencyTrackingLevel.CreateDependencyGraph(nodeFactory);
diff --git a/src/ILCompiler.Compiler/src/Compiler/MetadataManager.cs b/src/ILCompiler.Compiler/src/Compiler/MetadataManager.cs
index 07e8fd4d8..d7f5dc695 100644
--- a/src/ILCompiler.Compiler/src/Compiler/MetadataManager.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/MetadataManager.cs
@@ -218,53 +218,10 @@ namespace ILCompiler
/// </summary>
public virtual bool IsReflectionInvokable(MethodDesc method)
{
- return IsMethodSignatureSupportedInReflectionInvoke(method)
+ return Internal.IL.Stubs.DynamicInvokeMethodThunk.SupportsSignature(method.Signature)
&& IsMethodSupportedInReflectionInvoke(method);
}
- protected bool IsMethodSignatureSupportedInReflectionInvoke(MethodDesc method)
- {
- var signature = method.Signature;
-
- for (int i = 0; i < signature.Length; i++)
- if (signature[i].IsByRef && ((ByRefType)signature[i]).ParameterType.IsPointer)
- return false;
-
- // ----------------------------------------------------------------
- // TODO: function pointer types are odd: https://github.com/dotnet/corert/issues/1929
- // ----------------------------------------------------------------
-
- if (signature.ReturnType.IsFunctionPointer)
- return false;
-
- for (int i = 0; i < signature.Length; i++)
- if (signature[i].IsFunctionPointer)
- return false;
-
- // ----------------------------------------------------------------
- // Methods with ByRef returns can't be reflection invoked
- // ----------------------------------------------------------------
-
- if (signature.ReturnType.IsByRef)
- return false;
-
- // ----------------------------------------------------------------
- // Methods that return ByRef-like types or take them by reference can't be reflection invoked
- // ----------------------------------------------------------------
-
- if (signature.ReturnType.IsByRefLike)
- return false;
-
- for (int i = 0; i < signature.Length; i++)
- {
- ByRefType paramType = signature[i] as ByRefType;
- if (paramType != null && paramType.ParameterType.IsByRefLike)
- return false;
- }
-
- return true;
- }
-
protected bool IsMethodSupportedInReflectionInvoke(MethodDesc method)
{
TypeDesc owningType = method.OwningType;
@@ -463,72 +420,7 @@ namespace ILCompiler
// Instantiate the generic thunk over the parameters and the return type of the target method
//
- ParameterMetadata[] paramMetadata = null;
- TypeDesc[] instantiation = new TypeDesc[sig.ReturnType.IsVoid ? sig.Length : sig.Length + 1];
- Debug.Assert(thunk.Instantiation.Length == instantiation.Length);
- for (int i = 0; i < sig.Length; i++)
- {
- TypeDesc parameterType = sig[i];
- if (parameterType.IsByRef)
- {
- // strip ByRefType off the parameter (the method already has ByRef in the signature)
- parameterType = ((ByRefType)parameterType).ParameterType;
-
- Debug.Assert(!parameterType.IsPointer); // TODO: support for methods returning pointer types - https://github.com/dotnet/corert/issues/2113
- }
- else if (parameterType.IsPointer)
- {
- // Strip off all the pointers. Pointers are not valid instantiation arguments and the thunk compensates for that
- // by being specialized for the specific pointer depth.
- while (parameterType.IsPointer)
- parameterType = ((PointerType)parameterType).ParameterType;
- }
- else if (parameterType.IsEnum)
- {
- // If the invoke method takes an enum as an input parameter and there is no default value for
- // that paramter, we don't need to specialize on the exact enum type (we only need to specialize
- // on the underlying integral type of the enum.)
- if (paramMetadata == null)
- paramMetadata = method.GetParameterMetadata();
-
- bool hasDefaultValue = false;
- foreach (var p in paramMetadata)
- {
- // Parameter metadata indexes are 1-based (0 is reserved for return "parameter")
- if (p.Index == (i + 1) && p.HasDefault)
- {
- hasDefaultValue = true;
- break;
- }
- }
-
- if (!hasDefaultValue)
- parameterType = parameterType.UnderlyingType;
- }
-
- instantiation[i] = parameterType;
- }
-
- if (!sig.ReturnType.IsVoid)
- {
- TypeDesc returnType = sig.ReturnType;
- Debug.Assert(!returnType.IsByRef);
-
- // If the invoke method return an object reference, we don't need to specialize on the
- // exact type of the object reference, as the behavior is not different.
- if ((returnType.IsDefType && !returnType.IsValueType) || returnType.IsArray)
- {
- returnType = context.GetWellKnownType(WellKnownType.Object);
- }
-
- // Strip off all the pointers. Pointers are not valid instantiation arguments and the thunk compensates for that
- // by being specialized for the specific pointer depth.
- while (returnType.IsPointer)
- returnType = ((PointerType)returnType).ParameterType;
-
- instantiation[sig.Length] = returnType;
- }
-
+ TypeDesc[] instantiation = Internal.IL.Stubs.DynamicInvokeMethodThunk.GetThunkInstantiationForMethod(method);
Debug.Assert(thunk.Instantiation.Length == instantiation.Length);
// Check if at least one of the instantiation arguments is a universal canonical type, and if so, we
diff --git a/src/ILCompiler.Compiler/src/Compiler/MultiFileCompilationModuleGroup.cs b/src/ILCompiler.Compiler/src/Compiler/MultiFileCompilationModuleGroup.cs
index 9541e4285..5afac3563 100644
--- a/src/ILCompiler.Compiler/src/Compiler/MultiFileCompilationModuleGroup.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/MultiFileCompilationModuleGroup.cs
@@ -17,12 +17,11 @@ namespace ILCompiler
private HashSet<ModuleDesc> _compilationModuleSet;
public MultiFileCompilationModuleGroup(TypeSystemContext context, IEnumerable<ModuleDesc> compilationModuleSet)
- : base(context)
{
_compilationModuleSet = new HashSet<ModuleDesc>(compilationModuleSet);
// The fake assembly that holds compiler generated types is part of the compilation.
- _compilationModuleSet.Add(this.GeneratedAssembly);
+ _compilationModuleSet.Add(context.GeneratedAssembly);
}
public sealed override bool ContainsType(TypeDesc type)
diff --git a/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs b/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs
index 773560798..f02559b4e 100644
--- a/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/RyuJitCompilationBuilder.cs
@@ -86,7 +86,7 @@ namespace ILCompiler
jitFlagBuilder.Add(CorJitFlag.CORJIT_FLAG_FEATURE_SIMD);
}
- var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_compilationGroup.GeneratedAssembly));
+ var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_context.GeneratedAssembly));
var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider);
var jitConfig = new JitConfigProvider(jitFlagBuilder.ToArray(), _ryujitOptions);
diff --git a/src/ILCompiler.Compiler/src/Compiler/SingleFileCompilationModuleGroup.cs b/src/ILCompiler.Compiler/src/Compiler/SingleFileCompilationModuleGroup.cs
index ba4c23d79..a305ad026 100644
--- a/src/ILCompiler.Compiler/src/Compiler/SingleFileCompilationModuleGroup.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/SingleFileCompilationModuleGroup.cs
@@ -10,11 +10,6 @@ namespace ILCompiler
{
public class SingleFileCompilationModuleGroup : CompilationModuleGroup
{
- public SingleFileCompilationModuleGroup(TypeSystemContext context)
- : base(context)
- {
- }
-
public override bool ContainsType(TypeDesc type)
{
return true;
diff --git a/src/ILCompiler.Compiler/src/Compiler/SingleMethodCompilationModuleGroup.cs b/src/ILCompiler.Compiler/src/Compiler/SingleMethodCompilationModuleGroup.cs
index 61f220e09..9f734c1e0 100644
--- a/src/ILCompiler.Compiler/src/Compiler/SingleMethodCompilationModuleGroup.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/SingleMethodCompilationModuleGroup.cs
@@ -17,7 +17,6 @@ namespace ILCompiler
private MethodDesc _method;
public SingleMethodCompilationModuleGroup(MethodDesc method)
- : base(method.Context)
{
_method = method;
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs b/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs
index b5845786c..a9f638d7b 100644
--- a/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs
@@ -36,7 +36,7 @@ namespace ILCompiler
MetadataBlockingPolicy blockingPolicy,
string logFile,
StackTraceEmissionPolicy stackTracePolicy)
- : base(group.GeneratedAssembly, typeSystemContext, blockingPolicy, logFile, stackTracePolicy)
+ : base(typeSystemContext, blockingPolicy, logFile, stackTracePolicy)
{
// We use this to mark places that would behave differently if we tracked exact fields used.
_hasPreciseFieldUsageInformation = false;
@@ -353,7 +353,7 @@ namespace ILCompiler
}
}
- return new AnalysisBasedMetadataManager(_compilationModuleGroup.GeneratedAssembly,
+ return new AnalysisBasedMetadataManager(
_typeSystemContext, _blockingPolicy, _metadataLogFile, _stackTraceEmissionPolicy,
_modulesWithMetadata, reflectableTypes.ToEnumerable(), reflectableMethods.ToEnumerable(),
reflectableFields.ToEnumerable());
diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
index b799fb700..9744fa933 100644
--- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
+++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
@@ -58,9 +58,6 @@
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\ComparerIntrinsics.cs">
<Link>IL\Stubs\ComparerIntrinsics.cs</Link>
</Compile>
- <Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DynamicInvokeMethodThunk.Sorting.cs">
- <Link>IL\Stubs\DynamicInvokeMethodThunk.Sorting.cs</Link>
- </Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\GetCanonTypeIntrinsic.cs">
<Link>IL\Stubs\GetCanonTypeIntrinsic.cs</Link>
</Compile>
@@ -73,9 +70,6 @@
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DelegateMethodILEmitter.cs">
<Link>IL\Stubs\DelegateMethodILEmitter.cs</Link>
</Compile>
- <Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DynamicInvokeMethodThunk.cs">
- <Link>IL\Stubs\DynamicInvokeMethodThunk.cs</Link>
- </Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\EETypePtrOfIntrinsic.cs">
<Link>IL\Stubs\EETypePtrOfIntrinsic.cs</Link>
</Compile>
@@ -100,8 +94,6 @@
<Compile Include="Compiler\AnalysisBasedMetadataManager.cs" />
<Compile Include="Compiler\BlockedInternalsBlockingPolicy.cs" />
<Compile Include="Compiler\CodeGenerationFailedException.cs" />
- <Compile Include="Compiler\CompilerGeneratedType.cs" />
- <Compile Include="Compiler\CompilerGeneratedType.Sorting.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.BoxedTypes.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.Mangling.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.Sorting.cs" />
diff --git a/src/ILCompiler.Compiler/tests/DependencyGraphTests.cs b/src/ILCompiler.Compiler/tests/DependencyGraphTests.cs
index c4ace726b..a0a60efda 100644
--- a/src/ILCompiler.Compiler/tests/DependencyGraphTests.cs
+++ b/src/ILCompiler.Compiler/tests/DependencyGraphTests.cs
@@ -64,7 +64,7 @@ namespace ILCompiler.Compiler.Tests
//
var context = (CompilerTypeSystemContext)method.Context;
- CompilationModuleGroup compilationGroup = new SingleFileCompilationModuleGroup(context);
+ CompilationModuleGroup compilationGroup = new SingleFileCompilationModuleGroup();
CompilationBuilder builder = new RyuJitCompilationBuilder(context, compilationGroup);
IILScanner scanner = builder.GetILScannerBuilder()
diff --git a/src/ILCompiler.Compiler/tests/DevirtualizationTests.cs b/src/ILCompiler.Compiler/tests/DevirtualizationTests.cs
index 6b320fb17..0ebda0cbc 100644
--- a/src/ILCompiler.Compiler/tests/DevirtualizationTests.cs
+++ b/src/ILCompiler.Compiler/tests/DevirtualizationTests.cs
@@ -32,7 +32,7 @@ namespace ILCompiler.Compiler.Tests
private DevirtualizationManager GetDevirtualizationManagerFromScan(MethodDesc method)
{
- CompilationModuleGroup compilationGroup = new SingleFileCompilationModuleGroup(_context);
+ CompilationModuleGroup compilationGroup = new SingleFileCompilationModuleGroup();
CompilationBuilder builder = new RyuJitCompilationBuilder(_context, compilationGroup);
IILScanner scanner = builder.GetILScannerBuilder()
diff --git a/src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilationBuilder.cs b/src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilationBuilder.cs
index 8b4fe6360..0068f2da8 100644
--- a/src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilationBuilder.cs
+++ b/src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilationBuilder.cs
@@ -31,7 +31,7 @@ namespace ILCompiler
public override ICompilation ToCompilation()
{
- var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_compilationGroup.GeneratedAssembly));
+ var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_context.GeneratedAssembly));
CppCodegenNodeFactory factory = new CppCodegenNodeFactory(_context, _compilationGroup, _metadataManager, interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider);
DependencyAnalyzerBase<NodeFactory> graph = CreateDependencyGraph(factory);
diff --git a/src/ILCompiler.TypeSystem/src/ILCompiler.TypeSystem.csproj b/src/ILCompiler.TypeSystem/src/ILCompiler.TypeSystem.csproj
index 162c941a7..aab6301a4 100644
--- a/src/ILCompiler.TypeSystem/src/ILCompiler.TypeSystem.csproj
+++ b/src/ILCompiler.TypeSystem/src/ILCompiler.TypeSystem.csproj
@@ -364,6 +364,12 @@
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DelegateThunks.Sorting.cs">
<Link>IL\Stubs\DelegateThunks.Sorting.cs</Link>
</Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DynamicInvokeMethodThunk.cs">
+ <Link>IL\Stubs\DynamicInvokeMethodThunk.cs</Link>
+ </Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DynamicInvokeMethodThunk.Sorting.cs">
+ <Link>IL\Stubs\DynamicInvokeMethodThunk.Sorting.cs</Link>
+ </Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\EnumThunks.cs">
<Link>IL\Stubs\EnumThunks.cs</Link>
</Compile>
@@ -391,6 +397,15 @@
<Compile Include="..\..\Common\src\TypeSystem\IL\TypeSystemContext.DelegateInfo.cs">
<Link>IL\TypeSystemContext.DelegateInfo.cs</Link>
</Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\IL\TypeSystemContext.DynamicInvoke.cs">
+ <Link>IL\TypeSystemContext.DynamicInvoke.cs</Link>
+ </Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\IL\TypeSystemContext.GeneratedAssembly.cs">
+ <Link>IL\TypeSystemContext.GeneratedAssembly.cs</Link>
+ </Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\IL\TypeSystemContext.GeneratedAssembly.Sorting.cs">
+ <Link>IL\TypeSystemContext.GeneratedAssembly.Sorting.cs</Link>
+ </Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\EcmaMethodIL.cs">
<Link>IL\EcmaMethodIL.cs</Link>
</Compile>
diff --git a/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyCodegenNodeFactory.cs b/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyCodegenNodeFactory.cs
index a43a1e572..2c09fc8fd 100644
--- a/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyCodegenNodeFactory.cs
+++ b/src/ILCompiler.WebAssembly/src/Compiler/DependencyAnalysis/WebAssemblyCodegenNodeFactory.cs
@@ -51,7 +51,7 @@ namespace ILCompiler.DependencyAnalysis
protected override IMethodNode CreateUnboxingStubNode(MethodDesc method)
{
- return new WebAssemblyMethodCodeNode(TypeSystemContext.GetUnboxingThunk(method, CompilationModuleGroup.GeneratedAssembly));
+ return new WebAssemblyMethodCodeNode(TypeSystemContext.GetUnboxingThunk(method, TypeSystemContext.GeneratedAssembly));
}
protected override ISymbolNode CreateReadyToRunHelperNode(ReadyToRunHelperKey helperCall)
diff --git a/src/ILCompiler.WebAssembly/src/Compiler/WebAssemblyCodegenCompilationBuilder.cs b/src/ILCompiler.WebAssembly/src/Compiler/WebAssemblyCodegenCompilationBuilder.cs
index 48bfaa15b..e6f82061e 100644
--- a/src/ILCompiler.WebAssembly/src/Compiler/WebAssemblyCodegenCompilationBuilder.cs
+++ b/src/ILCompiler.WebAssembly/src/Compiler/WebAssemblyCodegenCompilationBuilder.cs
@@ -31,7 +31,7 @@ namespace ILCompiler
public override ICompilation ToCompilation()
{
- var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_compilationGroup.GeneratedAssembly));
+ var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_context.GeneratedAssembly));
WebAssemblyCodegenNodeFactory factory = new WebAssemblyCodegenNodeFactory(_context, _compilationGroup, _metadataManager, interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider);
DependencyAnalyzerBase<NodeFactory> graph = CreateDependencyGraph(factory);
diff --git a/src/ILCompiler/src/Program.cs b/src/ILCompiler/src/Program.cs
index 58d549ec0..03ae9284d 100644
--- a/src/ILCompiler/src/Program.cs
+++ b/src/ILCompiler/src/Program.cs
@@ -17,6 +17,8 @@ namespace ILCompiler
{
internal class Program
{
+ private const string DefaultSystemModule = "System.Private.CoreLib";
+
private Dictionary<string, string> _inputFilePaths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private Dictionary<string, string> _referenceFilePaths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
@@ -37,7 +39,7 @@ namespace ILCompiler
private OptimizationMode _optimizationMode;
private bool _enableDebugInfo;
private string _ilDump;
- private string _systemModuleName = "System.Private.CoreLib";
+ private string _systemModuleName = DefaultSystemModule;
private bool _multiFile;
private bool _nativeLib;
private string _exportsFile;
@@ -341,7 +343,7 @@ namespace ILCompiler
throw new Exception("No entrypoint module");
compilationRoots.Add(new ExportedMethodsRootProvider((EcmaModule)typeSystemContext.SystemModule));
- compilationGroup = new SingleFileCompilationModuleGroup(typeSystemContext);
+ compilationGroup = new SingleFileCompilationModuleGroup();
}
if (_nativeLib)
@@ -349,7 +351,7 @@ namespace ILCompiler
// Set owning module of generated native library startup method to compiler generated module,
// to ensure the startup method is included in the object file during multimodule mode build
LibraryInitializers libraryInitializers = new LibraryInitializers(typeSystemContext, _isCppCodegen);
- compilationRoots.Add(new NativeLibraryInitializerRootProvider(compilationGroup.GeneratedAssembly, libraryInitializers.LibraryInitializerMethods));
+ compilationRoots.Add(new NativeLibraryInitializerRootProvider(typeSystemContext.GeneratedAssembly, libraryInitializers.LibraryInitializerMethods));
}
if (_rdXmlFilePaths.Count > 0)
@@ -392,7 +394,9 @@ namespace ILCompiler
useScanner &= !_noScanner;
- MetadataManager compilationMetadataManager = _isWasmCodegen ? (MetadataManager)new EmptyMetadataManager(typeSystemContext) : metadataManager;
+ bool supportsReflection = !_isWasmCodegen && !_isCppCodegen && _systemModuleName == DefaultSystemModule;
+
+ MetadataManager compilationMetadataManager = supportsReflection ? metadataManager : (MetadataManager)new EmptyMetadataManager(typeSystemContext);
ILScanResults scanResults = null;
if (useScanner)
{
diff --git a/src/System.Private.CoreLib/src/System/Delegate.cs b/src/System.Private.CoreLib/src/System/Delegate.cs
index e4746b1ab..9f8808fdd 100644
--- a/src/System.Private.CoreLib/src/System/Delegate.cs
+++ b/src/System.Private.CoreLib/src/System/Delegate.cs
@@ -373,7 +373,22 @@ namespace System
else
{
IntPtr invokeThunk = this.GetThunk(DelegateInvokeThunk);
- object result = System.InvokeUtils.CallDynamicInvokeMethod(this.m_firstParameter, this.m_functionPointer, this, invokeThunk, IntPtr.Zero, this, args, binderBundle: null, wrapInTargetInvocationException: true);
+#if PROJECTN
+ object result = InvokeUtils.CallDynamicInvokeMethod(this.m_firstParameter, this.m_functionPointer, this, invokeThunk, IntPtr.Zero, this, args, binderBundle: null, wrapInTargetInvocationException: true);
+#else
+ IntPtr genericDictionary = IntPtr.Zero;
+ if (FunctionPointerOps.IsGenericMethodPointer(invokeThunk))
+ {
+ unsafe
+ {
+ GenericMethodDescriptor* descriptor = FunctionPointerOps.ConvertToGenericDescriptor(invokeThunk);
+ genericDictionary = descriptor->InstantiationArgument;
+ invokeThunk = descriptor->MethodFunctionPointer;
+ }
+ }
+
+ object result = InvokeUtils.CallDynamicInvokeMethod(this.m_firstParameter, this.m_functionPointer, null, invokeThunk, genericDictionary, this, args, binderBundle: null, wrapInTargetInvocationException: true, invokeMethodHelperIsThisCall: false);
+#endif
DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
return result;
}
diff --git a/src/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj b/src/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj
index 09fdd65da..11afdf633 100644
--- a/src/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj
+++ b/src/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj
@@ -75,6 +75,7 @@
<Compile Include="..\..\Common\src\TypeSystem\RuntimeDetermined\TypeSystemContext.RuntimeDetermined.cs" />
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\ILEmitter.cs" />
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DelegateThunks.cs" />
+ <Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DynamicInvokeMethodThunk.cs" />
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\EnumThunks.cs" />
<Compile Include="..\..\Common\src\TypeSystem\IL\HelperExtensions.cs" />
<Compile Include="..\..\Common\src\TypeSystem\IL\ILDisassembler.cs" />
@@ -87,7 +88,9 @@
<Compile Include="..\..\Common\src\TypeSystem\IL\MethodILDebugView.cs" />
<Compile Include="..\..\Common\src\TypeSystem\IL\DelegateInfo.cs" />
<Compile Include="..\..\Common\src\TypeSystem\IL\TypeSystemContext.DelegateInfo.cs" />
+ <Compile Include="..\..\Common\src\TypeSystem\IL\TypeSystemContext.DynamicInvoke.cs" />
<Compile Include="..\..\Common\src\TypeSystem\IL\TypeSystemContext.EnumMethods.cs" />
+ <Compile Include="..\..\Common\src\TypeSystem\IL\TypeSystemContext.GeneratedAssembly.cs" />
<Compile Include="Internal\TypeSystem\ILStubMethod.Runtime.cs" />
<Compile Include="Internal\TypeSystem\MethodForRuntimeDeterminedType.Runtime.cs" />
<Compile Include="Internal\Runtime\TypeLoader\JitSupport.MethodEntrypointStubs.cs" />