/**
*
* Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
**/
package lucee.transformer.bytecode.op;
import lucee.transformer.TransformerException;
import lucee.transformer.bytecode.BytecodeContext;
import lucee.transformer.bytecode.expression.ExpressionBase;
import lucee.transformer.bytecode.util.Methods;
import lucee.transformer.bytecode.util.Methods_Operator;
import lucee.transformer.bytecode.util.Types;
import lucee.transformer.expression.ExprBoolean;
import lucee.transformer.expression.Expression;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
public final class OPDecision extends ExpressionBase implements ExprBoolean {
private Expression right;
private Expression left;
private int operation;
public static final int LT=GeneratorAdapter.LT;
public static final int LTE=GeneratorAdapter.LE;
public static final int GTE=GeneratorAdapter.GE;
public static final int GT=GeneratorAdapter.GT;
public static final int EQ=GeneratorAdapter.EQ;
public static final int NEQ=GeneratorAdapter.NE;
public static final int CT = 1000;
public static final int NCT = 1001;
public static final int EEQ = 1002;
public static final int NEEQ = 1003;
// int compare (Object, Object)
final public static Method METHOD_COMPARE = new Method("compare",
Types.INT_VALUE,
new Type[]{Types.OBJECT,Types.OBJECT});
private OPDecision(Expression left, Expression right, int operation) {
super(left.getFactory(),left.getStart(),right.getEnd());
this.left=left;
this.right=right;
this.operation=operation;
}
/**
* Create a String expression from a operation
* @param left
* @param right
*
* @return String expression
*/
public static ExprBoolean toExprBoolean(Expression left, Expression right, int operation) {
return new OPDecision(left,right,operation);
}
@Override
public Type _writeOut(BytecodeContext bc, int mode) throws TransformerException {
GeneratorAdapter adapter = bc.getAdapter();
if(mode==MODE_REF) {
_writeOut(bc,MODE_VALUE);
adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_BOOLEAN_FROM_BOOLEAN);
return Types.BOOLEAN;
}
if(operation==CT) {
left.writeOut(bc,MODE_REF);
right.writeOut(bc,MODE_REF);
adapter.invokeStatic(Types.OPERATOR,Methods_Operator.OPERATOR_CT);
}
else if(operation==NCT) {
left.writeOut(bc,MODE_REF);
right.writeOut(bc,MODE_REF);
adapter.invokeStatic(Types.OPERATOR,Methods_Operator.OPERATOR_NCT);
}
else if(operation==EEQ) {
left.writeOut(bc,MODE_REF);
right.writeOut(bc,MODE_REF);
adapter.invokeStatic(Types.OPERATOR,Methods_Operator.OPERATOR_EEQ);
}
else if(operation==NEEQ) {
left.writeOut(bc,MODE_REF);
right.writeOut(bc,MODE_REF);
adapter.invokeStatic(Types.OPERATOR,Methods_Operator.OPERATOR_NEEQ);
}
else {
int iLeft = Types.getType(left.writeOut(bc,MODE_VALUE));
int iRight = Types.getType(right.writeOut(bc,MODE_VALUE));
adapter.invokeStatic(Types.OPERATOR,Methods_Operator.OPERATORS[iLeft][iRight]);
adapter.visitInsn(Opcodes.ICONST_0);
Label l1 = new Label();
Label l2 = new Label();
adapter.ifCmp(Type.INT_TYPE,operation,l1);
//adapter.visitJumpInsn(Opcodes.IF_ICMPEQ, l1);
adapter.visitInsn(Opcodes.ICONST_0);
adapter.visitJumpInsn(Opcodes.GOTO, l2);
adapter.visitLabel(l1);
adapter.visitInsn(Opcodes.ICONST_1);
adapter.visitLabel(l2);
}
return Types.BOOLEAN_VALUE;
}
}