001 package railo.transformer.bytecode.op; 002 003 import org.objectweb.asm.Label; 004 import org.objectweb.asm.Opcodes; 005 import org.objectweb.asm.Type; 006 import org.objectweb.asm.commons.GeneratorAdapter; 007 import org.objectweb.asm.commons.Method; 008 009 import railo.transformer.bytecode.BytecodeContext; 010 import railo.transformer.bytecode.BytecodeException; 011 import railo.transformer.bytecode.expression.ExprBoolean; 012 import railo.transformer.bytecode.expression.Expression; 013 import railo.transformer.bytecode.expression.ExpressionBase; 014 import railo.transformer.bytecode.util.Methods; 015 import railo.transformer.bytecode.util.Methods_Operator; 016 import railo.transformer.bytecode.util.Types; 017 018 public final class OPDecision extends ExpressionBase implements ExprBoolean { 019 020 private Expression right; 021 private Expression left; 022 private int operation; 023 024 public static final int LT=GeneratorAdapter.LT; 025 public static final int LTE=GeneratorAdapter.LE; 026 public static final int GTE=GeneratorAdapter.GE; 027 public static final int GT=GeneratorAdapter.GT; 028 public static final int EQ=GeneratorAdapter.EQ; 029 public static final int NEQ=GeneratorAdapter.NE; 030 public static final int CT = 1000; 031 public static final int NCT = 1001; 032 public static final int EEQ = 1002; 033 public static final int NEEQ = 1003; 034 // int compare (Object, Object) 035 final public static Method METHOD_COMPARE = new Method("compare", 036 Types.INT_VALUE, 037 new Type[]{Types.OBJECT,Types.OBJECT}); 038 039 private OPDecision(Expression left, Expression right, int operation) { 040 super(left.getLine()); 041 this.left=left; 042 this.right=right; 043 this.operation=operation; 044 } 045 046 /** 047 * Create a String expression from a operation 048 * @param left 049 * @param right 050 * 051 * @return String expression 052 */ 053 public static ExprBoolean toExprBoolean(Expression left, Expression right, int operation) { 054 return new OPDecision(left,right,operation); 055 } 056 057 058 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 059 GeneratorAdapter adapter = bc.getAdapter(); 060 if(mode==MODE_REF) { 061 _writeOut(bc,MODE_VALUE); 062 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN_FROM_BOOLEAN); 063 return Types.BOOLEAN; 064 } 065 066 if(operation==CT) { 067 left.writeOut(bc,MODE_REF); 068 right.writeOut(bc,MODE_REF); 069 adapter.invokeStatic(Types.OPERATOR,Methods_Operator.OPERATOR_CT); 070 } 071 else if(operation==NCT) { 072 left.writeOut(bc,MODE_REF); 073 right.writeOut(bc,MODE_REF); 074 adapter.invokeStatic(Types.OPERATOR,Methods_Operator.OPERATOR_NCT); 075 } 076 else if(operation==EEQ) { 077 left.writeOut(bc,MODE_REF); 078 right.writeOut(bc,MODE_REF); 079 adapter.invokeStatic(Types.OPERATOR,Methods_Operator.OPERATOR_EEQ); 080 } 081 else if(operation==NEEQ) { 082 left.writeOut(bc,MODE_REF); 083 right.writeOut(bc,MODE_REF); 084 adapter.invokeStatic(Types.OPERATOR,Methods_Operator.OPERATOR_NEEQ); 085 } 086 else { 087 int iLeft = Types.getType(left.writeOut(bc,MODE_VALUE)); 088 int iRight = Types.getType(right.writeOut(bc,MODE_VALUE)); 089 090 adapter.invokeStatic(Types.OPERATOR,Methods_Operator.OPERATORS[iLeft][iRight]); 091 092 093 adapter.visitInsn(Opcodes.ICONST_0); 094 095 Label l1 = new Label(); 096 Label l2 = new Label(); 097 adapter.ifCmp(Type.INT_TYPE,operation,l1); 098 //adapter.visitJumpInsn(Opcodes.IF_ICMPEQ, l1); 099 adapter.visitInsn(Opcodes.ICONST_0); 100 adapter.visitJumpInsn(Opcodes.GOTO, l2); 101 adapter.visitLabel(l1); 102 adapter.visitInsn(Opcodes.ICONST_1); 103 adapter.visitLabel(l2); 104 } 105 return Types.BOOLEAN_VALUE; 106 } 107 108 }