public void Visit(CastEntry entry) { Print($"CAST {entry.DesiredType}"); _indent++; entry.Op1.Accept(this); _indent--; }
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); }
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); }
public void Visit(CastEntry entry) { _sb.AppendLine($" ┌──▌ t{entry.Op1.TreeID}"); _sb.AppendLine($" cast {entry.DesiredType}"); }
public void Visit(CastEntry entry) { _genericStackEntryVisitor.Visit <CastEntry>(entry); }
public void Visit(CastEntry entry) { entry.Op1.Accept(this); SetNext(entry); }
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; }