Exemple #1
0
        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());
        }
Exemple #4
0
        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());
            }
        }
Exemple #6
0
 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;
 }
Exemple #7
0
        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);
                }
            }
        }
Exemple #12
0
        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);
            }
Exemple #16
0
        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);
        }
Exemple #17
0
        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();
            }
        }
Exemple #18
0
        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();
            }
        }
Exemple #19
0
        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);
        }
Exemple #20
0
        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);
                }
            }
        }
Exemple #21
0
 public void EmitMethodRefToken(ModuleToken memberRefToken)
 {
     Debug.Assert(memberRefToken.TokenType == CorTokenType.mdtMemberRef);
     EmitUInt(RidFromToken(memberRefToken.Token));
 }
Exemple #22
0
 public void EmitMethodDefToken(ModuleToken methodDefToken)
 {
     Debug.Assert(methodDefToken.TokenType == CorTokenType.mdtMethodDef);
     EmitUInt(methodDefToken.TokenRid);
 }
Exemple #23
0
        private void EmitTypeToken(EcmaType type, SignatureContext context)
        {
            ModuleToken token = context.GetModuleTokenForType(type);

            EmitToken(token.Token);
        }
Exemple #24
0
        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();
            }
        }
Exemple #25
0
        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 }));
        }
Exemple #26
0
 public StringImport(ImportSectionNode table, ModuleToken token, SignatureContext signatureContext)
     : base(table, new StringImportSignature(token, signatureContext))
 {
     _token = token;
 }
Exemple #27
0
        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);
            }
        }
Exemple #28
0
 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;
 }