lucee.transformer.bytecode.op.OPDecision.java Source code

Java tutorial

Introduction

Here is the source code for lucee.transformer.bytecode.op.OPDecision.java

Source

/**
 *
 * 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.bytecode.BytecodeContext;
import lucee.transformer.bytecode.BytecodeException;
import lucee.transformer.bytecode.expression.ExprBoolean;
import lucee.transformer.bytecode.expression.Expression;
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 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.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);
    }

    public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
        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;
    }

}