Exemplo n.º 1
0
        private void SerializeExceptionRegions(MethodBody body)
        {
            // Get exception clauses, quit if none
            var clauses = body.ExceptionHandlingClauses;

            if (clauses.Count == 0)
            {
                return;
            }

            // Can we use a small exception table?
            var useSmallTable = HasSmallExceptionRegions(body.ExceptionHandlingClauses);

            // Align to 4 byte boundary
            var exre = ExceptionRegionEncoder.SerializeTableHeader(_metadata.ILBuilder, clauses.Count, useSmallTable);

            foreach (var ex in body.ExceptionHandlingClauses)
            {
                exre.Add((ExceptionRegionKind)ex.Flags, ex.TryOffset, ex.TryLength, ex.HandlerOffset, ex.HandlerLength,
                         ex.Flags == ExceptionHandlingClauseOptions.Clause ? _metadata.GetTypeHandle(ex.CatchType) : default(EntityHandle),
                         ex.Flags == ExceptionHandlingClauseOptions.Filter ? ex.FilterOffset : 0);
            }
        }
Exemplo n.º 2
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.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.º 3
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.º 4
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);
            }
        }