コード例 #1
0
 public void Visit(CastEntry entry)
 {
     Print($"CAST {entry.DesiredType}");
     _indent++;
     entry.Op1.Accept(this);
     _indent--;
 }
コード例 #2
0
        public void Import(Instruction instruction, ImportContext context, IILImporterProxy importer)
        {
            var op2 = importer.PopExpression();
            var op1 = importer.PopExpression();

            // If one of the values is a native int then cast the other to be native int too
            if (op1.Kind == StackValueKind.NativeInt && op2.Kind == StackValueKind.Int32)
            {
                op2 = new CastEntry(Common.TypeSystem.WellKnownType.Object, op2, op1.Kind);
            }
            else if (op1.Kind == StackValueKind.Int32 && op2.Kind == StackValueKind.NativeInt)
            {
                op1 = new CastEntry(Common.TypeSystem.WellKnownType.Object, op1, op2.Kind);
            }

            // StackValueKind is carefully ordered to make this work
            StackValueKind kind;

            kind = op1.Kind > op2.Kind ? op1.Kind : op2.Kind;

            if (kind != StackValueKind.Int32 && kind != StackValueKind.NativeInt)
            {
                throw new NotSupportedException($"Binary operation on type {kind} not supported");
            }

            Operation binaryOp;

            switch (instruction.OpCode.Code)
            {
            case Code.Mul_Ovf_Un:
                // For now this maps to standard multiplication as we have no exception support
                binaryOp = Operation.Mul;
                break;

            default:
                binaryOp = Operation.Add + (instruction.OpCode.Code - Code.Add);
                break;
            }

            var binaryExpr = new BinaryOperator(binaryOp, isComparison: false, op1, op2, kind);

            importer.PushExpression(binaryExpr);
        }
コード例 #3
0
ファイル: ConversionImporter.cs プロジェクト: drcjt/CSharp-80
        public void Import(Instruction instruction, ImportContext context, IILImporterProxy importer)
        {
            WellKnownType wellKnownType;

            switch (instruction.OpCode.Code)
            {
            case Code.Conv_I4: wellKnownType = WellKnownType.Int32; break;

            case Code.Conv_U4: wellKnownType = WellKnownType.UInt32; break;

            case Code.Conv_I2: wellKnownType = WellKnownType.Int16; break;

            case Code.Conv_U2: wellKnownType = WellKnownType.UInt16; break;

            case Code.Conv_I1: wellKnownType = WellKnownType.SByte; break;

            case Code.Conv_U1: wellKnownType = WellKnownType.Byte; break;

            case Code.Conv_U: wellKnownType = WellKnownType.UIntPtr; break;

            case Code.Conv_I: wellKnownType = WellKnownType.IntPtr; break;

            default: throw new NotImplementedException($"Conversion type not supported for opcode {instruction.OpCode.Code}");
            }

            var op1 = importer.PopExpression();

            // Work out if a cast is required
            if ((op1.Kind == StackValueKind.Int32 && wellKnownType == Common.TypeSystem.WellKnownType.UInt16) ||
                (op1.Kind == StackValueKind.Int32 && wellKnownType == Common.TypeSystem.WellKnownType.Int16) ||
                (op1.Kind == StackValueKind.Int32 && wellKnownType == WellKnownType.Byte) ||
                (op1.Kind == StackValueKind.Int32 && wellKnownType == WellKnownType.SByte))
            {
                op1 = new CastEntry(wellKnownType, op1, op1.Kind);
            }

            importer.PushExpression(op1);
        }
コード例 #4
0
ファイル: LIRDumper.cs プロジェクト: drcjt/CSharp-80
 public void Visit(CastEntry entry)
 {
     _sb.AppendLine($"       ┌──▌  t{entry.Op1.TreeID}");
     _sb.AppendLine($"       cast {entry.DesiredType}");
 }
コード例 #5
0
 public void Visit(CastEntry entry)
 {
     _genericStackEntryVisitor.Visit <CastEntry>(entry);
 }
コード例 #6
0
ファイル: Flowgraph.cs プロジェクト: drcjt/CSharp-80
 public void Visit(CastEntry entry)
 {
     entry.Op1.Accept(this);
     SetNext(entry);
 }
コード例 #7
0
ファイル: BranchImporter.cs プロジェクト: drcjt/CSharp-80
        public void Import(Instruction instruction, ImportContext context, IILImporterProxy importer)
        {
            var code = instruction.OpCode.Code;

            switch (code)
            {
            case Code.Br_S:
            case Code.Blt_S:
            case Code.Bgt_S:
            case Code.Ble_S:
            case Code.Bge_S:
            case Code.Beq_S:
            case Code.Bne_Un_S:
            case Code.Brfalse_S:
            case Code.Brtrue_S:
                code += (Code.Br - Code.Br_S);
                break;
            }
            var target = instruction.OperandAs <Instruction>();

            var targetBlock      = importer.BasicBlocks[(int)target.Offset];
            var fallthroughBlock = (code != Code.Br) ? context.FallThroughBlock : null;

            if (code != Code.Br)
            {
                var op2 = importer.PopExpression();
                if (op2.Kind != StackValueKind.Int32 && op2.Kind != StackValueKind.NativeInt)
                {
                    throw new NotSupportedException("Boolean comparisons only supported using int and nativeint as underlying type");
                }

                StackEntry op1;
                Operation  op;
                if (code != Code.Brfalse && code != Code.Brtrue)
                {
                    op1 = importer.PopExpression();
                    op  = Operation.Eq + (code - Code.Beq);

                    // If one of the values is a native int then cast the other to be native int too
                    if (op1.Kind == StackValueKind.NativeInt && op2.Kind == StackValueKind.Int32)
                    {
                        op2 = new CastEntry(Common.TypeSystem.WellKnownType.Object, op2, op1.Kind);
                    }
                    else if (op1.Kind == StackValueKind.Int32 && op2.Kind == StackValueKind.NativeInt)
                    {
                        op1 = new CastEntry(Common.TypeSystem.WellKnownType.Object, op1, op2.Kind);
                    }
                }
                else
                {
                    op1 = new Int32ConstantEntry(0);
                    op  = (code == Code.Brfalse) ? Operation.Eq : Operation.Ne;
                }
                op1 = new BinaryOperator(op, isComparison: true, op1, op2, op1.Kind);
                importer.ImportAppendTree(new JumpTrueEntry(targetBlock.Label, op1));
            }
            else
            {
                importer.ImportAppendTree(new JumpEntry(targetBlock.Label));
            }

            // Fall through handling
            importer.ImportFallThrough(targetBlock);

            if (fallthroughBlock != null)
            {
                importer.ImportFallThrough(fallthroughBlock);
            }

            context.StopImporting = true;
        }