예제 #1
0
        public override bool VisitInstructionExpression(CilInstructionExpression expression)
        {
            if (expression.Instructions.Count == 1 &&
                expression.Instructions[0].OpCode.Code == CilCode.Unbox_Any &&
                IsBoxExpression(expression.Arguments[0], out var argument, out var boxedType) &&
                expression.Instructions[0].Operand is ITypeDefOrRef type &&
                type.FullName == boxedType.FullName)
            {
                argument.ExpectedType = expression.ExpectedType;
                expression.ReplaceWith(argument.Remove());
            }

            return(base.VisitInstructionExpression(expression));
        }
예제 #2
0
        private void ReplaceWithLdlen(CilInstructionExpression expression, SzArrayTypeSignature arrayType)
        {
            var arrayExpr = expression.Arguments[0];

            arrayExpr.ExpectedType = arrayType;

            var arrayLengthExpr = new CilInstructionExpression(CilOpCodes.Ldlen, null,
                                                               (CilExpression)arrayExpr.Remove())
            {
                ExpressionType = _context.TargetModule.CorLibTypeFactory.Int32
            };

            expression.ReplaceWith(arrayLengthExpr);
        }
예제 #3
0
        private void ReplaceWithLdlen(CilInstructionExpression expression, SzArrayTypeSignature arrayType)
        {
            var arrayExpr = expression.Arguments[0];

            arrayExpr.ExpectedType = arrayType;

            var arrayLoadExpr = new CilInstructionExpression(CilOpCodes.Ldlen, null,
                                                             (CilExpression)arrayExpr.Remove())
            {
                ExpressionType = arrayType.BaseType
            };

            expression.ReplaceWith(arrayLoadExpr);
        }
예제 #4
0
        private void ReplaceWithLdelema(CilInstructionExpression expression, SzArrayTypeSignature arrayType)
        {
            var arrayExpr = expression.Arguments[0];
            var indexExpr = expression.Arguments[1];

            arrayExpr.ExpectedType = arrayType;
            var elementTypeRef = _context.ReferenceImporter
                                 .ImportType(arrayType.BaseType.ToTypeDefOrRef());

            var arrayLoadExpr = new CilInstructionExpression(CilOpCodes.Ldelema, elementTypeRef,
                                                             (CilExpression)arrayExpr.Remove(),
                                                             (CilExpression)indexExpr.Remove())
            {
                ExpressionType = new ByReferenceTypeSignature(arrayType.BaseType)
            };

            expression.ReplaceWith(arrayLoadExpr);
        }
예제 #5
0
        private void ReplaceWithStelem(CilInstructionExpression expression, SzArrayTypeSignature arrayType)
        {
            var arrayExpr = expression.Arguments[0];
            var valueExpr = expression.Arguments[1];
            var indexExpr = expression.Arguments[2];

            arrayExpr.ExpectedType = arrayType;

            // Select appropriate opcode.
            CilOpCode opCode;
            object    operand = null;

            switch (arrayType.BaseType.ElementType)
            {
            case ElementType.I1:
            case ElementType.U1:
                opCode = CilOpCodes.Stelem_I1;
                break;

            case ElementType.Char:
            case ElementType.I2:
            case ElementType.U2:
                opCode = CilOpCodes.Stelem_I2;
                break;

            case ElementType.Boolean:
            case ElementType.I4:
            case ElementType.U4:
                opCode = CilOpCodes.Stelem_I4;
                break;

            case ElementType.I8:
            case ElementType.U8:
                opCode = CilOpCodes.Stelem_I8;
                break;

            case ElementType.R4:
                opCode = CilOpCodes.Stelem_R4;
                break;

            case ElementType.R8:
                opCode = CilOpCodes.Stelem_R8;
                break;

            case ElementType.I:
            case ElementType.U:
                opCode = CilOpCodes.Stelem_I;
                break;

            case ElementType.ValueType:
                opCode  = CilOpCodes.Stelem;
                operand = _context.ReferenceImporter
                          .ImportType(arrayType.BaseType.ToTypeDefOrRef());
                break;

            default:
                opCode = CilOpCodes.Stelem_Ref;
                break;
            }

            valueExpr.ExpectedType = arrayType.BaseType;

            var arrayStoreExpr = new CilInstructionExpression(opCode, operand,
                                                              (CilExpression)arrayExpr.Remove(),
                                                              (CilExpression)indexExpr.Remove(),
                                                              (CilExpression)valueExpr.Remove());

            expression.ReplaceWith(arrayStoreExpr);
        }
예제 #6
0
        private void ReplaceWithLdelem(CilInstructionExpression expression, SzArrayTypeSignature arrayType)
        {
            var arrayExpr = expression.Arguments[0];
            var indexExpr = expression.Arguments[1];

            arrayExpr.ExpectedType = arrayType;
            var elementTypeRef = _context.ReferenceImporter
                                 .ImportType(arrayType.BaseType.ToTypeDefOrRef());

            // Select appropriate opcode.
            CilOpCode opCode;
            object    operand = null;

            switch (arrayType.BaseType.ElementType)
            {
            case ElementType.I1:
                opCode = CilOpCodes.Ldelem_I1;
                break;

            case ElementType.U1:
                opCode = CilOpCodes.Ldelem_U1;
                break;

            case ElementType.I2:
                opCode = CilOpCodes.Ldelem_I2;
                break;

            case ElementType.Char:
            case ElementType.U2:
                opCode = CilOpCodes.Ldelem_U2;
                break;

            case ElementType.Boolean:
            case ElementType.I4:
                opCode = CilOpCodes.Ldelem_I4;
                break;

            case ElementType.U4:
                opCode = CilOpCodes.Ldelem_U4;
                break;

            case ElementType.I8:
            case ElementType.U8:
                opCode = CilOpCodes.Ldelem_I8;
                break;

            case ElementType.R4:
                opCode = CilOpCodes.Ldelem_R4;
                break;

            case ElementType.R8:
                opCode = CilOpCodes.Ldelem_R8;
                break;

            case ElementType.I:
            case ElementType.U:
                opCode = CilOpCodes.Ldelem_I;
                break;

            case ElementType.ValueType:
                opCode  = CilOpCodes.Ldelem;
                operand = elementTypeRef;
                break;

            default:
                opCode = CilOpCodes.Ldelem_Ref;
                break;
            }

            // Create the ldelem expression
            var arrayLoadExpr = new CilInstructionExpression(opCode, operand,
                                                             (CilExpression)arrayExpr.Remove(),
                                                             (CilExpression)indexExpr.Remove())
            {
                ExpressionType = arrayType.BaseType
            };

            if (arrayType.BaseType.IsValueType)
            {
                // Array.GetValue boxes value typed values.
                arrayLoadExpr = new CilInstructionExpression(CilOpCodes.Box, elementTypeRef, arrayLoadExpr)
                {
                    ExpectedType   = expression.ExpectedType,
                    ExpressionType = expression.ExpressionType
                };
            }

            expression.ReplaceWith(arrayLoadExpr);
        }