- Fix issue where method token referred to derived type but method was actually defined on base type
- Previously the methods did not carry enough state to determine when to emit the owner type of the method, and which exact type was the owning type. The new logic computes it from the token in the presence of a proper instantiation context, which allows for correct operation.
- Fix issue where constrained dispatch on a method of a valuetype would not put in the correct owner type
- Issue fixed by determining if the token resolves to a method on the same type as the eventual target method, or if it needs to have a specific owning type specified
In general these issues where both caused by confusion around exactly the correct owning type, and it turned out that computation could not be computed within the signature emitter code, but instead needed to be computed in the JIT at point of use. Fortunately, we had a structure `MethodWithToken` that is used in these (and only these situations). Finally, I also made a pass through the emitter and related logic to remove various band-aids that had built up over the last few years to make all the tests and applications pass. I believe that the new logic should be correct in the general case.
Bonus tweak... Use parallelism when compiling the framework composite images with crossgen2, and fix bug in composite image generation where mangled symbol names might conflict.
Fixes #43466 and fixes #43467
private readonly IMethodNode _targetMethod;
- private readonly ModuleToken _methodToken;
+ private readonly MethodWithToken _methodToken;
public DelegateCtorSignature(
TypeDesc delegateType,
IMethodNode targetMethod,
- ModuleToken methodToken)
+ MethodWithToken methodToken)
{
_delegateType = delegateType;
_targetMethod = targetMethod;
if (!relocsOnly)
{
- SignatureContext innerContext = builder.EmitFixup(factory, ReadyToRunFixupKind.DelegateCtor, _methodToken.Module, factory.SignatureContext);
+ SignatureContext innerContext = builder.EmitFixup(factory, ReadyToRunFixupKind.DelegateCtor, _methodToken.Token.Module, factory.SignatureContext);
builder.EmitMethodSignature(
- new MethodWithToken(_targetMethod.Method, _methodToken, constrainedType: null, unboxing: false),
+ _methodToken,
enforceDefEncoding: false,
enforceOwningType: false,
innerContext,
if (result != 0)
return result;
- return _methodToken.CompareTo(otherNode._methodToken);
+ return _methodToken.CompareTo(otherNode._methodToken, comparer);
}
}
}
public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(nameMangler.CompilationUnitPrefix);
- sb.Append($@"TypeFixupSignature({_fixupKind.ToString()}): {_fieldDesc.ToString()}");
+ sb.Append($@"FieldFixupSignature({_fixupKind.ToString()}): ");
+ sb.Append(nameMangler.GetMangledFieldName(_fieldDesc));
}
public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
ArraySignatureBuilder signatureBuilder = new ArraySignatureBuilder();
signatureBuilder.EmitMethodSignature(
- new MethodWithToken(method.Method, moduleToken, constrainedType: null, unboxing: false),
+ new MethodWithToken(method.Method, moduleToken, constrainedType: null, unboxing: false, context: null),
enforceDefEncoding: true,
enforceOwningType: _factory.CompilationModuleGroup.EnforceOwningType(moduleToken.Module),
factory.SignatureContext,
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Diagnostics;
+using System.Reflection.Metadata;
+using System.Reflection.Metadata.Ecma335;
using Internal.JitInterface;
using Internal.Text;
// Ensure types in signature are loadable and resolvable, otherwise we'll fail later while emitting the signature
CompilerTypeSystemContext compilerContext = (CompilerTypeSystemContext)method.Method.Context;
compilerContext.EnsureLoadableMethod(method.Method);
+ compilerContext.EnsureLoadableType(_method.OwningType);
+
if (method.ConstrainedType != null)
compilerContext.EnsureLoadableType(method.ConstrainedType);
}
}
else if (_method.Token.TokenType == CorTokenType.mdtMemberRef)
{
- fixupKind = ReadyToRunFixupKind.MethodEntry_RefToken;
- optimized = true;
+ if (!_method.OwningTypeNotDerivedFromToken)
+ {
+ fixupKind = ReadyToRunFixupKind.MethodEntry_RefToken;
+ optimized = true;
+ }
}
}
}
{
if (method.Token.TokenType == CorTokenType.mdtMethodSpec)
{
- method = new MethodWithToken(method.Method, factory.SignatureContext.GetModuleTokenForMethod(method.Method, throwIfNotFound: false), method.ConstrainedType, unboxing: _method.Unboxing);
+ method = new MethodWithToken(method.Method, factory.SignatureContext.GetModuleTokenForMethod(method.Method, throwIfNotFound: false), method.ConstrainedType, unboxing: _method.Unboxing, null);
}
else if (!optimized && (method.Token.TokenType == CorTokenType.mdtMemberRef))
{
if (method.Method.OwningType.GetTypeDefinition() is EcmaType)
{
- method = new MethodWithToken(method.Method, factory.SignatureContext.GetModuleTokenForMethod(method.Method, throwIfNotFound: false), method.ConstrainedType, unboxing: _method.Unboxing);
+ method = new MethodWithToken(method.Method, factory.SignatureContext.GetModuleTokenForMethod(method.Method, throwIfNotFound: false), method.ConstrainedType, unboxing: _method.Unboxing, null);
}
}
}
{
flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained;
}
- if (enforceOwningType)
+ if (enforceOwningType || method.OwningTypeNotDerivedFromToken)
{
flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
}
- if ((method.Method.HasInstantiation || method.Method.OwningType.HasInstantiation) && !method.Method.IsGenericMethodDefinition)
- {
- EmitMethodSpecificationSignature(method, flags, enforceDefEncoding, context);
- }
- else
- {
- switch (method.Token.TokenType)
- {
- case CorTokenType.mdtMethodDef:
- {
- EmitUInt(flags);
- if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
- {
- EmitTypeSignature(method.Method.OwningType, context);
- }
- EmitMethodDefToken(method.Token);
- }
- break;
-
- case CorTokenType.mdtMemberRef:
- {
- flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken;
-
- // Owner type is needed for type specs to instantiating stubs or generics with signature variables still present
- if (!method.Method.OwningType.IsDefType &&
- ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0 || method.Method.OwningType.ContainsSignatureVariables()))
- {
- flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
- }
- else if (method.Method.IsArrayMethod())
- {
- var memberRefMethod = method.Token.Module.GetMethod(MetadataTokens.EntityHandle((int)method.Token.Token));
- if (memberRefMethod.OwningType != method.Method.OwningType)
- {
- flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
- }
- }
-
- EmitUInt(flags);
- if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
- {
- EmitTypeSignature(method.Method.OwningType, context);
- }
- EmitMethodRefToken(method.Token);
- }
- break;
-
- default:
- throw new NotImplementedException();
- }
- }
+ EmitMethodSpecificationSignature(method, flags, enforceDefEncoding, context);
if (method.ConstrainedType != null)
{
uint flags, bool enforceDefEncoding, SignatureContext context)
{
ModuleToken methodToken = method.Token;
- if (method.Method.HasInstantiation)
+ if (method.Method.HasInstantiation && !method.Method.IsGenericMethodDefinition)
{
flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation;
if (!method.Token.IsNull)
}
}
- if (methodToken.IsNull && !enforceDefEncoding)
- {
- methodToken = context.GetModuleTokenForMethod(method.Method, throwIfNotFound: false);
- }
- if (methodToken.IsNull)
- {
- flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
- methodToken = context.GetModuleTokenForMethod(method.Method);
- }
-
- if (method.Method.OwningType.HasInstantiation)
- {
- // resolveToken currently resolves the token in the context of a given scope;
- // in such case, we receive a method on instantiated type along with the
- // generic definition token.
- flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
- }
+ Debug.Assert(!methodToken.IsNull);
switch (methodToken.TokenType)
{
EmitUInt(flags);
if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
{
- EmitTypeSignature(method.Method.OwningType, context);
+ // The type here should be the type referred to by the memberref (if this is one, not the type where the method was eventually found!
+ EmitTypeSignature(method.OwningType, context);
}
EmitTokenRid(methodToken.Token);
if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0)
EcmaModule module = ((EcmaMethod)method.GetTypicalMethodDefinition()).Module;
ModuleToken moduleToken = Resolver.GetModuleTokenForMethod(method, throwIfNotFound: true);
- IMethodNode methodNodeDebug = MethodEntrypoint(new MethodWithToken(method, moduleToken, constrainedType: null, unboxing: false), false, false);
+ IMethodNode methodNodeDebug = MethodEntrypoint(new MethodWithToken(method, moduleToken, constrainedType: null, unboxing: false, context: null), false, false);
MethodWithGCInfo methodCodeNodeDebug = methodNodeDebug as MethodWithGCInfo;
if (methodCodeNodeDebug == null && methodNodeDebug is DelayLoadMethodImport DelayLoadMethodImport)
{
_codegenNodeFactory,
_codegenNodeFactory.HelperImports,
ReadyToRunHelper.DelayLoad_Helper_ObjObj,
- new DelegateCtorSignature(ctorKey.Type, targetMethodNode, ctorKey.Method.Token));
+ new DelegateCtorSignature(ctorKey.Type, targetMethodNode, ctorKey.Method));
});
_checkTypeLayoutCache = new NodeCache<TypeDesc, ISymbolNode>(key =>
public readonly ModuleToken Token;
public readonly TypeDesc ConstrainedType;
public readonly bool Unboxing;
+ public readonly bool OwningTypeNotDerivedFromToken;
+ public readonly TypeDesc OwningType;
- public MethodWithToken(MethodDesc method, ModuleToken token, TypeDesc constrainedType, bool unboxing)
+
+ public MethodWithToken(MethodDesc method, ModuleToken token, TypeDesc constrainedType, bool unboxing, object context)
{
Debug.Assert(!method.IsUnboxingThunk());
Method = method;
Token = token;
ConstrainedType = constrainedType;
Unboxing = unboxing;
+ OwningType = GetMethodTokenOwningType(this, constrainedType, context, out OwningTypeNotDerivedFromToken);
+ }
+
+ private static TypeDesc GetMethodTokenOwningType(MethodWithToken methodToken, TypeDesc constrainedType, object context, out bool owningTypeNotDerivedFromToken)
+ {
+ ModuleToken moduleToken = methodToken.Token;
+ owningTypeNotDerivedFromToken = false;
+
+ // Strip off method spec details. The owning type is only associated with a MethodDef or a MemberRef
+ if (moduleToken.TokenType == CorTokenType.mdtMethodSpec)
+ {
+ var methodSpecification = moduleToken.MetadataReader.GetMethodSpecification((MethodSpecificationHandle)moduleToken.Handle);
+ moduleToken = new ModuleToken(moduleToken.Module, methodSpecification.Method);
+ }
+
+ if (moduleToken.TokenType == CorTokenType.mdtMethodDef)
+ {
+ var methodDefinition = moduleToken.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)moduleToken.Handle);
+ return HandleContext(moduleToken.Module, methodDefinition.GetDeclaringType(), methodToken.Method.OwningType, constrainedType, context, ref owningTypeNotDerivedFromToken);
+ }
+
+ // At this point moduleToken must point at a MemberRef.
+ Debug.Assert(moduleToken.TokenType == CorTokenType.mdtMemberRef);
+ var memberRef = moduleToken.MetadataReader.GetMemberReference((MemberReferenceHandle)moduleToken.Handle);
+ switch (memberRef.Parent.Kind)
+ {
+ case HandleKind.TypeDefinition:
+ case HandleKind.TypeReference:
+ case HandleKind.TypeSpecification:
+ {
+ return HandleContext(moduleToken.Module, memberRef.Parent, methodToken.Method.OwningType, constrainedType, context, ref owningTypeNotDerivedFromToken);
+ }
+
+ default:
+ return methodToken.Method.OwningType;
+ }
+
+ TypeDesc HandleContext(EcmaModule module, EntityHandle handle, TypeDesc methodTargetOwner, TypeDesc constrainedType, object context, ref bool owningTypeNotDerivedFromToken)
+ {
+ var tokenOnlyOwningType = module.GetType(handle);
+ TypeDesc actualOwningType;
+
+ if (context == null)
+ {
+ actualOwningType = methodTargetOwner;
+ }
+ else
+ {
+ Instantiation typeInstantiation;
+ Instantiation methodInstantiation = new Instantiation();
+
+ if (context is MethodDesc methodContext)
+ {
+ typeInstantiation = methodContext.OwningType.Instantiation;
+ methodInstantiation = methodContext.Instantiation;
+ }
+ else
+ {
+ TypeDesc typeContext = (TypeDesc)context;
+ typeInstantiation = typeContext.Instantiation;
+ }
+
+ var instantiatedOwningType = tokenOnlyOwningType.InstantiateSignature(typeInstantiation, methodInstantiation);
+ var canonicalizedOwningType = instantiatedOwningType.ConvertToCanonForm(CanonicalFormKind.Specific);
+ if ((instantiatedOwningType == canonicalizedOwningType) || (constrainedType != null))
+ {
+ actualOwningType = instantiatedOwningType;
+ }
+ else
+ {
+ actualOwningType = ComputeActualOwningType(methodTargetOwner, instantiatedOwningType, canonicalizedOwningType);
+
+ // Implement via a helper function, so that managing the loop escape behavior is easier to read
+ TypeDesc ComputeActualOwningType(TypeDesc methodTargetOwner, TypeDesc instantiatedOwningType, TypeDesc canonicalizedOwningType)
+ {
+ // Pick between Canonical and Exact OwningTypes.
+ //
+ // If the canonicalizedOwningType is the OwningType (or parent type) of the associated method
+ // Then return canonicalizedOwningType
+ // Else If the Exact Owning type is the OwningType (or parent type) of the associated method
+ // Then return actualOwningType
+ // Else If the canonicallized owningType (or canonicalized parent type) of the associated method
+ // Return the canonicalizedOwningType
+ // Else
+ // Fail, unexpected behavior
+ var currentType = canonicalizedOwningType;
+ while (currentType != null)
+ {
+ if (currentType == methodTargetOwner)
+ return canonicalizedOwningType;
+ currentType = currentType.BaseType;
+ }
+
+ currentType = instantiatedOwningType;
+ while (currentType != null)
+ {
+ if (currentType == methodTargetOwner)
+ return instantiatedOwningType;
+ currentType = currentType.BaseType;
+ }
+
+ currentType = canonicalizedOwningType;
+ while (currentType != null)
+ {
+ currentType = currentType.ConvertToCanonForm(CanonicalFormKind.Specific);
+ if (currentType == methodTargetOwner)
+ return canonicalizedOwningType;
+ currentType = currentType.BaseType;
+ }
+
+ Debug.Assert(false);
+ throw new Exception();
+ }
+ }
+ }
+
+ if (actualOwningType != tokenOnlyOwningType)
+ {
+ owningTypeNotDerivedFromToken = true;
+ }
+ return actualOwningType;
+ }
}
public override bool Equals(object obj)
public bool Equals(MethodWithToken methodWithToken)
{
- return Method == methodWithToken.Method && Token.Equals(methodWithToken.Token) && ConstrainedType == methodWithToken.ConstrainedType && Unboxing == methodWithToken.Unboxing;
+ bool equals = Method == methodWithToken.Method && Token.Equals(methodWithToken.Token) && ConstrainedType == methodWithToken.ConstrainedType &&
+ Unboxing == methodWithToken.Unboxing;
+ if (equals)
+ {
+ Debug.Assert(OwningTypeNotDerivedFromToken == methodWithToken.OwningTypeNotDerivedFromToken);
+ Debug.Assert(OwningType == methodWithToken.OwningType);
+ }
+
+ return equals;
}
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
if (result != 0)
return result;
- return Unboxing.CompareTo(other.Unboxing);
+ result = Unboxing.CompareTo(other.Unboxing);
+ if (result != 0)
+ return result;
+
+ // The OwningType/OwningTypeNotDerivedFromToken shoud be equivalent if the above conditions are equal.
+ Debug.Assert(OwningTypeNotDerivedFromToken == other.OwningTypeNotDerivedFromToken);
+ Debug.Assert(OwningType == other.OwningType);
+
+ if (OwningTypeNotDerivedFromToken != other.OwningTypeNotDerivedFromToken)
+ {
+ if (OwningTypeNotDerivedFromToken)
+ return 1;
+ else
+ return -1;
+ }
+
+ return comparer.Compare(OwningType, other.OwningType);
}
}
object helperArg = GetRuntimeDeterminedObjectForToken(ref pResolvedToken);
if (helperArg is MethodDesc methodDesc)
{
- helperArg = new MethodWithToken(methodDesc, HandleToModuleToken(ref pResolvedToken), constrainedType, unboxing: false);
+ var methodIL = (MethodIL)HandleToObject((IntPtr)pResolvedToken.tokenScope);
+ MethodDesc sharedMethod = methodIL.OwningMethod.GetSharedRuntimeFormMethodTarget();
+ helperArg = new MethodWithToken(methodDesc, HandleToModuleToken(ref pResolvedToken), constrainedType, unboxing: false, context: sharedMethod);
}
GenericContext methodContext = new GenericContext(entityFromContext(pResolvedToken.tokenContext));
TypeDesc delegateTypeDesc = HandleToObject(delegateType);
MethodDesc targetMethodDesc = HandleToObject(pTargetMethod.hMethod);
Debug.Assert(!targetMethodDesc.IsUnboxingThunk());
- MethodWithToken targetMethod = new MethodWithToken(targetMethodDesc, HandleToModuleToken(ref pTargetMethod), constrainedType: null, unboxing: false);
+ MethodWithToken targetMethod = new MethodWithToken(targetMethodDesc, HandleToModuleToken(ref pTargetMethod), constrainedType: null, unboxing: false, context: entityFromContext(pTargetMethod.tokenContext));
pLookup.lookupKind.needsRuntimeLookup = false;
pLookup.constLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.DelegateCtor(delegateTypeDesc, targetMethod));
return false;
}
- private ModuleToken HandleToModuleToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken, MethodDesc methodDesc)
+ private MethodWithToken ComputeMethodWithToken(MethodDesc method, ref CORINFO_RESOLVED_TOKEN pResolvedToken, TypeDesc constrainedType, bool unboxing)
+ {
+ ModuleToken token = HandleToModuleToken(ref pResolvedToken, method, out object context, ref constrainedType);
+ return new MethodWithToken(method, token, constrainedType: constrainedType, unboxing: unboxing, context: context);
+ }
+
+ private ModuleToken HandleToModuleToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken, MethodDesc methodDesc, out object context, ref TypeDesc constrainedType)
{
if (methodDesc != null && (_compilation.NodeFactory.CompilationModuleGroup.VersionsWithMethodBody(methodDesc) || methodDesc.IsPInvoke))
{
methodDesc?.GetTypicalMethodDefinition() is EcmaMethod ecmaMethod)
{
mdToken token = (mdToken)MetadataTokens.GetToken(ecmaMethod.Handle);
+
+ // This is used for de-virtualization of non-generic virtual methods, and should be treated
+ // as a the methodDesc parameter defining the exact OwningType, not doing resolution through the token.
+ context = null;
+ constrainedType = null;
+
return new ModuleToken(ecmaMethod.Module, token);
}
}
+ context = entityFromContext(pResolvedToken.tokenContext);
return HandleToModuleToken(ref pResolvedToken);
}
+
private ModuleToken HandleToModuleToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken)
{
mdToken token = pResolvedToken.token;
pResult->codePointerOrStubLookup.constLookup = CreateConstLookupToSymbol(
_compilation.SymbolNodeFactory.InterfaceDispatchCell(
- new MethodWithToken(targetMethod, HandleToModuleToken(ref pResolvedToken, targetMethod), constrainedType: null, unboxing: false),
+ ComputeMethodWithToken(targetMethod, ref pResolvedToken, constrainedType: null, unboxing: false),
MethodBeingCompiled));
// If the abi of the method isn't stable, this will cause a usage of the RequiresRuntimeJitSymbol, which will trigger a RequiresRuntimeJitException
// READYTORUN: FUTURE: Direct calls if possible
pResult->codePointerOrStubLookup.constLookup = CreateConstLookupToSymbol(
_compilation.NodeFactory.MethodEntrypoint(
- new MethodWithToken(nonUnboxingMethod, HandleToModuleToken(ref pResolvedToken, nonUnboxingMethod), constrainedType, unboxing: isUnboxingStub),
+ ComputeMethodWithToken(nonUnboxingMethod, ref pResolvedToken, constrainedType, unboxing: isUnboxingStub),
isInstantiatingStub: useInstantiatingStub,
isPrecodeImportRequired: (flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_LDFTN) != 0));
bool atypicalCallsite = (flags & CORINFO_CALLINFO_FLAGS.CORINFO_CALLINFO_ATYPICAL_CALLSITE) != 0;
pResult->codePointerOrStubLookup.constLookup = CreateConstLookupToSymbol(
_compilation.NodeFactory.DynamicHelperCell(
- new MethodWithToken(targetMethod, HandleToModuleToken(ref pResolvedToken, targetMethod), constrainedType: null, unboxing: false),
+ ComputeMethodWithToken(targetMethod, ref pResolvedToken, constrainedType: null, unboxing: false),
useInstantiatingStub));
Debug.Assert(!pResult->sig.hasTypeArg());
{
pResult->instParamLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.CreateReadyToRunHelper(
ReadyToRunHelperId.MethodDictionary,
- new MethodWithToken(targetMethod, HandleToModuleToken(ref pResolvedToken, targetMethod), constrainedType, unboxing: false)));
+ ComputeMethodWithToken(targetMethod, ref pResolvedToken, constrainedType: constrainedType, unboxing: false)));
}
else
{
symbolNode = _compilation.SymbolNodeFactory.CreateReadyToRunHelper(
ReadyToRunHelperId.MethodHandle,
- new MethodWithToken(md, HandleToModuleToken(ref pResolvedToken), constrainedType: null, unboxing: unboxingStub));
+ ComputeMethodWithToken(md, ref pResolvedToken, constrainedType: null, unboxing: unboxingStub));
}
break;
methodDesc = rawPInvoke.Target;
EcmaMethod ecmaMethod = (EcmaMethod)methodDesc;
ModuleToken moduleToken = new ModuleToken(ecmaMethod.Module, ecmaMethod.Handle);
- MethodWithToken methodWithToken = new MethodWithToken(ecmaMethod, moduleToken, constrainedType: null, unboxing: false);
+ MethodWithToken methodWithToken = new MethodWithToken(ecmaMethod, moduleToken, constrainedType: null, unboxing: false, context: null);
if (ecmaMethod.IsSuppressGCTransition())
{
if defined __CompositeBuildMode (
set __CrossgenCmd=%__CrossgenCmd% --composite
) else (
- set __CrossgenCmd=%__CrossgenCmd% --large-bubble
+ set __CrossgenCmd=%__CrossgenCmd% --large-bubble --crossgen2-parallelism 1
)
set __CrossgenDir=%__BinDir%
if /i "%__BuildArch%" == "x86" (
set __CrossgenDir=!__CrossgenDir!\x64
)
- set __CrossgenCmd=%__CrossgenCmd% --verify-type-and-field-layout --crossgen2-parallelism 1 --crossgen2-path "!__CrossgenDir!\crossgen2\crossgen2.dll"
+ set __CrossgenCmd=%__CrossgenCmd% --verify-type-and-field-layout --crossgen2-path "!__CrossgenDir!\crossgen2\crossgen2.dll"
)
echo Running %__CrossgenCmd%
if [[ "$__CompositeBuildMode" != 0 ]]; then
crossgenCmd="$crossgenCmd --composite"
+ else
+ crossgenCmd="$crossgenCmd --crossgen2-parallelism 1"
fi
local crossgenDir="$__BinDir"
if [[ "$__DoCrossgen" != 0 ]]; then
crossgenCmd="$crossgenCmd --crossgen --nocrossgen2 --crossgen-path \"$crossgenDir/crossgen\""
else
- crossgenCmd="$crossgenCmd --verify-type-and-field-layout --crossgen2-parallelism 1 --crossgen2-path \"$crossgenDir/crossgen2/crossgen2.dll\""
+ crossgenCmd="$crossgenCmd --verify-type-and-field-layout --crossgen2-path \"$crossgenDir/crossgen2/crossgen2.dll\""
fi
echo "Running $crossgenCmd"
</ExcludeList>
</ItemGroup>
- <!-- Crossgen2 type generator tests currently failing outerloop Windows legs -->
- <ItemGroup Condition="'$(XunitTestBinBase)' != '' and '$(TestBuildMode)' == 'crossgen2' and '$(RuntimeFlavor)' == 'coreclr' and '$(TargetsWindows)' == 'true'">
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest612/Generated612/*">
- <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest613/Generated613/*">
- <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest614/Generated614/*">
- <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest681/Generated681/*">
- <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest682/Generated682/*">
- <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest683/Generated683/*">
- <Issue>https://github.com/dotnet/runtime/issues/43466</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest1/Generated1/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest14/Generated14/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest15/Generated15/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest16/Generated16/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest17/Generated17/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest18/Generated18/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest19/Generated19/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest20/Generated20/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest21/Generated21/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest22/Generated22/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest23/Generated23/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest24/Generated24/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest25/Generated25/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest26/Generated26/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest27/Generated27/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest28/Generated28/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest62/Generated62/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest63/Generated63/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest64/Generated64/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest65/Generated65/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest66/Generated66/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest67/Generated67/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest68/Generated68/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest69/Generated69/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest70/Generated70/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest171/Generated171/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest192/Generated192/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest193/Generated193/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest194/Generated194/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest195/Generated195/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest196/Generated196/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest197/Generated197/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest198/Generated198/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest199/Generated199/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest200/Generated200/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest201/Generated201/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest202/Generated202/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest203/Generated203/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest204/Generated204/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest205/Generated205/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest206/Generated206/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest207/Generated207/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest208/Generated208/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest209/Generated209/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest210/Generated210/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest211/Generated211/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest212/Generated212/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest213/Generated213/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest214/Generated214/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest215/Generated215/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest292/Generated292/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest293/Generated293/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest294/Generated294/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest295/Generated295/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest296/Generated296/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest297/Generated297/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest298/Generated298/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest299/Generated299/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest300/Generated300/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest301/Generated301/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest302/Generated302/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest303/Generated303/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest304/Generated304/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest305/Generated305/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest306/Generated306/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/TypeGeneratorTests/TypeGeneratorTest307/Generated307/*">
- <Issue>https://github.com/dotnet/runtime/issues/43467</Issue>
- </ExcludeList>
- </ItemGroup>
-
<!-- run.proj finds all the *.cmd/*.sh scripts in a test folder and creates corresponding test methods.
Exclude these scripts to avoid creating such methods for the superpmicollect dependent test projects
and running them separately from superpmicollect test. These should be excluded regardless of RuntimeFlavor/os/arch-->
<ExcludeList Include="$(XunitTestBinBase)/readytorun/crossgen2/crossgen2smoke/**">
<Issue>needs triage</Issue>
</ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)/readytorun/crossgen2/crossgen2smoke_donotalwaysusecrossgen2/**">
+ <Issue>needs triage</Issue>
+ </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/readytorun/tests/mainv1/**">
<Issue>needs triage</Issue>
</ExcludeList>
TextFileName = EmitTextFileForTesting();
+ RunTest("CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller", HelperILDllTests.CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller());
+ RunTest("CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller", HelperILDllTests.CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller());
+ RunTest("CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCreateDelegate", HelperILDllTests.CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCreateDelegate());
+ RunTest("CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller", HelperILDllTests.CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller());
+ RunTest("CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller", HelperILDllTests.CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller());
RunTest("NewString", NewString());
RunTest("WriteLine", WriteLine());
RunTest("IsInstanceOf", IsInstanceOf());
RunTest("TestWithStructureNonBlittableFieldDueToGenerics", TestWithStructureNonBlittableFieldDueToGenerics());
RunTest("TestSingleElementStructABI", TestSingleElementStructABI());
RunTest("TestEnumLayoutAlignments", TestEnumLayoutAlignments());
-
File.Delete(TextFileName);
Console.WriteLine($@"{_passedTests.Count} tests pass:");
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <OutputType>exe</OutputType>
- <CLRTestKind>BuildAndRun</CLRTestKind>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <CLRTestPriority>0</CLRTestPriority>
-
<!-- ilasm round-trip testing doesn't make sense for this test -->
<IlasmRoundTripIncompatible>true</IlasmRoundTripIncompatible>
<!-- This is an explicit crossgen test -->
<AlwaysUseCrossGen2>true</AlwaysUseCrossGen2>
</PropertyGroup>
- <ItemGroup>
- <ProjectReference Include=".\helperdll.csproj" />
- <ProjectReference Include=".\helperildll.ilproj" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Program.cs" />
- </ItemGroup>
+ <Import Project="smoketest.targets" />
</Project>
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <Import Project="smoketest.targets" />
+</Project>
\ No newline at end of file
return inputIntValue;
}
}
+
+public class BaseTypeNonGenericMethodActuallyOnBase
+{
+ public string Method()
+ {
+ return "BaseTypeNonGenericMethodActuallyOnBase::Method";
+ }
+
+ public string GenMethod<T>()
+ {
+ return "BaseTypeNonGenericMethodActuallyOnBase::GenMethod<T>";
+ }
+}
+
+public class BaseTypeGenericMethodActuallyOnBase<U>
+{
+ public string Method()
+ {
+ return "BaseTypeGenericMethodActuallyOnBase<U>::Method";
+ }
+
+ public string GenMethod<T>()
+ {
+ return "BaseTypeGenericMethodActuallyOnBase<U>::GenMethod<T>";
+ }
+}
ret
}
}
+
+.class auto ansi public beforefieldinit BaseTypeNonGenericMethodActuallyOnBase_ModuleLocal extends [mscorlib]System.Object
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ldarg.0
+ call instance void [mscorlib]System.Object::.ctor()
+ ret
+ }
+
+ .method public hidebysig instance string Method() cil managed noinlining
+ {
+ ldstr "BaseTypeNonGenericMethodActuallyOnBase::Method"
+ ret
+ }
+}
+
+.class auto ansi public beforefieldinit DerivedTypeGenericMethodActuallyOnBase_ModuleLocal`1<T0> extends BaseTypeNonGenericMethodActuallyOnBase_ModuleLocal
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ldarg.0
+ call instance void BaseTypeNonGenericMethodActuallyOnBase_ModuleLocal::.ctor()
+ ret
+ }
+}
+
+.class auto ansi public beforefieldinit DerivedTypeGenericMethodActuallyOnBase`1<T0> extends [helperdll]BaseTypeNonGenericMethodActuallyOnBase
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ldarg.0
+ call instance void [helperdll]BaseTypeNonGenericMethodActuallyOnBase::.ctor()
+ ret
+ }
+}
+
+.class auto ansi public beforefieldinit DerivedTypeNonGenericMethodActuallyOnBase`1<T0> extends class [helperdll]BaseTypeGenericMethodActuallyOnBase<string>
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ldarg.0
+ call instance void class [helperdll]BaseTypeGenericMethodActuallyOnBase<string>::.ctor()
+ ret
+ }
+}
+
+.class public auto ansi beforefieldinit HelperILDllTests {
+
+ .method static class [mscorlib]System.Func`1<string> GetDelegateMethodFromGenericType<T0>() cil managed noinlining
+ {
+ newobj instance void class DerivedTypeGenericMethodActuallyOnBase_ModuleLocal`1<!!0>::.ctor()
+ ldftn instance string class DerivedTypeGenericMethodActuallyOnBase_ModuleLocal`1<!!T0>::Method()
+ newobj instance void class [mscorlib]System.Func`1<string>::.ctor(object, native int)
+ ret
+ }
+
+ .method static string CallMethodFromGenericType<T0>() cil managed noinlining
+ {
+ newobj instance void class DerivedTypeGenericMethodActuallyOnBase`1<!!0>::.ctor()
+ callvirt instance string class DerivedTypeGenericMethodActuallyOnBase`1<!!T0>::Method()
+ ret
+ }
+
+ .method static string CallGenMethodFromGenericType<T0>() cil managed noinlining
+ {
+ newobj instance void class DerivedTypeGenericMethodActuallyOnBase`1<!!0>::.ctor()
+ callvirt instance string class DerivedTypeGenericMethodActuallyOnBase`1<!!T0>::GenMethod<!!0>()
+ ret
+ }
+
+ .method public hidebysig static bool CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCreateDelegate() cil managed noinlining
+ {
+ .maxstack 10
+ .locals init (object V_0)
+ call class [mscorlib]System.Func`1<string> HelperILDllTests::GetDelegateMethodFromGenericType<object>()
+ callvirt instance !0 class [mscorlib]System.Func`1<string>::Invoke()
+ ldstr "BaseTypeNonGenericMethodActuallyOnBase::Method"
+ call bool [mscorlib]System.String::op_Equality(string,string)
+ ret
+ }
+
+
+ .method public hidebysig static bool CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller() cil managed noinlining
+ {
+ .maxstack 10
+ .locals init (object V_0)
+ call string HelperILDllTests::CallMethodFromGenericType<object>()
+ ldstr "BaseTypeNonGenericMethodActuallyOnBase::Method"
+ call bool [mscorlib]System.String::op_Equality(string,string)
+ ret
+ }
+
+ .method public hidebysig static bool CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_GenericCaller() cil managed noinlining
+ {
+ .maxstack 10
+ .locals init (object V_0)
+ call string HelperILDllTests::CallGenMethodFromGenericType<object>()
+ ldstr "BaseTypeNonGenericMethodActuallyOnBase::GenMethod<T>"
+ call bool [mscorlib]System.String::op_Equality(string,string)
+ ret
+ }
+
+ .method public hidebysig static bool CallMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller() cil managed noinlining
+ {
+ .maxstack 10
+ .locals init (object V_0)
+ newobj instance void class DerivedTypeGenericMethodActuallyOnBase`1<object>::.ctor()
+ callvirt instance string class DerivedTypeGenericMethodActuallyOnBase`1<object>::Method()
+ ldstr "BaseTypeNonGenericMethodActuallyOnBase::Method"
+ call bool [mscorlib]System.String::op_Equality(string,string)
+ ret
+ }
+
+ .method public hidebysig static bool CallGenMethodUsingMemberRefToDerivedWhereMethodIsActuallyOnBase_NonGenericCaller() cil managed noinlining
+ {
+ .maxstack 10
+ .locals init (object V_0)
+ newobj instance void class DerivedTypeGenericMethodActuallyOnBase`1<object>::.ctor()
+ callvirt instance string class DerivedTypeGenericMethodActuallyOnBase`1<object>::GenMethod<string>()
+ ldstr "BaseTypeNonGenericMethodActuallyOnBase::GenMethod<T>"
+ call bool [mscorlib]System.String::op_Equality(string,string)
+ ret
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project>
+ <PropertyGroup>
+ <OutputType>exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+ <ItemGroup>
+ <ProjectReference Include=".\helperdll.csproj" />
+ <ProjectReference Include=".\helperildll.ilproj" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ </ItemGroup>
+</Project>
\ No newline at end of file