Java Code Examples for jdk.nashorn.internal.ir.BinaryNode#rhs()

The following examples show how to use jdk.nashorn.internal.ir.BinaryNode#rhs() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: FinalizeTypes.java    From nashorn with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Add is a special binary, as it works not only on arithmetic, but for
 * strings etc as well.
 */
@Override
public Expression leaveADD(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();

    final Type type = binaryNode.getType();

    if (type.isObject()) {
        if (!isAddString(binaryNode)) {
            return new RuntimeNode(binaryNode, Request.ADD);
        }
    }

    return binaryNode.setLHS(convert(lhs, type)).setRHS(convert(rhs, type));
}
 
Example 2
Source File: CodeGenerator.java    From openjdk-8 with GNU General Public License v2.0 6 votes vote down vote up
private boolean enterAND_OR(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();

    final Label skip = new Label("skip");

    load(lhs, Type.OBJECT).dup().convert(Type.BOOLEAN);

    if (binaryNode.tokenType() == TokenType.AND) {
        method.ifeq(skip);
    } else {
        method.ifne(skip);
    }

    method.pop();
    load(rhs, Type.OBJECT);
    method.label(skip);
    method.store(binaryNode.getSymbol());

    return false;
}
 
Example 3
Source File: Attr.java    From nashorn with GNU General Public License v2.0 6 votes vote down vote up
/**
 * This assign helper is called after an assignment, when all children of
 * the assign has been processed. It fixes the types and recursively makes
 * sure that everyhing has slots that should have them in the chain.
 *
 * @param binaryNode assignment node
 */
private Node leaveAssignmentNode(final BinaryNode binaryNode) {
    BinaryNode newBinaryNode = binaryNode;

    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();
    final Type type;

    if (rhs.getType().isNumeric()) {
        type = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType());
    } else {
        type = Type.OBJECT; //force lhs to be an object if not numeric assignment, e.g. strings too.
    }

    newType(lhs.getSymbol(), type);
    return end(ensureSymbol(type, newBinaryNode));
}
 
Example 4
Source File: CodeGenerator.java    From openjdk-8-source with GNU General Public License v2.0 6 votes vote down vote up
private boolean enterAND_OR(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();

    final Label skip = new Label("skip");

    load(lhs, Type.OBJECT).dup().convert(Type.BOOLEAN);

    if (binaryNode.tokenType() == TokenType.AND) {
        method.ifeq(skip);
    } else {
        method.ifne(skip);
    }

    method.pop();
    load(rhs, Type.OBJECT);
    method.label(skip);
    method.store(binaryNode.getSymbol());

    return false;
}
 
Example 5
Source File: CodeGenerator.java    From openjdk-8 with GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean enterASSIGN(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();

    final Type lhsType = lhs.getType();
    final Type rhsType = rhs.getType();

    if (!lhsType.isEquivalentTo(rhsType)) {
        //this is OK if scoped, only locals are wrong
    }

    new Store<BinaryNode>(binaryNode, lhs) {
        @Override
        protected void evaluate() {
            if ((lhs instanceof IdentNode) && !lhs.getSymbol().isScope()) {
                load(rhs, lhsType);
            } else {
                load(rhs);
            }
        }
    }.store();

    return false;
}
 
Example 6
Source File: CodeGenerator.java    From nashorn with GNU General Public License v2.0 6 votes vote down vote up
private boolean enterAND_OR(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();

    final Label skip = new Label("skip");

    load(lhs).convert(Type.OBJECT).dup().convert(Type.BOOLEAN);

    if (binaryNode.tokenType() == TokenType.AND) {
        method.ifeq(skip);
    } else {
        method.ifne(skip);
    }

    method.pop();
    load(rhs).convert(Type.OBJECT);
    method.label(skip);
    method.store(binaryNode.getSymbol());

    return false;
}
 
Example 7
Source File: LocalVariableTypesCalculator.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean enterBinaryNode(final BinaryNode binaryNode) {
    // NOTE: regardless of operator's lexical associativity, lhs is always evaluated first.
    final Expression lhs = binaryNode.lhs();
    final LvarType lhsType;
    if (!(lhs instanceof IdentNode && binaryNode.isTokenType(TokenType.ASSIGN))) {
        lhsType = visitExpression(lhs);
    } else {
        // Can't visit IdentNode on LHS of a simple assignment, as visits imply use, and this is def.
        // The type is irrelevant, as only RHS is used to determine the type anyway.
        lhsType = LvarType.UNDEFINED;
    }

    final boolean isLogical = binaryNode.isLogical();
    final Label joinLabel = isLogical ? new Label("") : null;
    if(isLogical) {
        jumpToLabel((JoinPredecessor)lhs, joinLabel);
    }

    final Expression rhs = binaryNode.rhs();
    final LvarType rhsType = visitExpression(rhs);
    if(isLogical) {
        jumpToLabel((JoinPredecessor)rhs, joinLabel);
    }
    joinOnLabel(joinLabel);

    final LvarType type = toLvarType(binaryNode.setOperands(lhsType.typeExpression, rhsType.typeExpression).getType());

    if(binaryNode.isAssignment() && lhs instanceof IdentNode) {
        if(binaryNode.isSelfModifying()) {
            onSelfAssignment((IdentNode)lhs, type);
        } else {
            onAssignment((IdentNode)lhs, type);
        }
    }
    typeStack.push(type);
    return false;
}
 
