Package com.facebook.presto.byteCode.expression

Source Code of com.facebook.presto.byteCode.expression.ComparisonByteCodeExpression

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook.presto.byteCode.expression;

import com.facebook.presto.byteCode.Block;
import com.facebook.presto.byteCode.ByteCodeNode;
import com.facebook.presto.byteCode.OpCode;
import com.facebook.presto.byteCode.instruction.JumpInstruction;
import com.facebook.presto.byteCode.instruction.LabelNode;
import com.google.common.collect.ImmutableList;

import java.util.List;

import static com.facebook.presto.byteCode.OpCode.DCMPG;
import static com.facebook.presto.byteCode.OpCode.DCMPL;
import static com.facebook.presto.byteCode.OpCode.FCMPG;
import static com.facebook.presto.byteCode.OpCode.FCMPL;
import static com.facebook.presto.byteCode.OpCode.IFEQ;
import static com.facebook.presto.byteCode.OpCode.IFGE;
import static com.facebook.presto.byteCode.OpCode.IFGT;
import static com.facebook.presto.byteCode.OpCode.IFLE;
import static com.facebook.presto.byteCode.OpCode.IFLT;
import static com.facebook.presto.byteCode.OpCode.IFNE;
import static com.facebook.presto.byteCode.OpCode.IF_ACMPEQ;
import static com.facebook.presto.byteCode.OpCode.IF_ACMPNE;
import static com.facebook.presto.byteCode.OpCode.IF_ICMPEQ;
import static com.facebook.presto.byteCode.OpCode.IF_ICMPGE;
import static com.facebook.presto.byteCode.OpCode.IF_ICMPGT;
import static com.facebook.presto.byteCode.OpCode.IF_ICMPLE;
import static com.facebook.presto.byteCode.OpCode.IF_ICMPLT;
import static com.facebook.presto.byteCode.OpCode.IF_ICMPNE;
import static com.facebook.presto.byteCode.OpCode.LCMP;
import static com.facebook.presto.byteCode.ParameterizedType.type;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

