Exemplo n.º 1
0
 // Add a range of local variables to a local signature encoder
 internal static void AddRange(this LocalVariablesEncoder sig, IEnumerable <LocalVariableInfo> localVariables, IAssemblyMetadata metadata)
 {
     foreach (var v in localVariables)
     {
         Add(sig, v, metadata);
     }
 }
Exemplo n.º 2
0
 // Add a local variable to a local variable signature encoder
 internal static void Add(this LocalVariablesEncoder sig, LocalVariableInfo localVariableInfo, IAssemblyMetadata metadata)
 {
     if (localVariableInfo.LocalType.IsByRef)
     {
         sig.AddVariable().Type(
             true,
             localVariableInfo.IsPinned)
         .FromSystemType(localVariableInfo.LocalType.GetElementType(), metadata);
     }
     else
     {
         sig.AddVariable().Type(
             false,
             localVariableInfo.IsPinned)
         .FromSystemType(localVariableInfo.LocalType, metadata);
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// Extracts the method signature from the metadata by rid
        /// </summary>
        public ReadyToRunMethod(
            ReadyToRunReader readyToRunReader,
            IAssemblyMetadata componentReader,
            EntityHandle methodHandle,
            int entryPointId,
            string owningType,
            string constrainedType,
            string[] instanceArgs,
            int?fixupOffset)
        {
            InstanceArgs                = (string[])instanceArgs?.Clone();
            _readyToRunReader           = readyToRunReader;
            _fixupOffset                = fixupOffset;
            MethodHandle                = methodHandle;
            EntryPointRuntimeFunctionId = entryPointId;

            ComponentReader = componentReader;

            EntityHandle owningTypeHandle;
            GenericParameterHandleCollection genericParams = default(GenericParameterHandleCollection);

            DisassemblingGenericContext genericContext = new DisassemblingGenericContext(typeParameters: Array.Empty <string>(), methodParameters: instanceArgs);
            DisassemblingTypeProvider   typeProvider   = new DisassemblingTypeProvider();

            // get the method signature from the method handle
            switch (MethodHandle.Kind)
            {
            case HandleKind.MethodDefinition:
            {
                MethodDefinition methodDef = ComponentReader.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle);
                if (methodDef.RelativeVirtualAddress != 0)
                {
                    MethodBodyBlock mbb = ComponentReader.ImageReader.GetMethodBody(methodDef.RelativeVirtualAddress);
                    if (!mbb.LocalSignature.IsNil)
                    {
                        StandaloneSignature ss = ComponentReader.MetadataReader.GetStandaloneSignature(mbb.LocalSignature);
                        LocalSignature = ss.DecodeLocalSignature(typeProvider, genericContext);
                    }
                }
                Name             = ComponentReader.MetadataReader.GetString(methodDef.Name);
                Signature        = methodDef.DecodeSignature <string, DisassemblingGenericContext>(typeProvider, genericContext);
                owningTypeHandle = methodDef.GetDeclaringType();
                genericParams    = methodDef.GetGenericParameters();
            }
            break;

            case HandleKind.MemberReference:
            {
                MemberReference memberRef = ComponentReader.MetadataReader.GetMemberReference((MemberReferenceHandle)MethodHandle);
                Name             = ComponentReader.MetadataReader.GetString(memberRef.Name);
                Signature        = memberRef.DecodeMethodSignature <string, DisassemblingGenericContext>(typeProvider, genericContext);
                owningTypeHandle = memberRef.Parent;
            }
            break;

            default:
                throw new NotImplementedException();
            }

            if (owningType != null)
            {
                DeclaringType = owningType;
            }
            else
            {
                DeclaringType = MetadataNameFormatter.FormatHandle(ComponentReader.MetadataReader, owningTypeHandle);
            }

            StringBuilder sb = new StringBuilder();

            sb.Append(Signature.ReturnType);
            sb.Append(" ");
            sb.Append(DeclaringType);
            sb.Append(".");
            sb.Append(Name);

            if (Signature.GenericParameterCount != 0)
            {
                sb.Append("<");
                for (int i = 0; i < Signature.GenericParameterCount; i++)
                {
                    if (i > 0)
                    {
                        sb.Append(", ");
                    }
                    if (instanceArgs != null && instanceArgs.Length > i)
                    {
                        sb.Append(instanceArgs[i]);
                    }
                    else
                    {
                        sb.Append("!");
                        sb.Append(i);
                    }
                }
                sb.Append(">");
            }

            sb.Append("(");
            for (int i = 0; i < Signature.ParameterTypes.Length; i++)
            {
                if (i > 0)
                {
                    sb.Append(", ");
                }
                sb.AppendFormat($"{Signature.ParameterTypes[i]}");
            }
            sb.Append(")");

            SignatureString = sb.ToString();
        }
Exemplo n.º 4
0
        internal static void FromSystemType(this SignatureTypeEncoder typeEncoder, Type type,
                                            IAssemblyMetadata metadata)
        {
            if (type.IsByRef)
            {
                throw new ArgumentException("ByRef types should be handled by parameter encoder or return type encoder");
            }
            else if (type.IsPointer)
            {
                typeEncoder.Pointer().FromSystemType(type.GetElementType(), metadata);
            }
            else if (type.IsPrimitive)
            {
                typeEncoder.PrimitiveType(GetPrimitiveTypeCode(type));
            }
            else if (type == typeof(string))
            {
                typeEncoder.String();
            }
            else if (type == typeof(object))
            {
                typeEncoder.Object();
            }
            else if (type == typeof(void))
            {
                throw new ArgumentException(
                          "Void type is not allowed in SignatureTypeEncoder. Please, use FromSystemType from ReturnTypeEncoder.",
                          nameof(type));
            }
            else if (type.IsArray)
            {
                var elementType = type.GetElementType();

                if (type.GetArrayRank() == 1)
                {
                    typeEncoder.SZArray().FromSystemType(elementType, metadata);
                }
                else
                {
                    typeEncoder.Array(
                        x => x.FromSystemType(elementType, metadata),
                        x => x.Shape(
                            type.GetArrayRank(),
                            ImmutableArray.Create <int>(),
                            ImmutableArray.CreateRange <int>(Enumerable.Repeat(0, type.GetArrayRank())) // better matches metadata from C#
                            ));
                }
            }
            else if (type.IsGenericType)
            {
                var genericTypeDef   = type.GetGenericTypeDefinition();
                var typeHandler      = metadata.GetTypeHandle(genericTypeDef);
                var genericArguments = type.GetGenericArguments();

                var inst = typeEncoder.GenericInstantiation(typeHandler, genericArguments.Length, type.IsValueType);
                foreach (var ga in genericArguments)
                {
                    if (ga.IsGenericMethodParameter())
                    {
                        inst.AddArgument().GenericMethodTypeParameter(ga.GenericParameterPosition);
                    }
                    else if (ga.IsGenericParameter)
                    {
                        inst.AddArgument().GenericTypeParameter(ga.GenericParameterPosition);
                    }
                    else
                    {
                        inst.AddArgument().FromSystemType(ga, metadata);
                    }
                }
            }
            else if (type.IsGenericMethodParameter())
            {
                typeEncoder.GenericMethodTypeParameter(type.GenericParameterPosition);
            }
            else if (type.IsGenericParameter)
            {
                typeEncoder.GenericTypeParameter(type.GenericParameterPosition);
            }
            else
            {
                var typeHandler = metadata.GetTypeHandle(type);
                typeEncoder.Type(typeHandler, type.IsValueType);
            }
        }
Exemplo n.º 5
0
 public MethodBodyStreamWriter(IAssemblyMetadata metadata)
 {
     _metadata = metadata;
 }
Exemplo n.º 6
0
        public PgoInfoKey(IAssemblyMetadata componentReader, string owningType, EntityHandle methodHandle, string[] instanceArgs)
        {
            ComponentReader = componentReader;
            EntityHandle owningTypeHandle;
            DisassemblingGenericContext genericContext = new DisassemblingGenericContext(typeParameters: Array.Empty <string>(), methodParameters: instanceArgs);
            DisassemblingTypeProvider   typeProvider   = new DisassemblingTypeProvider();

            MethodHandle = methodHandle;

            // get the method signature from the method handle
            switch (MethodHandle.Kind)
            {
            case HandleKind.MethodDefinition:
            {
                MethodDefinition methodDef = componentReader.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle);
                Name             = componentReader.MetadataReader.GetString(methodDef.Name);
                Signature        = methodDef.DecodeSignature <string, DisassemblingGenericContext>(typeProvider, genericContext);
                owningTypeHandle = methodDef.GetDeclaringType();
            }
            break;

            case HandleKind.MemberReference:
            {
                MemberReference memberRef = componentReader.MetadataReader.GetMemberReference((MemberReferenceHandle)MethodHandle);
                Name             = componentReader.MetadataReader.GetString(memberRef.Name);
                Signature        = memberRef.DecodeMethodSignature <string, DisassemblingGenericContext>(typeProvider, genericContext);
                owningTypeHandle = memberRef.Parent;
            }
            break;

            default:
                throw new NotImplementedException();
            }

            if (owningType != null)
            {
                DeclaringType = owningType;
            }
            else
            {
                DeclaringType = MetadataNameFormatter.FormatHandle(componentReader.MetadataReader, owningTypeHandle);
            }

            StringBuilder sb = new StringBuilder();

            sb.Append(Signature.ReturnType);
            sb.Append(" ");
            sb.Append(DeclaringType);
            sb.Append(".");
            sb.Append(Name);

            if (Signature.GenericParameterCount != 0)
            {
                sb.Append("<");
                for (int i = 0; i < Signature.GenericParameterCount; i++)
                {
                    if (i > 0)
                    {
                        sb.Append(", ");
                    }
                    if (instanceArgs != null && instanceArgs.Length > i)
                    {
                        sb.Append(instanceArgs[i]);
                    }
                    else
                    {
                        sb.Append("!");
                        sb.Append(i);
                    }
                }
                sb.Append(">");
            }

            sb.Append("(");
            for (int i = 0; i < Signature.ParameterTypes.Length; i++)
            {
                if (i > 0)
                {
                    sb.Append(", ");
                }
                sb.AppendFormat($"{Signature.ParameterTypes[i]}");
            }
            sb.Append(")");

            SignatureString = sb.ToString();
        }