Example 8
Source File: Attr.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Add is a special binary, as it works not only on arithmetic, but for
 * strings etc as well.
 */
@Override
public Node leaveADD(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();

    ensureTypeNotUnknown(lhs);
    ensureTypeNotUnknown(rhs);
    //even if we are adding two known types, this can overflow. i.e.
    //int and number -> number.
    //int and int are also number though.
    //something and object is object
    return end(ensureSymbol(Type.widest(arithType(), Type.widest(lhs.getType(), rhs.getType())), binaryNode));
}
 
Example 9
Source File: Attr.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
@Override
public Node leaveASSIGN_ADD(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();

    final Type widest = Type.widest(lhs.getType(), rhs.getType());
    //Type.NUMBER if we can't prove that the add doesn't overflow. todo
    return leaveSelfModifyingAssignmentNode(binaryNode, widest.isNumeric() ? Type.NUMBER : Type.OBJECT);
}
 
Example 10
Source File: CodeGenerator.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
private boolean enterComma(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();

    load(lhs);
    load(rhs);
    method.store(binaryNode.getSymbol());

    return false;
}
 
Example 11
Source File: LocalVariableTypesCalculator.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean enterBinaryNode(final BinaryNode binaryNode) {
    // NOTE: regardless of operator's lexical associativity, lhs is always evaluated first.
    final Expression lhs = binaryNode.lhs();
    final LvarType lhsType;
    if (!(lhs instanceof IdentNode && binaryNode.isTokenType(TokenType.ASSIGN))) {
        lhsType = visitExpression(lhs);
    } else {
        // Can't visit IdentNode on LHS of a simple assignment, as visits imply use, and this is def.
        // The type is irrelevant, as only RHS is used to determine the type anyway.
        lhsType = LvarType.UNDEFINED;
    }

    final boolean isLogical = binaryNode.isLogical();
    final Label joinLabel = isLogical ? new Label("") : null;
    if(isLogical) {
        jumpToLabel((JoinPredecessor)lhs, joinLabel);
    }

    final Expression rhs = binaryNode.rhs();
    final LvarType rhsType = visitExpression(rhs);
    if(isLogical) {
        jumpToLabel((JoinPredecessor)rhs, joinLabel);
    }
    joinOnLabel(joinLabel);

    final LvarType type = toLvarType(binaryNode.setOperands(lhsType.typeExpression, rhsType.typeExpression).getType());

    if(binaryNode.isAssignment() && lhs instanceof IdentNode) {
        if(binaryNode.isSelfModifying()) {
            onSelfAssignment((IdentNode)lhs, type);
        } else {
            onAssignment((IdentNode)lhs, type);
        }
    }
    typeStack.push(type);
    return false;
}
 
Example 12
Source File: LocalVariableTypesCalculator.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean enterBinaryNode(final BinaryNode binaryNode) {
    // NOTE: regardless of operator's lexical associativity, lhs is always evaluated first.
    final Expression lhs = binaryNode.lhs();
    final LvarType lhsType;
    if (!(lhs instanceof IdentNode && binaryNode.isTokenType(TokenType.ASSIGN))) {
        lhsType = visitExpression(lhs);
    } else {
        // Can't visit IdentNode on LHS of a simple assignment, as visits imply use, and this is def.
        // The type is irrelevant, as only RHS is used to determine the type anyway.
        lhsType = LvarType.UNDEFINED;
    }

    final boolean isLogical = binaryNode.isLogical();
    final Label joinLabel = isLogical ? new Label("") : null;
    if(isLogical) {
        jumpToLabel((JoinPredecessor)lhs, joinLabel);
    }

    final Expression rhs = binaryNode.rhs();
    final LvarType rhsType = visitExpression(rhs);
    if(isLogical) {
        jumpToLabel((JoinPredecessor)rhs, joinLabel);
    }
    joinOnLabel(joinLabel);

    final LvarType type = toLvarType(binaryNode.setOperands(lhsType.typeExpression, rhsType.typeExpression).getType());

    if(binaryNode.isAssignment() && lhs instanceof IdentNode) {
        if(binaryNode.isSelfModifying()) {
            onSelfAssignment((IdentNode)lhs, type);
        } else {
            onAssignment((IdentNode)lhs, type);
        }
    }
    typeStack.push(type);
    return false;
}
 
