public override void Branch(BranchOpcode opcode, Label target) { switch (opcode.BranchKind) { case BranchKind.Unconditional: break; case BranchKind.Boolean: { var dataType = stack.Pop(opcode).DataType; switch (dataType) { case DataType.Int32: case DataType.Int64: case DataType.NativeInt: case DataType.ObjectReference: case DataType.MutableManagedPointer: case DataType.ReadonlyManagedPointer: break; default: throw Error("{0} requires an int, reference or pointer stack operand, but the top of the stack has type {1}.", opcode.Name, dataType); } break; } // TODO: Check operand types case BranchKind.Comparison: { stack.RequireSize(opcode, 2); var lhs = stack.Pop(opcode); var rhs = stack.Pop(opcode); bool verifiable; if (!opcode.Comparison.IsApplicableTo(lhs.DataType, rhs.DataType, out verifiable)) { throw Error("{0} cannot operate on stack operands of type {1} and {2}.", opcode.Name, lhs.DataType, rhs.DataType); } break; } default: throw new NotImplementedException(); } var labelInfo = GetLabelInfo(target); SetLabelStackState(labelInfo); if (opcode.BranchKind == BranchKind.Unconditional && !labelInfo.Marked) { // Forward jump, can assume the stack is empty (ECMA 335 III.1.7.5) // TODO: Not necessarily, there could have been a prior branch to here stack.Clear(); } if (sink != null) { sink.Branch(opcode, target); } }
public override void Branch(BranchOpcode opcode, Label target) { OpCode emitOpCode; opcode.GetReflectionEmitOpCode(out emitOpCode); generator.Emit(emitOpCode, GetEmitLabel(target)); }
public override void VisitBranch(BranchOpcode opcode, VisitorParam param) { throw RequiresSymbolicOverload(opcode); }
public override void Branch(BranchOpcode opcode, Label target) { stringBuilder.AppendLine(opcode.Name + ' ' + GetLabelName(target)); }
public abstract void Branch(BranchOpcode opcode, Label target);