public void AddModuleTokenForField(FieldDesc field, ModuleToken token) { if (_compilationModuleGroup.VersionsWithType(field.OwningType) && field.OwningType is EcmaType) { // We don't need to store handles within the current compilation group // as we can read them directly from the ECMA objects. return; } TypeDesc owningCanonType = field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific); FieldDesc canonField = field; if (owningCanonType != field.OwningType) { canonField = CompilerContext.GetFieldForInstantiatedType(field.GetTypicalFieldDefinition(), (InstantiatedType)owningCanonType); } SetModuleTokenForTypeSystemEntity(_fieldToRefTokens, canonField, token); switch (token.TokenType) { case CorTokenType.mdtMemberRef: AddModuleTokenForFieldReference(owningCanonType, token); break; default: throw new NotImplementedException(); } }
public void EmitFieldSignature(FieldWithToken field, SignatureContext context) { uint fieldSigFlags = 0; TypeDesc ownerType = null; if (field.OwningTypeNotDerivedFromToken) { ownerType = field.Field.OwningType; fieldSigFlags |= (uint)ReadyToRunFieldSigFlags.READYTORUN_FIELD_SIG_OwnerType; } ModuleToken fieldToken = field.Token; switch (fieldToken.TokenType) { case CorTokenType.mdtMemberRef: fieldSigFlags |= (uint)ReadyToRunFieldSigFlags.READYTORUN_FIELD_SIG_MemberRefToken; break; case CorTokenType.mdtFieldDef: break; default: throw new NotImplementedException(); } EmitUInt(fieldSigFlags); if (ownerType != null) { EmitTypeSignature(ownerType, context); } EmitTokenRid(fieldToken.Token); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { ObjectDataSignatureBuilder dataBuilder = new ObjectDataSignatureBuilder(); if (!relocsOnly) { dataBuilder.AddSymbol(this); ModuleToken moduleToken = GetModuleToken(factory); IEcmaModule targetModule = moduleToken.Module; SignatureContext innerContext = dataBuilder.EmitFixup(factory, _fixupKind, targetModule, factory.SignatureContext); var metadata = ReadyToRunStandaloneMethodMetadata.Compute(_method); dataBuilder.EmitUInt(checked ((uint)metadata.ConstantData.Length)); dataBuilder.EmitBytes(metadata.ConstantData); dataBuilder.EmitUInt(checked ((uint)metadata.TypeRefs.Length)); foreach (var typeRef in metadata.TypeRefs) { if (factory.SignatureContext.Resolver.GetModuleTokenForType((EcmaType)typeRef, allowDynamicallyCreatedReference: true, throwIfNotFound: false).Module == null) { // If there isn't a module token yet for this type, force it to exist factory.ManifestMetadataTable._mutableModule.TryGetEntityHandle(typeRef); } dataBuilder.EmitTypeSignature(typeRef, innerContext); } MethodWithToken method = new MethodWithToken(_method, moduleToken, null, unboxing: false, context: null); dataBuilder.EmitMethodSignature(method, enforceDefEncoding: false, enforceOwningType: false, innerContext, false); } return(dataBuilder.ToObjectData()); }
public static byte[] BuildSignatureForMethodDefinedInModule(MethodDesc method, NodeFactory factory) { EcmaMethod typicalMethod = (EcmaMethod)method.GetTypicalMethodDefinition(); ModuleToken moduleToken; if (factory.CompilationModuleGroup.VersionsWithMethodBody(typicalMethod)) { moduleToken = new ModuleToken(typicalMethod.Module, typicalMethod.Handle); } else { MutableModule manifestMetadata = factory.ManifestMetadataTable._mutableModule; var handle = manifestMetadata.TryGetExistingEntityHandle(method.GetTypicalMethodDefinition()); Debug.Assert(handle.HasValue); moduleToken = new ModuleToken(factory.ManifestMetadataTable._mutableModule, handle.Value); } ArraySignatureBuilder signatureBuilder = new ArraySignatureBuilder(); signatureBuilder.EmitMethodSignature( new MethodWithToken(method, moduleToken, constrainedType: null, unboxing: false, context: null), enforceDefEncoding: true, enforceOwningType: moduleToken.Module is EcmaModule ? factory.CompilationModuleGroup.EnforceOwningType((EcmaModule)moduleToken.Module) : true, factory.SignatureContext, isInstantiatingStub: false); return(signatureBuilder.ToArray()); }
public void AddModuleTokenForType(TypeDesc type, ModuleToken token) { bool specialTypeFound = false; // Collect underlying type tokens for type specifications if (token.TokenType == CorTokenType.mdtTypeSpec) { TypeSpecification typeSpec = token.MetadataReader.GetTypeSpecification((TypeSpecificationHandle)token.Handle); typeSpec.DecodeSignature(new TokenResolverProvider(this, token.Module), this); specialTypeFound = true; } if (_compilationModuleGroup.VersionsWithType(type)) { // We don't need to store handles within the current compilation group // as we can read them directly from the ECMA objects. return; } if (type is EcmaType ecmaType) { // Don't store typespec tokens where a generic parameter resolves to the type in question if (token.TokenType == CorTokenType.mdtTypeDef || token.TokenType == CorTokenType.mdtTypeRef) { SetModuleTokenForTypeSystemEntity(_typeToRefTokens, ecmaType, token); } } else if (!specialTypeFound) { throw new NotImplementedException(type.ToString()); } }
public ExternalMethodImport( ReadyToRunCodegenNodeFactory factory, ReadyToRunFixupKind fixupKind, MethodDesc methodDesc, TypeDesc constrainedType, ModuleToken methodToken, bool isUnboxingStub, bool isInstantiatingStub, SignatureContext signatureContext) : base( factory, factory.MethodImports, ReadyToRunHelper.READYTORUN_HELPER_DelayLoad_MethodCall, factory.MethodSignature( fixupKind, methodDesc, constrainedType, methodToken, isUnboxingStub, isInstantiatingStub, signatureContext)) { _methodDesc = methodDesc; _signatureContext = signatureContext; }
public void EmitMethodSignature( MethodDesc method, TypeDesc constrainedType, ModuleToken methodToken, bool enforceDefEncoding, SignatureContext context, bool isUnboxingStub, bool isInstantiatingStub) { uint flags = 0; if (isUnboxingStub) { flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_UnboxingStub; } if (isInstantiatingStub) { flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub; } if (constrainedType != null) { flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained; } if (method.HasInstantiation || method.OwningType.HasInstantiation) { EmitMethodSpecificationSignature(method, methodToken, flags, enforceDefEncoding, context); } else { if (methodToken.IsNull) { methodToken = context.GetModuleTokenForMethod(method.GetTypicalMethodDefinition()); } switch (methodToken.TokenType) { case CorTokenType.mdtMethodDef: // TODO: module override for methoddefs with external module context EmitUInt(flags); EmitMethodDefToken(methodToken); break; case CorTokenType.mdtMemberRef: // TODO: module override for methodrefs with external module context flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken; EmitUInt(flags); EmitMethodRefToken(methodToken); break; default: throw new NotImplementedException(); } } if (constrainedType != null) { EmitTypeSignature(constrainedType, context); } }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, Array.Empty <ISymbolDefinitionNode>())); } PgoValueEmitter pgoEmitter = new PgoValueEmitter(_factory.CompilationModuleGroup, _symbolNodeFactory, true); NativeWriter hashtableWriter = new NativeWriter(); Section hashtableSection = hashtableWriter.NewSection(); VertexHashtable vertexHashtable = new VertexHashtable(); hashtableSection.Place(vertexHashtable); Dictionary <byte[], BlobVertex> uniqueInstrumentationData = new Dictionary <byte[], BlobVertex>(ByteArrayComparer.Instance); foreach (MethodDesc method in _instrumentationDataMethods) { pgoEmitter.Clear(); PgoProcessor.EncodePgoData(_profileDataManager[method].SchemaData, pgoEmitter, false); // In composite R2R format, always enforce owning type to let us share generic instantiations among modules EcmaMethod typicalMethod = (EcmaMethod)method.GetTypicalMethodDefinition(); ModuleToken moduleToken = new ModuleToken(typicalMethod.Module, typicalMethod.Handle); ArraySignatureBuilder signatureBuilder = new ArraySignatureBuilder(); signatureBuilder.EmitMethodSignature( new MethodWithToken(method, moduleToken, constrainedType: null, unboxing: false, context: null), enforceDefEncoding: true, enforceOwningType: _factory.CompilationModuleGroup.EnforceOwningType(moduleToken.Module), factory.SignatureContext, isInstantiatingStub: false); byte[] signature = signatureBuilder.ToArray(); BlobVertex signatureBlob = new BlobVertex(signature); byte[] encodedInstrumentationData = pgoEmitter.ToByteArray(); BlobVertex instrumentationDataBlob = null; if (!uniqueInstrumentationData.TryGetValue(encodedInstrumentationData, out instrumentationDataBlob)) { instrumentationDataBlob = new BlobVertex(encodedInstrumentationData); hashtableSection.Place(instrumentationDataBlob); uniqueInstrumentationData.Add(encodedInstrumentationData, instrumentationDataBlob); } PgoInstrumentedDataWithSignatureBlobVertex pgoDataVertex = new PgoInstrumentedDataWithSignatureBlobVertex(signatureBlob, 0, instrumentationDataBlob); hashtableSection.Place(pgoDataVertex); vertexHashtable.Append(unchecked ((uint)ReadyToRunHashCode.MethodHashCode(method)), pgoDataVertex); } MemoryStream hashtableContent = new MemoryStream(); hashtableWriter.Save(hashtableContent); return(new ObjectData( data: hashtableContent.ToArray(), relocs: null, alignment: 8, definedSymbols: new ISymbolDefinitionNode[] { this })); }
private void AddModuleTokenForFieldReference(TypeDesc owningType, ModuleToken token) { MemberReference memberRef = token.MetadataReader.GetMemberReference((MemberReferenceHandle)token.Handle); EntityHandle owningTypeHandle = memberRef.Parent; AddModuleTokenForType(owningType, new ModuleToken(token.Module, owningTypeHandle)); memberRef.DecodeFieldSignature <DummyTypeInfo, ModuleTokenResolver>(new TokenResolverProvider(this, token.Module), this); }
public DelegateCtorSignature( TypeDesc delegateType, IMethodNode targetMethod, ModuleToken methodToken, SignatureContext signatureContext) { _delegateType = delegateType; _targetMethod = targetMethod; _methodToken = methodToken; _signatureContext = signatureContext; }
private void EmitMethodSpecificationSignature(MethodWithToken method, uint flags, bool enforceDefEncoding, SignatureContext context) { ModuleToken methodToken = method.Token; if (method.Method.HasInstantiation && !method.Method.IsGenericMethodDefinition) { flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation; if (!method.Token.IsNull) { if (method.Token.TokenType == CorTokenType.mdtMethodSpec) { MethodSpecification methodSpecification = methodToken.MetadataReader.GetMethodSpecification((MethodSpecificationHandle)methodToken.Handle); methodToken = new ModuleToken(methodToken.Module, methodSpecification.Method); } } } Debug.Assert(!methodToken.IsNull); switch (methodToken.TokenType) { case CorTokenType.mdtMethodDef: break; case CorTokenType.mdtMemberRef: flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken; break; default: throw new NotImplementedException(); } EmitUInt(flags); if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0) { // 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) { Instantiation instantiation = method.Method.Instantiation; EmitUInt((uint)instantiation.Length); SignatureContext outerContext = context.OuterContext; for (int typeParamIndex = 0; typeParamIndex < instantiation.Length; typeParamIndex++) { EmitTypeSignature(instantiation[typeParamIndex], outerContext); } } }
public DelegateCtorSignature( TypeDesc delegateType, IMethodNode targetMethod, ModuleToken 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 void AddModuleTokenForMethod(MethodDesc method, ModuleToken token) { if (token.TokenType == CorTokenType.mdtMethodSpec) { MethodSpecification methodSpec = token.MetadataReader.GetMethodSpecification((MethodSpecificationHandle)token.Handle); methodSpec.DecodeSignature <DummyTypeInfo, ModuleTokenResolver>(new TokenResolverProvider(this, token.Module), this); token = new ModuleToken(token.Module, methodSpec.Method); } if (token.TokenType == CorTokenType.mdtMemberRef) { MemberReference memberRef = token.MetadataReader.GetMemberReference((MemberReferenceHandle)token.Handle); EntityHandle owningTypeHandle = memberRef.Parent; AddModuleTokenForType(method.OwningType, new ModuleToken(token.Module, owningTypeHandle)); memberRef.DecodeMethodSignature <DummyTypeInfo, ModuleTokenResolver>(new TokenResolverProvider(this, token.Module), this); } }
public MethodFixupSignature( ReadyToRunFixupKind fixupKind, MethodDesc methodDesc, TypeDesc constrainedType, ModuleToken methodToken, SignatureContext signatureContext, bool isUnboxingStub, bool isInstantiatingStub) { _fixupKind = fixupKind; _methodDesc = methodDesc; _methodToken = methodToken; _constrainedType = constrainedType; _signatureContext = signatureContext; _isUnboxingStub = isUnboxingStub; _isInstantiatingStub = isInstantiatingStub; }
private int MethodToInt(TypeSystemEntityOrUnknown handle) { if (handle.IsNull || (handle.AsMethod == null && handle.AsUnknown == 0)) { return(0); } if (_methodConversions.TryGetValue(handle, out int computedInt)) { return(computedInt); } if (handle.AsMethod != null && _compilationGroup.VersionsWithMethodBody(handle.AsMethod)) { EcmaMethod typicalMethod = (EcmaMethod)handle.AsMethod.GetTypicalMethodDefinition(); ModuleToken moduleToken = new ModuleToken(typicalMethod.Module, typicalMethod.Handle); MethodWithToken tok = new MethodWithToken(handle.AsMethod, moduleToken, constrainedType: null, unboxing: false, context: null); Import methodHandleImport = (Import)_symbolFactory.CreateReadyToRunHelper(ReadyToRunHelperId.MethodHandle, tok); _imports.Add(methodHandleImport); if (_actuallyCaptureOutput) { if (methodHandleImport.Table.IndexFromBeginningOfArray >= 0xF) { // The current implementation of this table only allows for 15 different // import tables to be used. This is probably enough for long term // but this code will throw if we use more import tables and attempt // to encode pgo data throw new Exception("Unexpected high index for table import"); } computedInt = (methodHandleImport.IndexFromBeginningOfArray << 4) | methodHandleImport.Table.IndexFromBeginningOfArray; } else { computedInt = _imports.Count << 1; } } else { computedInt = ((++_unknownMethodsFound) << 4) | 0xF; } _methodConversions.Add(handle, computedInt); return(computedInt); }
private ArraySignatureBuilder BuildSignatureForMethod(MethodWithGCInfo method, NodeFactory factory) { // In composite R2R format, always enforce owning type to let us share generic instantiations among modules EcmaMethod typicalMethod = (EcmaMethod)method.Method.GetTypicalMethodDefinition(); ModuleToken moduleToken = new ModuleToken(typicalMethod.Module, typicalMethod.Handle); ArraySignatureBuilder signatureBuilder = new ArraySignatureBuilder(); signatureBuilder.EmitMethodSignature( new MethodWithToken(method.Method, moduleToken, constrainedType: null, unboxing: false, context: null), enforceDefEncoding: true, enforceOwningType: _factory.CompilationModuleGroup.EnforceOwningType(moduleToken.Module), factory.SignatureContext, isInstantiatingStub: false); return(signatureBuilder); }
public void AddModuleTokenForField(FieldDesc field, ModuleToken token) { if (_compilationModuleGroup.ContainsType(field.OwningType)) { // We don't need to store handles within the current compilation group // as we can read them directly from the ECMA objects. return; } switch (token.TokenType) { case CorTokenType.mdtMemberRef: AddModuleTokenForFieldReference(field.OwningType, token); break; default: throw new NotImplementedException(); } }
public void EmitFieldSignature(FieldDesc field, SignatureContext context) { ModuleToken fieldToken = context.GetModuleTokenForField(field); switch (fieldToken.TokenType) { case CorTokenType.mdtMemberRef: EmitUInt((uint)ReadyToRunFieldSigFlags.READYTORUN_FIELD_SIG_MemberRefToken); EmitTokenRid(fieldToken.Token); break; case CorTokenType.mdtFieldDef: EmitUInt((uint)0); EmitTokenRid(fieldToken.Token); break; default: throw new NotImplementedException(); } }
public void EmitFieldSignature(FieldDesc field, SignatureContext context) { uint fieldSigFlags = 0; TypeDesc canonOwnerType = field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific); TypeDesc ownerType = null; if (canonOwnerType.HasInstantiation) { ownerType = field.OwningType; fieldSigFlags |= (uint)ReadyToRunFieldSigFlags.READYTORUN_FIELD_SIG_OwnerType; } if (canonOwnerType != field.OwningType) { // Convert field to canonical form as this is what the field - module token lookup stores field = field.Context.GetFieldForInstantiatedType(field.GetTypicalFieldDefinition(), (InstantiatedType)canonOwnerType); } ModuleToken fieldToken = context.GetModuleTokenForField(field); switch (fieldToken.TokenType) { case CorTokenType.mdtMemberRef: fieldSigFlags |= (uint)ReadyToRunFieldSigFlags.READYTORUN_FIELD_SIG_MemberRefToken; break; case CorTokenType.mdtFieldDef: break; default: throw new NotImplementedException(); } EmitUInt(fieldSigFlags); if (ownerType != null) { EmitTypeSignature(ownerType, context); } EmitTokenRid(fieldToken.Token); }
private void EmitMethodSpecificationSignature(MethodWithToken method, uint flags, bool enforceDefEncoding, SignatureContext context) { ModuleToken methodToken = method.Token; if (method.Method.HasInstantiation) { flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation; if (!method.Token.IsNull) { if (method.Token.TokenType == CorTokenType.mdtMethodSpec) { MethodSpecification methodSpecification = methodToken.MetadataReader.GetMethodSpecification((MethodSpecificationHandle)methodToken.Handle); methodToken = new ModuleToken(methodToken.Module, methodSpecification.Method); } } } 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; } switch (methodToken.TokenType) { case CorTokenType.mdtMethodDef: break; case CorTokenType.mdtMemberRef: flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken; break; default: throw new NotImplementedException(); } EmitUInt(flags); if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0) { EmitTypeSignature(method.Method.OwningType, context); } EmitTokenRid(methodToken.Token); if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0) { Instantiation instantiation = method.Method.Instantiation; EmitUInt((uint)instantiation.Length); SignatureContext outerContext = context.OuterContext; for (int typeParamIndex = 0; typeParamIndex < instantiation.Length; typeParamIndex++) { EmitTypeSignature(instantiation[typeParamIndex], outerContext); } } }
public void EmitMethodRefToken(ModuleToken memberRefToken) { Debug.Assert(memberRefToken.TokenType == CorTokenType.mdtMemberRef); EmitUInt(RidFromToken(memberRefToken.Token)); }
public void EmitMethodDefToken(ModuleToken methodDefToken) { Debug.Assert(methodDefToken.TokenType == CorTokenType.mdtMethodDef); EmitUInt(methodDefToken.TokenRid); }
private void EmitTypeToken(EcmaType type, SignatureContext context) { ModuleToken token = context.GetModuleTokenForType(type); EmitToken(token.Token); }
public void EmitTypeSignature(TypeDesc typeDesc, SignatureContext context) { if (typeDesc is RuntimeDeterminedType runtimeDeterminedType) { switch (runtimeDeterminedType.RuntimeDeterminedDetailsType.Kind) { case GenericParameterKind.Type: EmitElementType(CorElementType.ELEMENT_TYPE_VAR); break; case GenericParameterKind.Method: EmitElementType(CorElementType.ELEMENT_TYPE_MVAR); break; default: throw new NotImplementedException(); } EmitUInt((uint)runtimeDeterminedType.RuntimeDeterminedDetailsType.Index); return; } if (typeDesc.HasInstantiation && !typeDesc.IsGenericDefinition) { EmitInstantiatedTypeSignature((InstantiatedType)typeDesc, context); return; } switch (typeDesc.Category) { case TypeFlags.Array: EmitArrayTypeSignature((ArrayType)typeDesc, context); return; case TypeFlags.SzArray: EmitSzArrayTypeSignature((ArrayType)typeDesc, context); return; case TypeFlags.Pointer: EmitPointerTypeSignature((PointerType)typeDesc, context); return; case TypeFlags.ByRef: EmitByRefTypeSignature((ByRefType)typeDesc, context); break; case TypeFlags.Void: EmitElementType(CorElementType.ELEMENT_TYPE_VOID); return; case TypeFlags.Boolean: EmitElementType(CorElementType.ELEMENT_TYPE_BOOLEAN); return; case TypeFlags.Char: EmitElementType(CorElementType.ELEMENT_TYPE_CHAR); return; case TypeFlags.SByte: EmitElementType(CorElementType.ELEMENT_TYPE_I1); return; case TypeFlags.Byte: EmitElementType(CorElementType.ELEMENT_TYPE_U1); return; case TypeFlags.Int16: EmitElementType(CorElementType.ELEMENT_TYPE_I2); return; case TypeFlags.UInt16: EmitElementType(CorElementType.ELEMENT_TYPE_U2); return; case TypeFlags.Int32: EmitElementType(CorElementType.ELEMENT_TYPE_I4); return; case TypeFlags.UInt32: EmitElementType(CorElementType.ELEMENT_TYPE_U4); return; case TypeFlags.Int64: EmitElementType(CorElementType.ELEMENT_TYPE_I8); return; case TypeFlags.UInt64: EmitElementType(CorElementType.ELEMENT_TYPE_U8); return; case TypeFlags.IntPtr: EmitElementType(CorElementType.ELEMENT_TYPE_I); return; case TypeFlags.UIntPtr: EmitElementType(CorElementType.ELEMENT_TYPE_U); return; case TypeFlags.Single: EmitElementType(CorElementType.ELEMENT_TYPE_R4); return; case TypeFlags.Double: EmitElementType(CorElementType.ELEMENT_TYPE_R8); return; case TypeFlags.Interface: case TypeFlags.Class: if (typeDesc.IsString) { EmitElementType(CorElementType.ELEMENT_TYPE_STRING); } else if (typeDesc.IsObject) { EmitElementType(CorElementType.ELEMENT_TYPE_OBJECT); } else if (typeDesc.IsCanonicalDefinitionType(CanonicalFormKind.Specific)) { EmitElementType(CorElementType.ELEMENT_TYPE_CANON_ZAPSIG); } else { ModuleToken token = context.GetModuleTokenForType((EcmaType)typeDesc); EmitModuleOverride(token.Module, context); EmitElementType(CorElementType.ELEMENT_TYPE_CLASS); EmitToken(token.Token); } return; case TypeFlags.ValueType: case TypeFlags.Nullable: case TypeFlags.Enum: if (typeDesc.IsWellKnownType(WellKnownType.TypedReference)) { EmitElementType(CorElementType.ELEMENT_TYPE_TYPEDBYREF); return; } { ModuleToken token = context.GetModuleTokenForType((EcmaType)typeDesc); EmitModuleOverride(token.Module, context); EmitElementType(CorElementType.ELEMENT_TYPE_VALUETYPE); EmitToken(token.Token); return; } default: throw new NotImplementedException(); } }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, Array.Empty <ISymbolDefinitionNode>())); } ReadyToRunCodegenNodeFactory r2rFactory = (ReadyToRunCodegenNodeFactory)factory; NativeWriter hashtableWriter = new NativeWriter(); Section hashtableSection = hashtableWriter.NewSection(); VertexHashtable vertexHashtable = new VertexHashtable(); hashtableSection.Place(vertexHashtable); Dictionary <byte[], BlobVertex> uniqueFixups = new Dictionary <byte[], BlobVertex>(ByteArrayComparer.Instance); Dictionary <byte[], BlobVertex> uniqueSignatures = new Dictionary <byte[], BlobVertex>(ByteArrayComparer.Instance); foreach (MethodWithGCInfo method in r2rFactory.EnumerateCompiledMethods()) { if (method.Method.HasInstantiation || method.Method.OwningType.HasInstantiation) { int methodIndex = r2rFactory.RuntimeFunctionsTable.GetIndex(method); bool enforceOwningType = false; ModuleToken moduleToken = method.SignatureContext.GetModuleTokenForMethod(method.Method.GetTypicalMethodDefinition()); if (moduleToken.Module != r2rFactory.InputModuleContext.GlobalContext) { enforceOwningType = true; } ArraySignatureBuilder signatureBuilder = new ArraySignatureBuilder(); signatureBuilder.EmitMethodSignature( new MethodWithToken(method.Method, moduleToken, constrainedType: null), enforceDefEncoding: true, enforceOwningType, method.SignatureContext, isUnboxingStub: false, isInstantiatingStub: false); byte[] signature = signatureBuilder.ToArray(); BlobVertex signatureBlob; if (!uniqueSignatures.TryGetValue(signature, out signatureBlob)) { signatureBlob = new BlobVertex(signature); hashtableSection.Place(signatureBlob); uniqueSignatures.Add(signature, signatureBlob); } byte[] fixup = method.GetFixupBlob(factory); BlobVertex fixupBlob = null; if (fixup != null && !uniqueFixups.TryGetValue(fixup, out fixupBlob)) { fixupBlob = new BlobVertex(fixup); hashtableSection.Place(fixupBlob); uniqueFixups.Add(fixup, fixupBlob); } EntryPointVertex entryPointVertex = new EntryPointWithBlobVertex((uint)methodIndex, fixupBlob, signatureBlob); hashtableSection.Place(entryPointVertex); vertexHashtable.Append(unchecked ((uint)ReadyToRunHashCode.MethodHashCode(method.Method)), entryPointVertex); } } MemoryStream hashtableContent = new MemoryStream(); hashtableWriter.Save(hashtableContent); return(new ObjectData( data: hashtableContent.ToArray(), relocs: null, alignment: 8, definedSymbols: new ISymbolDefinitionNode[] { this })); }
public StringImport(ImportSectionNode table, ModuleToken token, SignatureContext signatureContext) : base(table, new StringImportSignature(token, signatureContext)) { _token = token; }
public void EmitMethodSignature( MethodDesc method, TypeDesc constrainedType, ModuleToken methodToken, bool enforceDefEncoding, SignatureContext context, bool isUnboxingStub, bool isInstantiatingStub) { uint flags = 0; if (isUnboxingStub) { flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_UnboxingStub; } if (isInstantiatingStub) { flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub; } if (constrainedType != null) { flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained; } if ((method.HasInstantiation || method.OwningType.HasInstantiation) && !method.IsGenericMethodDefinition) { EmitMethodSpecificationSignature(method, methodToken, flags, enforceDefEncoding, context); } else { if (methodToken.IsNull) { methodToken = context.GetModuleTokenForMethod(method); } switch (methodToken.TokenType) { case CorTokenType.mdtMethodDef: // TODO: module override for methoddefs with external module context EmitUInt(flags); EmitMethodDefToken(methodToken); break; case CorTokenType.mdtMemberRef: { // TODO: module override for methodrefs with external module context flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken; MemberReference memberRef = methodToken.MetadataReader.GetMemberReference((MemberReferenceHandle)methodToken.Handle); if (methodToken.Module.GetObject(memberRef.Parent) != (object)method.OwningType) { // We have a memberref token for a different type - encode owning type explicitly in the signature flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType; } EmitUInt(flags); if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0) { EmitTypeSignature(method.OwningType, context); } EmitMethodRefToken(methodToken); } break; default: throw new NotImplementedException(); } } if (constrainedType != null) { EmitTypeSignature(constrainedType, context); } }
public StringImport(ImportSectionNode table, ModuleToken token) : base(table, new StringImportSignature(token)) { _token = token; }
// Add TypeSystemEntity -> ModuleToken mapping to a ConcurrentDictionary. Using CompareTo sort the token used, so it will // be consistent in all runs of the compiler void SetModuleTokenForTypeSystemEntity <T>(ConcurrentDictionary <T, ModuleToken> dictionary, T tse, ModuleToken token) { if (!dictionary.TryAdd(tse, token)) { ModuleToken oldToken; do { // We will reach here, if the field already has a token if (!dictionary.TryGetValue(tse, out oldToken)) { throw new InternalCompilerErrorException("TypeSystemEntity both present and not present in emission dictionary."); } if (oldToken.CompareTo(token) <= 0) { break; } } while (dictionary.TryUpdate(tse, token, oldToken)); } }
public StringImportSignature(ModuleToken token, SignatureContext signatureContext) { _token = token; _signatureContext = signatureContext; }