class ComparisonByteCodeExpression
        extends ByteCodeExpression
{
    static ByteCodeExpression lessThan(ByteCodeExpression left, ByteCodeExpression right)
    {
        checkArgumentTypes(left, right);

        OpCode comparisonInstruction;
        OpCode noMatchJumpInstruction;

        Class<?> type = left.getType().getPrimitiveType();
        if (type == int.class) {
            comparisonInstruction = null;
            noMatchJumpInstruction = IF_ICMPGE;
        }
        else if (type == long.class) {
            comparisonInstruction = LCMP;
            noMatchJumpInstruction = IFGE;
        }
        else if (type == float.class) {
            comparisonInstruction = FCMPG;
            noMatchJumpInstruction = IFGE;
        }
        else if (type == double.class) {
            comparisonInstruction = DCMPG;
            noMatchJumpInstruction = IFGE;
        }
        else {
            throw new IllegalArgumentException("Less than does not support " + type);
        }

        return new ComparisonByteCodeExpression("<", comparisonInstruction, noMatchJumpInstruction, left, right);
    }

    static ByteCodeExpression greaterThan(ByteCodeExpression left, ByteCodeExpression right)
    {
        checkArgumentTypes(left, right);

        OpCode comparisonInstruction;
        OpCode noMatchJumpInstruction;

        Class<?> type = left.getType().getPrimitiveType();
        if (type == int.class) {
            comparisonInstruction = null;
            noMatchJumpInstruction = IF_ICMPLE;
        }
        else if (type == long.class) {
            comparisonInstruction = LCMP;
            noMatchJumpInstruction = IFLE;
        }
        else if (type == float.class) {
            comparisonInstruction = FCMPL;
            noMatchJumpInstruction = IFLE;
        }
        else if (type == double.class) {
            comparisonInstruction = DCMPL;
            noMatchJumpInstruction = IFLE;
        }
        else {
            throw new IllegalArgumentException("Less than does not support " + type);
        }
        return new ComparisonByteCodeExpression(">", comparisonInstruction, noMatchJumpInstruction, left, right);
    }

    static ByteCodeExpression lessThanOrEqual(ByteCodeExpression left, ByteCodeExpression right)
    {
        checkArgumentTypes(left, right);

        OpCode comparisonInstruction;
        OpCode noMatchJumpInstruction;

        Class<?> type = left.getType().getPrimitiveType();
        if (type == int.class) {
            comparisonInstruction = null;
            noMatchJumpInstruction = IF_ICMPGT;
        }
        else if (type == long.class) {
            comparisonInstruction = LCMP;
            noMatchJumpInstruction = IFGT;
        }
        else if (type == float.class) {
            comparisonInstruction = FCMPG;
            noMatchJumpInstruction = IFGT;
        }
        else if (type == double.class) {
            comparisonInstruction = DCMPG;
            noMatchJumpInstruction = IFGT;
        }
        else {
            throw new IllegalArgumentException("Less than does not support " + type);
        }
        return new ComparisonByteCodeExpression("<=", comparisonInstruction, noMatchJumpInstruction, left, right);
    }

    static ByteCodeExpression greaterThanOrEqual(ByteCodeExpression left, ByteCodeExpression right)
    {
        checkArgumentTypes(left, right);

        OpCode comparisonInstruction;
        OpCode noMatchJumpInstruction;

        Class<?> type = left.getType().getPrimitiveType();
        if (type == int.class) {
            comparisonInstruction = null;
            noMatchJumpInstruction = IF_ICMPLT;
        }
        else if (type == long.class) {
            comparisonInstruction = LCMP;
            noMatchJumpInstruction = IFLT;
        }
        else if (type == float.class) {
            comparisonInstruction = FCMPL;
            noMatchJumpInstruction = IFLT;
        }
        else if (type == double.class) {
            comparisonInstruction = DCMPL;
            noMatchJumpInstruction = IFLT;
        }
        else {
            throw new IllegalArgumentException("Less than does not support " + type);
        }
        return new ComparisonByteCodeExpression(">=", comparisonInstruction, noMatchJumpInstruction, left, right);
    }

    static ByteCodeExpression equal(ByteCodeExpression left, ByteCodeExpression right)
    {
        checkNotNull(left, "left is null");
        checkNotNull(right, "right is null");
        checkArgument(left.getType().equals(right.getType()), "left and right must be the same type");

        OpCode comparisonInstruction;
        OpCode noMatchJumpInstruction;

        Class<?> type = left.getType().getPrimitiveType();
        if (type == int.class) {
            comparisonInstruction = null;
            noMatchJumpInstruction = IF_ICMPNE;
        }
        else if (type == long.class) {
            comparisonInstruction = LCMP;
            noMatchJumpInstruction = IFNE;
        }
        else if (type == float.class) {
            comparisonInstruction = FCMPL;
            noMatchJumpInstruction = IFNE;
        }
        else if (type == double.class) {
            comparisonInstruction = DCMPL;
            noMatchJumpInstruction = IFNE;
        }
        else if (type == null) {
            comparisonInstruction = null;
            noMatchJumpInstruction = IF_ACMPNE;
        }
        else {
            throw new IllegalArgumentException("Less than does not support " + type);
        }
        return new ComparisonByteCodeExpression("==", comparisonInstruction, noMatchJumpInstruction, left, right);
    }

    static ByteCodeExpression notEqual(ByteCodeExpression left, ByteCodeExpression right)
    {
        checkNotNull(left, "left is null");
        checkNotNull(right, "right is null");
        checkArgument(left.getType().equals(right.getType()), "left and right must be the same type");

        OpCode comparisonInstruction;
        OpCode noMatchJumpInstruction;

        Class<?> type = left.getType().getPrimitiveType();
        if (type == int.class) {
            comparisonInstruction = null;
            noMatchJumpInstruction = IF_ICMPEQ;
        }
        else if (type == long.class) {
            comparisonInstruction = LCMP;
            noMatchJumpInstruction = IFEQ;
        }
        else if (type == float.class) {
            comparisonInstruction = FCMPL;
            noMatchJumpInstruction = IFEQ;
        }
        else if (type == double.class) {
            comparisonInstruction = DCMPL;
            noMatchJumpInstruction = IFEQ;
        }
        else if (type == null) {
            comparisonInstruction = null;
            noMatchJumpInstruction = IF_ACMPEQ;
        }
        else {
            throw new IllegalArgumentException("Less than does not support " + type);
        }
        return new ComparisonByteCodeExpression("!=", comparisonInstruction, noMatchJumpInstruction, left, right);
    }

    private static void checkArgumentTypes(ByteCodeExpression left, ByteCodeExpression right)
    {
        Class<?> leftType = getPrimitiveType(left, "left");
        Class<?> rightType = getPrimitiveType(right, "right");
        checkArgument(leftType == rightType, "left and right must be the same type");
    }

    private static Class<?> getPrimitiveType(ByteCodeExpression expression, String name)
    {
        checkNotNull(expression, name + " is null");
        Class<?> leftType = expression.getType().getPrimitiveType();
        checkArgument(leftType != null, name + " is not a primitive");
        checkArgument(leftType != void.class, name + " is void");
        return leftType;
    }

    private final String infixSymbol;
    private OpCode comparisonInstruction;
    private OpCode noMatchJumpInstruction;
    private final ByteCodeExpression left;
    private final ByteCodeExpression right;

    private ComparisonByteCodeExpression(
            String infixSymbol,
            OpCode comparisonInstruction,
            OpCode noMatchJumpInstruction,
            ByteCodeExpression left,
            ByteCodeExpression right)
    {
        super(type(boolean.class));
        this.infixSymbol = infixSymbol;
        this.comparisonInstruction = comparisonInstruction;
        this.noMatchJumpInstruction = noMatchJumpInstruction;
        this.left = left;
        this.right = right;
    }

    @Override
    public ByteCodeNode getByteCode()
    {
        Block block = new Block(null)
                .append(left)
                .append(right);

        if (comparisonInstruction != null) {
            block.append(comparisonInstruction);
        }

        LabelNode noMatch = new LabelNode("no_match");
        LabelNode end = new LabelNode("end");
        return block
                .append(new JumpInstruction(noMatchJumpInstruction, noMatch))
                .push(true)
                .gotoLabel(end)
                .append(noMatch)
                .push(false)
                .append(end);
    }

    @Override
    public List<ByteCodeNode> getChildNodes()
    {
        return ImmutableList.<ByteCodeNode>of(left, right);
    }

    @Override
    protected String formatOneLine()
    {
        return "(" + left + " " + infixSymbol + " " + right + ")";
    }
}
TOP

Related Classes of com.facebook.presto.byteCode.expression.ComparisonByteCodeExpression

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.