/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.ir.compiler.bytecode.expression; import gw.internal.gosu.ir.compiler.bytecode.AbstractBytecodeCompiler; import gw.internal.gosu.ir.compiler.bytecode.IRBytecodeContext; import gw.internal.gosu.ir.compiler.bytecode.IRBytecodeCompiler; import gw.lang.ir.expression.IRRelationalExpression; import gw.lang.ir.IRType; import gw.internal.ext.org.objectweb.asm.Label; import gw.internal.ext.org.objectweb.asm.Opcodes; import gw.internal.ext.org.objectweb.asm.MethodVisitor; public class IRRelationalExpressionCompiler extends AbstractBytecodeCompiler { public static void compile( IRRelationalExpression expression, IRBytecodeContext context ) { if (!expression.getLhs().getType().equals(expression.getRhs().getType())) { throw new IllegalStateException("Relational expression had one side as a " + expression.getLhs().getType().getName() + " and the other as a " + expression.getRhs().getType().getName()); } IRBytecodeCompiler.compileIRExpression( expression.getLhs(), context ); IRBytecodeCompiler.compileIRExpression( expression.getRhs(), context ); MethodVisitor mv = context.getMv(); Label trueLabel = new Label(); IRType type = expression.getLhs().getType(); IRRelationalExpression.Operation op = expression.getOp(); if( type.isLong() || type.isDouble() || type.isFloat() ) { mv.visitInsn( type.isDouble() ? Opcodes.DCMPL : type.isFloat() ? Opcodes.FCMPL : Opcodes.LCMP ); if( op == IRRelationalExpression.Operation.LTE ) { mv.visitJumpInsn( Opcodes.IFLE, trueLabel ); } else if( op == IRRelationalExpression.Operation.LT ) { mv.visitJumpInsn( Opcodes.IFLT, trueLabel ); } else if( op == IRRelationalExpression.Operation.GTE ) { mv.visitJumpInsn( Opcodes.IFGE, trueLabel ); } else { mv.visitJumpInsn( Opcodes.IFGT, trueLabel ); } } else { if( op == IRRelationalExpression.Operation.LTE ) { mv.visitJumpInsn( Opcodes.IF_ICMPLE, trueLabel ); } else if( op == IRRelationalExpression.Operation.LT ) { mv.visitJumpInsn( Opcodes.IF_ICMPLT, trueLabel ); } else if( op == IRRelationalExpression.Operation.GTE ) { mv.visitJumpInsn( Opcodes.IF_ICMPGE, trueLabel ); } else { mv.visitJumpInsn( Opcodes.IF_ICMPGT, trueLabel ); } } mv.visitInsn( Opcodes.ICONST_0 ); Label falseLabel = new Label(); mv.visitJumpInsn( Opcodes.GOTO, falseLabel ); mv.visitLabel( trueLabel ); mv.visitInsn( Opcodes.ICONST_1 ); mv.visitLabel( falseLabel ); } }