Example 13
Source File: Attr.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
@Override
public Node leaveASSIGN_ADD(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();

    final Type widest = Type.widest(lhs.getType(), rhs.getType());
    //Type.NUMBER if we can't prove that the add doesn't overflow. todo
    return leaveSelfModifyingAssignmentNode(binaryNode, widest.isNumeric() ? Type.NUMBER : Type.OBJECT);
}
 
Example 14
Source File: LocalVariableTypesCalculator.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean enterBinaryNode(final BinaryNode binaryNode) {
    // NOTE: regardless of operator's lexical associativity, lhs is always evaluated first.
    final Expression lhs = binaryNode.lhs();
    final LvarType lhsType;
    if (!(lhs instanceof IdentNode && binaryNode.isTokenType(TokenType.ASSIGN))) {
        lhsType = visitExpression(lhs);
    } else {
        // Can't visit IdentNode on LHS of a simple assignment, as visits imply use, and this is def.
        // The type is irrelevant, as only RHS is used to determine the type anyway.
        lhsType = LvarType.UNDEFINED;
    }

    final boolean isLogical = binaryNode.isLogical();
    final Label joinLabel = isLogical ? new Label("") : null;
    if(isLogical) {
        jumpToLabel((JoinPredecessor)lhs, joinLabel);
    }

    final Expression rhs = binaryNode.rhs();
    final LvarType rhsType = visitExpression(rhs);
    if(isLogical) {
        jumpToLabel((JoinPredecessor)rhs, joinLabel);
    }
    joinOnLabel(joinLabel);

    final LvarType type = toLvarType(binaryNode.setOperands(lhsType.typeExpression, rhsType.typeExpression).getType());

    if(binaryNode.isAssignment() && lhs instanceof IdentNode) {
        if(binaryNode.isSelfModifying()) {
            onSelfAssignment((IdentNode)lhs, type);
        } else {
            onAssignment((IdentNode)lhs, type);
        }
    }
    typeStack.push(type);
    return false;
}
 
Example 15
Source File: FinalizeTypes.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Exit a comparison node and do the appropriate replacements. We need to introduce runtime
 * nodes late for comparisons as types aren't known until the last minute
 *
 * Both compares and adds may turn into runtimes node at this level as when we first bump
 * into the op in Attr, we may type it according to what we know there, which may be wrong later
 *
 * e.g. i (int) < 5 -> normal compare
 *     i = object
 *  then the post pass that would add the conversion to the 5 needs to
 *
 * @param binaryNode binary node to leave
 * @param request    runtime request
 * @return lowered cmp node
 */
@SuppressWarnings("fallthrough")
private Node leaveCmp(final BinaryNode binaryNode, final RuntimeNode.Request request) {
    final Expression lhs    = binaryNode.lhs();
    final Expression rhs    = binaryNode.rhs();

    Type widest = Type.widest(lhs.getType(), rhs.getType());

    boolean newRuntimeNode = false, finalized = false;
    switch (request) {
    case EQ_STRICT:
    case NE_STRICT:
        if (lhs.getType().isBoolean() != rhs.getType().isBoolean()) {
            newRuntimeNode = true;
            widest = Type.OBJECT;
            finalized = true;
        }
        //fallthru
    default:
        if (newRuntimeNode || widest.isObject()) {
            return new RuntimeNode(binaryNode, request).setIsFinal(finalized);
        }
        break;
    }

    return binaryNode.setLHS(convert(lhs, widest)).setRHS(convert(rhs, widest));
}
 
Example 16
Source File: Attr.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * This assign helper is called after an assignment, when all children of
 * the assign has been processed. It fixes the types and recursively makes
 * sure that everyhing has slots that should have them in the chain.
 *
 * @param binaryNode assignment node
 */
private Node leaveAssignmentNode(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();
    final Type type;

    if (lhs instanceof IdentNode) {
        final Block     block = lc.getCurrentBlock();
        final IdentNode ident = (IdentNode)lhs;
        final String    name  = ident.getName();
        final Symbol symbol = findSymbol(block, name);

        if (symbol == null) {
            defineSymbol(block, name, IS_GLOBAL);
        } else {
            maybeForceScope(symbol);
        }

        addLocalDef(name);
    }

    if (rhs.getType().isNumeric()) {
        type = Type.widest(lhs.getType(), rhs.getType());
    } else {
        type = Type.OBJECT; //force lhs to be an object if not numeric assignment, e.g. strings too.
    }

    newType(lhs.getSymbol(), type);
    return end(ensureSymbol(type, binaryNode));
}
 
