1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
6 using System.Diagnostics;
8 using Internal.JitInterface;
10 using Internal.TypeSystem;
11 using Internal.TypeSystem.Ecma;
13 namespace ILCompiler.DependencyAnalysis.ReadyToRun
15 public class GenericLookupSignature : Signature
17 private readonly CORINFO_RUNTIME_LOOKUP_KIND _runtimeLookupKind;
19 private readonly ReadyToRunFixupKind _fixupKind;
21 private readonly TypeDesc _typeArgument;
23 private readonly MethodWithToken _methodArgument;
25 private readonly FieldDesc _fieldArgument;
27 private readonly GenericContext _methodContext;
29 private readonly SignatureContext _signatureContext;
31 public GenericLookupSignature(
32 CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind,
33 ReadyToRunFixupKind fixupKind,
34 TypeDesc typeArgument,
35 MethodWithToken methodArgument,
36 FieldDesc fieldArgument,
37 GenericContext methodContext,
38 SignatureContext signatureContext)
40 Debug.Assert(typeArgument != null || methodArgument != null || fieldArgument != null);
41 _runtimeLookupKind = runtimeLookupKind;
42 _fixupKind = fixupKind;
43 _typeArgument = typeArgument;
44 _methodArgument = methodArgument;
45 _fieldArgument = fieldArgument;
46 _methodContext = methodContext;
47 _signatureContext = signatureContext;
50 public override int ClassCode => 258608008;
52 public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
56 return new ObjectData(Array.Empty<byte>(), null, 1, null);
59 ReadyToRunCodegenNodeFactory r2rFactory = (ReadyToRunCodegenNodeFactory)factory;
61 // Determine the need for module override
62 EcmaModule targetModule;
63 if (_methodArgument != null)
65 targetModule = _methodArgument.Token.Module;
67 else if (_typeArgument != null)
69 targetModule = _signatureContext.GetTargetModule(_typeArgument);
71 else if (_fieldArgument != null)
73 targetModule = _signatureContext.GetTargetModule(_fieldArgument);
77 throw new NotImplementedException();
80 ReadyToRunFixupKind fixupToEmit;
81 TypeDesc contextTypeToEmit = null;
83 switch (_runtimeLookupKind)
85 case CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_CLASSPARAM:
86 fixupToEmit = ReadyToRunFixupKind.READYTORUN_FIXUP_TypeDictionaryLookup;
89 case CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_METHODPARAM:
90 fixupToEmit = ReadyToRunFixupKind.READYTORUN_FIXUP_MethodDictionaryLookup;
93 case CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_THISOBJ:
94 fixupToEmit = ReadyToRunFixupKind.READYTORUN_FIXUP_ThisObjDictionaryLookup;
95 contextTypeToEmit = _methodContext.ContextType;
99 throw new NotImplementedException();
102 ObjectDataSignatureBuilder dataBuilder = new ObjectDataSignatureBuilder();
103 dataBuilder.AddSymbol(this);
105 SignatureContext innerContext = dataBuilder.EmitFixup(r2rFactory, fixupToEmit, targetModule, _signatureContext);
106 if (contextTypeToEmit != null)
108 dataBuilder.EmitTypeSignature(contextTypeToEmit, innerContext);
111 dataBuilder.EmitByte((byte)_fixupKind);
112 if (_methodArgument != null)
114 dataBuilder.EmitMethodSignature(
116 enforceDefEncoding: false,
117 enforceOwningType: false,
118 context: innerContext,
119 isUnboxingStub: false,
120 isInstantiatingStub: true);
122 else if (_typeArgument != null)
124 dataBuilder.EmitTypeSignature(_typeArgument, innerContext);
126 else if (_fieldArgument != null)
128 dataBuilder.EmitFieldSignature(_fieldArgument, innerContext);
132 throw new NotImplementedException();
135 return dataBuilder.ToObjectData();
138 public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
140 sb.Append(nameMangler.CompilationUnitPrefix);
141 sb.Append("GenericLookupSignature(");
142 sb.Append(_runtimeLookupKind.ToString());
144 sb.Append(_fixupKind.ToString());
146 if (_methodArgument != null)
148 sb.Append(nameMangler.GetMangledMethodName(_methodArgument.Method));
149 if (!_methodArgument.Token.IsNull)
152 sb.Append(_methodArgument.Token.MetadataReader.GetString(_methodArgument.Token.MetadataReader.GetAssemblyDefinition().Name));
154 sb.Append(((uint)_methodArgument.Token.Token).ToString("X8"));
158 if (_typeArgument != null)
160 sb.Append(nameMangler.GetMangledTypeName(_typeArgument));
162 if (_fieldArgument != null)
164 sb.Append(nameMangler.GetMangledFieldName(_fieldArgument));
167 _methodContext.AppendMangledName(nameMangler, sb);
171 public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
173 GenericLookupSignature otherNode = (GenericLookupSignature)other;
174 int result = _runtimeLookupKind.CompareTo(otherNode._runtimeLookupKind);
178 result = _fixupKind.CompareTo(otherNode._fixupKind);
182 if (_typeArgument != null || otherNode._typeArgument != null)
184 if (_typeArgument == null)
186 if (otherNode._typeArgument == null)
189 result = comparer.Compare(_typeArgument, otherNode._typeArgument);
194 if (_fieldArgument != null || otherNode._fieldArgument != null)
196 if (_fieldArgument == null)
198 if (otherNode._fieldArgument == null)
201 result = comparer.Compare(_fieldArgument, otherNode._fieldArgument);
206 if (_methodArgument != null || otherNode._methodArgument != null)
208 if (_methodArgument == null)
210 if (otherNode._methodArgument == null)
213 result = _methodArgument.CompareTo(otherNode._methodArgument, comparer);
218 result = comparer.Compare(_methodContext.ContextMethod, otherNode._methodContext.ContextMethod);
222 return _signatureContext.CompareTo(otherNode._signatureContext, comparer);
225 protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
227 DependencyList dependencies = new DependencyList();
228 if (_typeArgument != null && !_typeArgument.IsRuntimeDeterminedSubtype)
230 dependencies.Add(factory.NecessaryTypeSymbol(_typeArgument), "Type referenced in a generic lookup signature");