Beispiel #1
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);
            }
        }
Beispiel #2
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);
                }
            }
        }
Beispiel #3
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);
            }
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                // Method fixup signature doesn't contain any direct relocs
                return(new ObjectData(data: Array.Empty <byte>(), relocs: null, alignment: 0, definedSymbols: null));
            }

            ObjectDataSignatureBuilder dataBuilder = new ObjectDataSignatureBuilder();

            dataBuilder.AddSymbol(this);

            // Optimize some of the fixups into a more compact form
            ReadyToRunFixupKind fixupKind = _fixupKind;
            bool optimized = false;

            if (!_isUnboxingStub && !_isInstantiatingStub && _method.ConstrainedType == null &&
                fixupKind == ReadyToRunFixupKind.MethodEntry)
            {
                if (!_method.Method.OwningType.HasInstantiation && !_method.Method.OwningType.IsArray)
                {
                    if (_method.Token.TokenType == CorTokenType.mdtMethodDef)
                    {
                        fixupKind = ReadyToRunFixupKind.MethodEntry_DefToken;
                        optimized = true;
                    }
                    else if (_method.Token.TokenType == CorTokenType.mdtMemberRef)
                    {
                        fixupKind = ReadyToRunFixupKind.MethodEntry_RefToken;
                        optimized = true;
                    }
                }
            }

            MethodWithToken method = _method;

            if (factory.CompilationModuleGroup.VersionsWithMethodBody(method.Method))
            {
                if (method.Token.TokenType == CorTokenType.mdtMethodSpec)
                {
                    method = new MethodWithToken(method.Method, _signatureContext.GetModuleTokenForMethod(method.Method, throwIfNotFound: false), method.ConstrainedType);
                }
                else if (!optimized && (method.Token.TokenType == CorTokenType.mdtMemberRef))
                {
                    if (method.Method.OwningType.GetTypeDefinition() is EcmaType)
                    {
                        method = new MethodWithToken(method.Method, _signatureContext.GetModuleTokenForMethod(method.Method, throwIfNotFound: false), method.ConstrainedType);
                    }
                }
            }

            SignatureContext innerContext = dataBuilder.EmitFixup(factory, fixupKind, method.Token.Module, _signatureContext);

            if (optimized && method.Token.TokenType == CorTokenType.mdtMethodDef)
            {
                dataBuilder.EmitMethodDefToken(method.Token);
            }
            else if (optimized && method.Token.TokenType == CorTokenType.mdtMemberRef)
            {
                dataBuilder.EmitMethodRefToken(method.Token);
            }
            else
            {
                dataBuilder.EmitMethodSignature(method, enforceDefEncoding: false, enforceOwningType: false, innerContext, _isUnboxingStub, _isInstantiatingStub);
            }

            return(dataBuilder.ToObjectData());
        }