Example 17
Source File: Attr.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public Node leaveASSIGN_ADD(final BinaryNode binaryNode) {
    final Expression lhs = binaryNode.lhs();
    final Expression rhs = binaryNode.rhs();

    final Type widest = Type.widest(lhs.getType(), rhs.getType());
    //Type.NUMBER if we can't prove that the add doesn't overflow. todo
    return leaveSelfModifyingAssignmentNode(binaryNode, widest.isNumeric() ? Type.NUMBER : Type.OBJECT);
}
 
Example 18
Source File: RangeAnalyzer.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Check for a loop counter. This is currently quite conservative, in that it only handles
 * x <= counter and x < counter.
 *
 * @param node loop node to check
 * @return
 */
private static Symbol findLoopCounter(final LoopNode node) {
    final Expression test = node.getTest();

    if (test != null && test.isComparison()) {
        final BinaryNode binaryNode = (BinaryNode)test;
        final Expression lhs = binaryNode.lhs();
        final Expression rhs = binaryNode.rhs();

        //detect ident cmp int_literal
        if (lhs instanceof IdentNode && rhs instanceof LiteralNode && ((LiteralNode<?>)rhs).getType().isInteger()) {
            final Symbol    symbol = lhs.getSymbol();
            final int       margin = ((LiteralNode<?>)rhs).getInt32();
            final TokenType op     = test.tokenType();

            switch (op) {
            case LT:
            case LE:
                symbol.setRange(RANGE.join(symbol.getRange(), Range.createRange(op == TokenType.LT ? margin - 1 : margin)));
                return symbol;
            case GT:
            case GE:
                //setRange(lhs, Range.createRange(op == TokenType.GT ? margin + 1 : margin));
                //return symbol;
            default:
                break;
            }
        }
    }

    return null;
}
 
Example 19
Source File: LocalVariableTypesCalculator.java    From jdk8u_nashorn with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean enterBinaryNode(final BinaryNode binaryNode) {
    // NOTE: regardless of operator's lexical associativity, lhs is always evaluated first.
    final Expression lhs = binaryNode.lhs();
    final LvarType lhsType;
    if (!(lhs instanceof IdentNode && binaryNode.isTokenType(TokenType.ASSIGN))) {
        lhsType = visitExpression(lhs);
    } else {
        // Can't visit IdentNode on LHS of a simple assignment, as visits imply use, and this is def.
        // The type is irrelevant, as only RHS is used to determine the type anyway.
        lhsType = LvarType.UNDEFINED;
    }

    final boolean isLogical = binaryNode.isLogical();
    final Label joinLabel = isLogical ? new Label("") : null;
    if(isLogical) {
        jumpToLabel((JoinPredecessor)lhs, joinLabel);
    }

    final Expression rhs = binaryNode.rhs();
    final LvarType rhsType = visitExpression(rhs);
    if(isLogical) {
        jumpToLabel((JoinPredecessor)rhs, joinLabel);
    }
    joinOnLabel(joinLabel);

    final LvarType type = toLvarType(binaryNode.setOperands(lhsType.typeExpression, rhsType.typeExpression).getType());

    if(binaryNode.isAssignment() && lhs instanceof IdentNode) {
        if(binaryNode.isSelfModifying()) {
            onSelfAssignment((IdentNode)lhs, type);
        } else {
            onAssignment((IdentNode)lhs, type);
        }
    }
    typeStack.push(type);
    return false;
}
 
Example 20
Source File: LocalVariableTypesCalculator.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public boolean enterBinaryNode(final BinaryNode binaryNode) {
    // NOTE: regardless of operator's lexical associativity, lhs is always evaluated first.
    final Expression lhs = binaryNode.lhs();
    final LvarType lhsType;
    if (!(lhs instanceof IdentNode && binaryNode.isTokenType(TokenType.ASSIGN))) {
        lhsType = visitExpression(lhs);
    } else {
        // Can't visit IdentNode on LHS of a simple assignment, as visits imply use, and this is def.
        // The type is irrelevant, as only RHS is used to determine the type anyway.
        lhsType = LvarType.UNDEFINED;
    }

    final boolean isLogical = binaryNode.isLogical();
    final Label joinLabel = isLogical ? new Label("") : null;
    if(isLogical) {
        jumpToLabel((JoinPredecessor)lhs, joinLabel);
    }

    final Expression rhs = binaryNode.rhs();
    final LvarType rhsType = visitExpression(rhs);
    if(isLogical) {
        jumpToLabel((JoinPredecessor)rhs, joinLabel);
    }
    joinOnLabel(joinLabel);

    final LvarType type = toLvarType(binaryNode.setOperands(lhsType.typeExpression, rhsType.typeExpression).getType());

    if(binaryNode.isAssignment() && lhs instanceof IdentNode) {
        if(binaryNode.isSelfModifying()) {
            onSelfAssignment((IdentNode)lhs, type);
        } else {
            onAssignment((IdentNode)lhs, type);
        }
    }
    typeStack.push(type);
    return false;
}