Exemplo n.º 7
0
        public static void Write(IAssemblyMetadata metadata, IReadOnlyList <Instruction> il)
        {
            for (var i = 0; i < il.Count; i++)
            {
                var opCode = il[i].OpCode;

                opCode.WriteOpCode(metadata.ILBuilder.WriteByte);

                switch (opCode.OperandType)
                {
                case OperandType.InlineNone:
                    break;

                case OperandType.InlineSwitch:
                    var branches = (int[])il[i].Operand;
                    metadata.ILBuilder.WriteInt32(branches.Length);
                    for (var k = 0; k < branches.Length; k++)
                    {
                        var branchOffset = branches[k];
                        metadata.ILBuilder.WriteInt32(branchOffset);
                    }

                    break;

                case OperandType.ShortInlineBrTarget:
                    var offset8 = (sbyte)il[i].Operand;
                    metadata.ILBuilder.WriteSByte(offset8);
                    break;

                case OperandType.InlineBrTarget:
                    var offset32 = (int)il[i].Operand;
                    // offset convention in IL: zero is at next instruction
                    metadata.ILBuilder.WriteInt32(offset32);
                    break;

                case OperandType.ShortInlineI:
                    if (opCode == OpCodes.Ldc_I4_S)
                    {
                        metadata.ILBuilder.WriteSByte((sbyte)il[i].Operand);
                    }
                    else
                    {
                        metadata.ILBuilder.WriteByte((byte)il[i].Operand);
                    }

                    break;

                case OperandType.InlineI:
                    metadata.ILBuilder.WriteInt32((int)il[i].Operand);
                    break;

                case OperandType.ShortInlineR:
                    metadata.ILBuilder.WriteSingle((float)il[i].Operand);
                    break;

                case OperandType.InlineR:
                    metadata.ILBuilder.WriteDouble((double)il[i].Operand);
                    break;

                case OperandType.InlineI8:
                    metadata.ILBuilder.WriteInt64((long)il[i].Operand);
                    break;

                case OperandType.InlineSig:
                    metadata.ILBuilder.WriteBytes((byte[])il[i].Operand);
                    break;

                case OperandType.InlineString:
                    metadata.ILBuilder.WriteInt32(
                        MetadataTokens.GetToken(metadata.GetOrAddUserString((string)il[i].Operand)));
                    break;

                case OperandType.InlineType:
                case OperandType.InlineTok:
                case OperandType.InlineMethod:
                case OperandType.InlineField:
                    switch (il[i].Operand)
                    {
                    case Type type:
                        metadata.ILBuilder.WriteInt32(MetadataTokens.GetToken(metadata.GetTypeHandle(type)));
                        break;

                    case ConstructorInfo constructorInfo:
                        metadata.ILBuilder.WriteInt32(
                            MetadataTokens.GetToken(metadata.GetConstructorHandle(constructorInfo)));
                        break;

                    case FieldInfo fieldInfo:
                        metadata.ILBuilder.WriteInt32(
                            MetadataTokens.GetToken(metadata.GetFieldHandle(fieldInfo)));
                        break;

                    case MethodInfo methodInfo:
                        metadata.ILBuilder.WriteInt32(
                            MetadataTokens.GetToken(metadata.GetMethodHandle(methodInfo)));
                        break;

                    default:
                        throw new NotSupportedException($"Unsupported inline operand: {il[i].Operand}");
                    }

                    break;

                case OperandType.ShortInlineVar:
                    var bLocalVariableInfo = il[i].Operand as LocalVariableInfo;
                    var bParameterInfo     = il[i].Operand as ParameterInfo;

                    if (bLocalVariableInfo != null)
                    {
                        metadata.ILBuilder.WriteByte((byte)bLocalVariableInfo.LocalIndex);
                    }
                    else if (bParameterInfo != null)
                    {
                        metadata.ILBuilder.WriteByte((byte)bParameterInfo.Position);
                    }
                    else
                    {
                        throw new NotSupportedException($"Unsupported short inline variable: {il[i].Operand}");
                    }

                    break;

                case OperandType.InlineVar:
                    var sLocalVariableInfo = il[i].Operand as LocalVariableInfo;
                    var sParameterInfo     = il[i].Operand as ParameterInfo;

                    if (sLocalVariableInfo != null)
                    {
                        metadata.ILBuilder.WriteUInt16((ushort)sLocalVariableInfo.LocalIndex);
                    }
                    else if (sParameterInfo != null)
                    {
                        metadata.ILBuilder.WriteUInt16((ushort)sParameterInfo.Position);
                    }
                    else
                    {
                        throw new NotSupportedException($"Unsupported inline variable: {il[i].Operand}");
                    }

                    break;

                default:
                    throw new NotSupportedException($"Unsupported operand type: {opCode.OperandType}");
                }
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Parse a single available types section. For composite R2R images this method is called multiple times
        /// as available types are stored separately for each component assembly of the composite R2R executable.
        /// </summary>
        /// <param name="availableTypesSection"></param>
        private void ParseAvailableTypesSection(int assemblyIndex, ReadyToRunSection availableTypesSection, IAssemblyMetadata metadataReader)
        {
            _readyToRunAssemblies[assemblyIndex]._availableTypes = new List <string>();
            int             availableTypesOffset = GetOffset(availableTypesSection.RelativeVirtualAddress);
            NativeParser    parser         = new NativeParser(Image, (uint)availableTypesOffset);
            NativeHashtable availableTypes = new NativeHashtable(Image, parser, (uint)(availableTypesOffset + availableTypesSection.Size));

            NativeHashtable.AllEntriesEnumerator allEntriesEnum = availableTypes.EnumerateAllEntries();
            NativeParser curParser = allEntriesEnum.GetNext();

            while (!curParser.IsNull())
            {
                uint rid = curParser.GetUnsigned();

                bool isExportedType = (rid & 1) != 0;
                rid = rid >> 1;

                if (isExportedType)
                {
                    ExportedTypeHandle exportedTypeHandle = MetadataTokens.ExportedTypeHandle((int)rid);
                    string             exportedTypeName   = GetExportedTypeFullName(metadataReader.MetadataReader, exportedTypeHandle);

                    _readyToRunAssemblies[assemblyIndex]._availableTypes.Add("exported " + exportedTypeName);
                }
                else
                {
                    TypeDefinitionHandle typeDefHandle = MetadataTokens.TypeDefinitionHandle((int)rid);
                    string typeDefName = MetadataNameFormatter.FormatHandle(metadataReader.MetadataReader, typeDefHandle);
                    _readyToRunAssemblies[assemblyIndex]._availableTypes.Add(typeDefName);
                }

                curParser = allEntriesEnum.GetNext();
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Initialize generic method instances with argument types and runtime function indices from InstanceMethodEntrypoints
        /// </summary>
        private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint)
        {
            if (!ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.InstanceMethodEntryPoints, out ReadyToRunSection instMethodEntryPointSection))
            {
                return;
            }
            int             instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress);
            NativeParser    parser = new NativeParser(Image, (uint)instMethodEntryPointsOffset);
            NativeHashtable instMethodEntryPoints = new NativeHashtable(Image, parser, (uint)(instMethodEntryPointsOffset + instMethodEntryPointSection.Size));

            NativeHashtable.AllEntriesEnumerator allEntriesEnum = instMethodEntryPoints.EnumerateAllEntries();
            NativeParser curParser = allEntriesEnum.GetNext();

            while (!curParser.IsNull())
            {
                IAssemblyMetadata          mdReader     = GetGlobalMetadata();
                SignatureFormattingOptions dummyOptions = new SignatureFormattingOptions();
                SignatureDecoder           decoder      = new SignatureDecoder(_assemblyResolver, dummyOptions, mdReader?.MetadataReader, this, (int)curParser.Offset);

                string owningType = null;

                uint methodFlags = decoder.ReadUInt();
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
                {
                    mdReader = decoder.GetMetadataReaderFromModuleOverride() ?? mdReader;
                    if ((_composite) && mdReader == null)
                    {
                        // The only types that don't have module overrides on them in composite images are primitive types within the system module
                        mdReader = GetSystemModuleMetadataReader();
                    }
                    owningType = decoder.ReadTypeSignatureNoEmit();
                }
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_SlotInsteadOfToken) != 0)
                {
                    throw new NotImplementedException();
                }
                EntityHandle methodHandle;
                int          rid = (int)decoder.ReadUInt();
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MemberRefToken) != 0)
                {
                    methodHandle = MetadataTokens.MemberReferenceHandle(rid);
                }
                else
                {
                    methodHandle = MetadataTokens.MethodDefinitionHandle(rid);
                }
                string[] methodTypeArgs = null;
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0)
                {
                    uint typeArgCount = decoder.ReadUInt();
                    methodTypeArgs = new string[typeArgCount];
                    for (int typeArgIndex = 0; typeArgIndex < typeArgCount; typeArgIndex++)
                    {
                        methodTypeArgs[typeArgIndex] = decoder.ReadTypeSignatureNoEmit();
                    }
                }

                string constrainedType = null;
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained) != 0)
                {
                    constrainedType = decoder.ReadTypeSignatureNoEmit();
                }

                int runtimeFunctionId;
                int?fixupOffset;
                GetRuntimeFunctionIndexFromOffset((int)decoder.Offset, out runtimeFunctionId, out fixupOffset);
                ReadyToRunMethod method = new ReadyToRunMethod(
                    this,
                    mdReader,
                    methodHandle,
                    runtimeFunctionId,
                    owningType,
                    constrainedType,
                    methodTypeArgs,
                    fixupOffset);
                if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < isEntryPoint.Length)
                {
                    isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                }
                _instanceMethods.Add(new InstanceMethod(curParser.LowHashcode, method));
                curParser = allEntriesEnum.GetNext();
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Parse a single method def entrypoint section. For composite R2R images, this method is called multiple times
        /// are method entrypoints are stored separately for each component assembly of the composite R2R executable.
        /// </summary>
        /// <param name="section">Method entrypoint section to parse</param>
        /// <param name="metadataReader">ECMA metadata reader representing this method entrypoint section</param>
        /// <param name="isEntryPoint">Set to true for each runtime function index representing a method entrypoint</param>
        private void ParseMethodDefEntrypointsSectionCustom <TType, TMethod, TGenericContext>(IR2RSignatureTypeProvider <TType, TMethod, TGenericContext> provider, Dictionary <TMethod, ReadyToRunMethod> foundMethods, ReadyToRunSection section, IAssemblyMetadata metadataReader)
        {
            int         methodDefEntryPointsOffset = GetOffset(section.RelativeVirtualAddress);
            NativeArray methodEntryPoints          = new NativeArray(Image, (uint)methodDefEntryPointsOffset);
            uint        nMethodEntryPoints         = methodEntryPoints.GetCount();

            for (uint rid = 1; rid <= nMethodEntryPoints; rid++)
            {
                int offset = 0;
                if (methodEntryPoints.TryGetAt(Image, rid - 1, ref offset))
                {
                    EntityHandle methodHandle = MetadataTokens.MethodDefinitionHandle((int)rid);
                    int          runtimeFunctionId;
                    int?         fixupOffset;
                    GetRuntimeFunctionIndexFromOffset(offset, out runtimeFunctionId, out fixupOffset);
                    ReadyToRunMethod r2rMethod = _runtimeFunctionToMethod[runtimeFunctionId];
                    var customMethod           = provider.GetMethodFromMethodDef(metadataReader.MetadataReader, MetadataTokens.MethodDefinitionHandle((int)rid), default(TType));

                    if (!Object.ReferenceEquals(customMethod, null) && !foundMethods.ContainsKey(customMethod))
                    {
                        foundMethods.Add(customMethod, r2rMethod);
                    }
                }
            }
        }
