// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Internal.TypeSystem; using Internal.JitInterface; using Internal.Text; using Internal.ReadyToRunConstants; namespace ILCompiler.DependencyAnalysis.ReadyToRun { public class DelegateCtorSignature : Signature { private readonly TypeDesc _delegateType; private readonly IMethodNode _targetMethod; private readonly MethodWithToken _methodToken; public DelegateCtorSignature( TypeDesc delegateType, IMethodNode targetMethod, MethodWithToken methodToken) { _delegateType = delegateType; _targetMethod = targetMethod; _methodToken = methodToken; // Ensure types in signature are loadable and resolvable, otherwise we'll fail later while emitting the signature CompilerTypeSystemContext compilerContext = (CompilerTypeSystemContext)delegateType.Context; compilerContext.EnsureLoadableType(delegateType); compilerContext.EnsureLoadableMethod(targetMethod.Method); } public override int ClassCode => 99885741; public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataSignatureBuilder builder = new ObjectDataSignatureBuilder(factory, relocsOnly); builder.AddSymbol(this); if (!relocsOnly) { SignatureContext innerContext = builder.EmitFixup(factory, ReadyToRunFixupKind.DelegateCtor, _methodToken.Token.Module, factory.SignatureContext); bool needsInstantiatingStub = _targetMethod.Method.HasInstantiation; if (_targetMethod.Method.IsVirtual && _targetMethod.Method.Signature.IsStatic) { // For static virtual methods, we always require an instantiating stub as the method may resolve to a canonical representation // at runtime without us being able to detect that at compile time. needsInstantiatingStub |= (_targetMethod.Method.OwningType.HasInstantiation || _methodToken.ConstrainedType != null); } builder.EmitMethodSignature( _methodToken, enforceDefEncoding: false, enforceOwningType: false, innerContext, isInstantiatingStub: needsInstantiatingStub); builder.EmitTypeSignature(_delegateType, innerContext); } return builder.ToObjectData(); } protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { return new DependencyList( new DependencyListEntry[] { new DependencyListEntry(_targetMethod, "Delegate target method") } ); } public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { sb.Append(nameMangler.CompilationUnitPrefix); sb.Append($@"DelegateCtor("); sb.Append(nameMangler.GetMangledTypeName(_delegateType)); sb.Append(" -> "u8); _targetMethod.AppendMangledName(nameMangler, sb); sb.Append("; "u8); sb.Append(_methodToken.ToString()); sb.Append(")"u8); } public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) { DelegateCtorSignature otherNode = (DelegateCtorSignature)other; int result = comparer.Compare(_delegateType, otherNode._delegateType); if (result != 0) return result; result = comparer.Compare(_targetMethod, otherNode._targetMethod); if (result != 0) return result; return _methodToken.CompareTo(otherNode._methodToken, comparer); } } } |