Exemplo n.º 11
0
        internal static void FromSystemType(this SignatureTypeEncoder typeEncoder, Type type,
                                            IAssemblyMetadata metadata)
        {
            if (type.IsByRef && type.GetElementType().IsPrimitive)
            {
                typeEncoder.PrimitiveType(GetPrimitiveTypeCode(type.GetElementType()));
            }
            else if (type.IsPrimitive)
            {
                typeEncoder.PrimitiveType(GetPrimitiveTypeCode(type));
            }
            else if (type == typeof(string))
            {
                typeEncoder.String();
            }
            else if (type == typeof(object))
            {
                typeEncoder.Object();
            }
            else if (type == typeof(void))
            {
                throw new ArgumentException(
                          "Void type is not allowed in SignatureTypeEncoder. Please, use FromSystemType from ReturnTypeEncoder.",
                          nameof(type));
            }
            else if (type.IsArray)
            {
                var elementType = type.GetElementType();

                typeEncoder.Array(
                    x => x.FromSystemType(elementType, metadata),
                    x => x.Shape(
                        type.GetArrayRank(),
                        ImmutableArray.Create <int>(),
                        ImmutableArray.Create <int>()));
            }
            else if (type.IsGenericType)
            {
                var genericTypeDef   = type.GetGenericTypeDefinition();
                var typeHandler      = metadata.GetTypeHandle(genericTypeDef);
                var genericArguments = type.GetGenericArguments();

                var inst = typeEncoder.GenericInstantiation(typeHandler, genericArguments.Length, false);
                foreach (var ga in genericArguments)
                {
                    if (ga.IsGenericParameter)
                    {
                        inst.AddArgument().GenericTypeParameter(ga.GenericParameterPosition);
                    }
                    else
                    {
                        inst.AddArgument().FromSystemType(ga, metadata);
                    }
                }
            }
            else
            {
                var typeHandler = metadata.GetTypeHandle(type);
                typeEncoder.Type(typeHandler, type.IsValueType);
            }
        }