nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BinaryNode.java
author attila
Thu, 05 Mar 2015 15:43:43 +0100
changeset 29283 fb47e4d25a9f
parent 28130 433d6755c5f8
child 30392 dc4a419b2982
permissions -rw-r--r--
8035712: Restore some of the RuntimeCallSite specializations Reviewed-by: hannesw, lagergren
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.ir;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    28
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    29
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    30
import java.util.Arrays;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    31
import java.util.Collections;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    32
import java.util.HashSet;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    33
import java.util.Set;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import jdk.nashorn.internal.codegen.types.Type;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    35
import jdk.nashorn.internal.ir.annotations.Ignore;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    36
import jdk.nashorn.internal.ir.annotations.Immutable;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    37
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
import jdk.nashorn.internal.parser.TokenType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    39
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
 * BinaryNode nodes represent two operand operations.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    42
 */
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    43
@Immutable
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    44
public final class BinaryNode extends Expression implements Assignment<Expression>, Optimistic {
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 25865
diff changeset
    45
    private static final long serialVersionUID = 1L;
06ec78f29a56 8059843: Make AST serializable
attila
parents: 25865
diff changeset
    46
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    47
    // Placeholder for "undecided optimistic ADD type". Unfortunately, we can't decide the type of ADD during optimistic
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    48
    // type calculation as it can have local variables as its operands that will decide its ultimate type.
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24769
diff changeset
    49
    private static final Type OPTIMISTIC_UNDECIDED_TYPE = Type.typeFor(new Object(){/*empty*/}.getClass());
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    50
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
    /** Left hand side argument. */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
    52
    private final Expression lhs;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    53
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
    54
    private final Expression rhs;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    56
    private final int programPoint;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    57
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    58
    private final Type type;
27204
06ec78f29a56 8059843: Make AST serializable
attila
parents: 25865
diff changeset
    59
    private transient Type cachedType;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    60
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    61
    @Ignore
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    62
    private static final Set<TokenType> CAN_OVERFLOW =
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    63
        Collections.unmodifiableSet(new HashSet<>(Arrays.asList(new TokenType[] {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    64
                TokenType.ADD,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    65
                TokenType.DIV,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    66
                TokenType.MOD,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    67
                TokenType.MUL,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    68
                TokenType.SUB,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    69
                TokenType.ASSIGN_ADD,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    70
                TokenType.ASSIGN_DIV,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    71
                TokenType.ASSIGN_MOD,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    72
                TokenType.ASSIGN_MUL,
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    73
                TokenType.ASSIGN_SUB
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    74
            })));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    75
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
     * @param token  token
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
     * @param lhs    left hand side
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
     * @param rhs    right hand side
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    82
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
    83
    public BinaryNode(final long token, final Expression lhs, final Expression rhs) {
17523
cb4a7c901e0d 8013913: Removed Source field from all nodes except FunctionNode in order to save footprint
lagergren
parents: 17233
diff changeset
    84
        super(token, lhs.getStart(), rhs.getFinish());
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    85
        assert !(isTokenType(TokenType.AND) || isTokenType(TokenType.OR)) || lhs instanceof JoinPredecessorExpression;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    86
        this.lhs   = lhs;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    87
        this.rhs   = rhs;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    88
        this.programPoint = INVALID_PROGRAM_POINT;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    89
        this.type = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    91
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    92
    private BinaryNode(final BinaryNode binaryNode, final Expression lhs, final Expression rhs, final Type type, final int programPoint) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    93
        super(binaryNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    94
        this.lhs = lhs;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    95
        this.rhs = rhs;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    96
        this.programPoint = programPoint;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    97
        this.type = type;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    99
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   100
    /**
29283
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   101
     * Returns true if the node is a comparison operation (either equality, inequality, or relational).
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   102
     * @return true if the node is a comparison operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   103
     */
17756
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   104
    public boolean isComparison() {
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   105
        switch (tokenType()) {
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   106
        case EQ:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   107
        case EQ_STRICT:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   108
        case NE:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   109
        case NE_STRICT:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   110
        case LE:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   111
        case LT:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   112
        case GE:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   113
        case GT:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   114
            return true;
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   115
        default:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   116
            return false;
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   117
        }
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   118
    }
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   119
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
    /**
29283
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   121
     * Returns true if the node is a relational operation (less than (or equals), greater than (or equals)).
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   122
     * @return true if the node is a relational operation.
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   123
     */
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   124
    public boolean isRelational() {
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   125
        switch (tokenType()) {
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   126
        case LT:
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   127
        case GT:
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   128
        case LE:
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   129
        case GE:
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   130
            return true;
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   131
        default:
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   132
            return false;
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   133
        }
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   134
    }
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   135
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   136
    /**
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   137
     * Returns true if the node is a logical operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   138
     * @return true if the node is a logical operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   139
     */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   140
    public boolean isLogical() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   141
        return isLogical(tokenType());
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   142
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   143
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   144
    /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   145
     * Returns true if the token type represents a logical operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   146
     * @param tokenType the token type
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   147
     * @return true if the token type represents a logical operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   148
     */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   149
    public static boolean isLogical(final TokenType tokenType) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   150
        switch (tokenType) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   151
        case AND:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   152
        case OR:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   153
            return true;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   154
        default:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   155
            return false;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   156
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   157
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   158
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   159
    /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   160
     * Return the widest possible operand type for this operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   161
     *
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   162
     * @return Type
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   163
     */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   164
    public Type getWidestOperandType() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   165
        switch (tokenType()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   166
        case SHR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   167
        case ASSIGN_SHR:
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   168
            return Type.INT;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   169
        case INSTANCEOF:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   170
            return Type.OBJECT;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   171
        default:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   172
            if (isComparison()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   173
                return Type.OBJECT;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   174
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   175
            return getWidestOperationType();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   176
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   177
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   178
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   179
    @Override
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   180
    public Type getWidestOperationType() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   181
        switch (tokenType()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   182
        case ADD:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   183
        case ASSIGN_ADD: {
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   184
            // Compare this logic to decideType(Type, Type); it's similar, but it handles the optimistic type
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   185
            // calculation case while this handles the conservative case.
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   186
            final Type lhsType = lhs.getType();
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   187
            final Type rhsType = rhs.getType();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   188
            if(lhsType == Type.BOOLEAN && rhsType == Type.BOOLEAN) {
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   189
                // Will always fit in an int, as the value range is [0, 1, 2]. If we didn't treat them specially here,
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   190
                // they'd end up being treated as generic INT operands and their sum would be conservatively considered
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   191
                // to be a LONG in the generic case below; we can do better here.
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   192
                return Type.INT;
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   193
            } else if(isString(lhsType) || isString(rhsType)) {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   194
                // We can statically figure out that this is a string if either operand is a string. In this case, use
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   195
                // CHARSEQUENCE to prevent it from being proactively flattened.
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   196
                return Type.CHARSEQUENCE;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   197
            }
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   198
            final Type widestOperandType = Type.widest(undefinedToNumber(booleanToInt(lhsType)), undefinedToNumber(booleanToInt(rhsType)));
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   199
            if(widestOperandType == Type.INT) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   200
                return Type.LONG;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   201
            } else if (widestOperandType.isNumeric()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   202
                return Type.NUMBER;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   203
            }
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   204
            // We pretty much can't know what it will be statically. Must presume OBJECT conservatively, as we can end
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   205
            // up getting either a string or an object when adding something + object, e.g.:
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   206
            // 1 + {} == "1[object Object]", but
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   207
            // 1 + {valueOf: function() { return 2 }} == 3. Also:
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   208
            // 1 + {valueOf: function() { return "2" }} == "12".
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   209
            return Type.OBJECT;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   210
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   211
        case SHR:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   212
        case ASSIGN_SHR:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   213
            return Type.LONG;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   214
        case ASSIGN_SAR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   215
        case ASSIGN_SHL:
21457
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   216
        case BIT_AND:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   217
        case BIT_OR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   218
        case BIT_XOR:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   219
        case ASSIGN_BIT_AND:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
        case ASSIGN_BIT_OR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   221
        case ASSIGN_BIT_XOR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   222
        case SAR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   223
        case SHL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   224
            return Type.INT;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   225
        case DIV:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   226
        case MOD:
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   227
        case ASSIGN_DIV:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   228
        case ASSIGN_MOD: {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   229
            // Naively, one might think MOD has the same type as the widest of its operands, this is unfortunately not
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   230
            // true when denominator is zero, so even type(int % int) == double.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   231
            return Type.NUMBER;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   232
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   233
        case MUL:
19472
9476460521b3 8023017: SUB missing for widest op == number for BinaryNode
lagergren
parents: 18867
diff changeset
   234
        case SUB:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   235
        case ASSIGN_MUL:
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   236
        case ASSIGN_SUB: {
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   237
            final Type lhsType = lhs.getType();
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   238
            final Type rhsType = rhs.getType();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   239
            if(lhsType == Type.BOOLEAN && rhsType == Type.BOOLEAN) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   240
                return Type.INT;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   241
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   242
            final Type widestOperandType = Type.widest(booleanToInt(lhsType), booleanToInt(rhsType));
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   243
            if(widestOperandType == Type.INT) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   244
                return Type.LONG;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   245
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   246
            return Type.NUMBER;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   247
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   248
        case VOID: {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   249
            return Type.UNDEFINED;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   250
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   251
        case ASSIGN: {
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   252
            return rhs.getType();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   253
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   254
        case INSTANCEOF: {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   255
            return Type.BOOLEAN;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   256
        }
24769
attila
parents: 24759
diff changeset
   257
        case COMMALEFT: {
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   258
            return lhs.getType();
24769
attila
parents: 24759
diff changeset
   259
        }
attila
parents: 24759
diff changeset
   260
        case COMMARIGHT: {
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   261
            return rhs.getType();
24769
attila
parents: 24759
diff changeset
   262
        }
27524
f34b84c9f880 8062799: Binary logical expressions can have numeric types
attila
parents: 27204
diff changeset
   263
        case AND:
f34b84c9f880 8062799: Binary logical expressions can have numeric types
attila
parents: 27204
diff changeset
   264
        case OR:{
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   265
            return Type.widestReturnType(lhs.getType(), rhs.getType());
27524
f34b84c9f880 8062799: Binary logical expressions can have numeric types
attila
parents: 27204
diff changeset
   266
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   267
        default:
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   268
            if (isComparison()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   269
                return Type.BOOLEAN;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   270
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   271
            return Type.OBJECT;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   272
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   273
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   274
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   275
    private static boolean isString(final Type type) {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   276
        return type == Type.STRING || type == Type.CHARSEQUENCE;
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   277
    }
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   278
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   279
    private static Type booleanToInt(final Type type) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   280
        return type == Type.BOOLEAN ? Type.INT : type;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   281
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   282
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   283
    private static Type undefinedToNumber(final Type type) {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   284
        return type == Type.UNDEFINED ? Type.NUMBER : type;
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   285
    }
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   286
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   287
    /**
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   288
     * Check if this node is an assignment
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   289
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   290
     * @return true if this node assigns a value
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   291
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   292
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   293
    public boolean isAssignment() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   294
        switch (tokenType()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   295
        case ASSIGN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   296
        case ASSIGN_ADD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   297
        case ASSIGN_BIT_AND:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   298
        case ASSIGN_BIT_OR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   299
        case ASSIGN_BIT_XOR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   300
        case ASSIGN_DIV:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   301
        case ASSIGN_MOD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   302
        case ASSIGN_MUL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   303
        case ASSIGN_SAR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   304
        case ASSIGN_SHL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   305
        case ASSIGN_SHR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   306
        case ASSIGN_SUB:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   307
           return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   308
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   309
           return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   310
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   311
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   312
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   313
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   314
    public boolean isSelfModifying() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   315
        return isAssignment() && tokenType() != TokenType.ASSIGN;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   316
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   317
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   318
    @Override
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   319
    public Expression getAssignmentDest() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   320
        return isAssignment() ? lhs() : null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   321
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   322
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   323
    @Override
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   324
    public BinaryNode setAssignmentDest(final Expression n) {
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16269
diff changeset
   325
        return setLHS(n);
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16269
diff changeset
   326
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16269
diff changeset
   327
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16269
diff changeset
   328
    @Override
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   329
    public Expression getAssignmentSource() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   330
        return rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   331
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   332
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   333
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   334
     * Assist in IR navigation.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   335
     * @param visitor IR navigating visitor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   336
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   337
    @Override
17769
14ea7feaf658 8012522: Clean up lexical contexts - split out stack based functionality in CodeGenerator and generify NodeVisitors based on their LexicalContext type to avoid casts
lagergren
parents: 17756
diff changeset
   338
    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   339
        if (visitor.enterBinaryNode(this)) {
27969
c03b64ccbd0f 8066227: CodeGenerator load unitialized slot
attila
parents: 27524
diff changeset
   340
            return visitor.leaveBinaryNode(setLHS((Expression)lhs.accept(visitor)).setRHS((Expression)rhs.accept(visitor)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   341
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   342
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   343
        return this;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   344
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   345
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   346
    @Override
21457
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   347
    public boolean isLocal() {
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   348
        switch (tokenType()) {
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   349
        case SAR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   350
        case SHL:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   351
        case SHR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   352
        case BIT_AND:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   353
        case BIT_OR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   354
        case BIT_XOR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   355
        case ADD:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   356
        case DIV:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   357
        case MOD:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   358
        case MUL:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   359
        case SUB:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   360
            return lhs.isLocal() && lhs.getType().isJSPrimitive()
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   361
                && rhs.isLocal() && rhs.getType().isJSPrimitive();
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   362
        case ASSIGN_ADD:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   363
        case ASSIGN_BIT_AND:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   364
        case ASSIGN_BIT_OR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   365
        case ASSIGN_BIT_XOR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   366
        case ASSIGN_DIV:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   367
        case ASSIGN_MOD:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   368
        case ASSIGN_MUL:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   369
        case ASSIGN_SAR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   370
        case ASSIGN_SHL:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   371
        case ASSIGN_SHR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   372
        case ASSIGN_SUB:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   373
            return lhs instanceof IdentNode && lhs.isLocal() && lhs.getType().isJSPrimitive()
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   374
                    && rhs.isLocal() && rhs.getType().isJSPrimitive();
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   375
        case ASSIGN:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   376
            return lhs instanceof IdentNode && lhs.isLocal() && rhs.isLocal();
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   377
        default:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   378
            return false;
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   379
        }
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   380
    }
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   381
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   382
    @Override
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   383
    public boolean isAlwaysFalse() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   384
        switch (tokenType()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   385
        case COMMALEFT:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   386
            return lhs.isAlwaysFalse();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   387
        case COMMARIGHT:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   388
            return rhs.isAlwaysFalse();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   389
        default:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   390
            return false;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   391
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   392
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   393
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   394
    @Override
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   395
    public boolean isAlwaysTrue() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   396
        switch (tokenType()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   397
        case COMMALEFT:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   398
            return lhs.isAlwaysTrue();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   399
        case COMMARIGHT:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   400
            return rhs.isAlwaysTrue();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   401
        default:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   402
            return false;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   403
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   404
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   405
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   406
    @Override
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   407
    public void toString(final StringBuilder sb, final boolean printType) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   408
        final TokenType tokenType = tokenType();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   409
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   410
        final boolean lhsParen = tokenType.needsParens(lhs().tokenType(), true);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   411
        final boolean rhsParen = tokenType.needsParens(rhs().tokenType(), false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   412
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   413
        if (lhsParen) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   414
            sb.append('(');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   416
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   417
        lhs().toString(sb, printType);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   418
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
        if (lhsParen) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   420
            sb.append(')');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   421
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   422
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   423
        sb.append(' ');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   424
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   425
        switch (tokenType) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
        case COMMALEFT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   427
            sb.append(",<");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   428
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   429
        case COMMARIGHT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   430
            sb.append(",>");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   431
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   432
        case INCPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   433
        case DECPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   434
            sb.append("++");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   435
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   436
        default:
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   437
            sb.append(tokenType.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   438
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   439
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   440
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   441
        if (isOptimistic()) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   442
            sb.append(Expression.OPT_IDENTIFIER);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   443
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   444
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   445
        sb.append(' ');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   446
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   447
        if (rhsParen) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   448
            sb.append('(');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   449
        }
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   450
        rhs().toString(sb, printType);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   451
        if (rhsParen) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   452
            sb.append(')');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   453
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   454
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   455
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   456
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   457
     * Get the left hand side expression for this node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   458
     * @return the left hand side expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   459
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   460
    public Expression lhs() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   461
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   462
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   463
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   464
    /**
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   465
     * Get the right hand side expression for this node
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   466
     * @return the left hand side expression
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   467
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   468
    public Expression rhs() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   469
        return rhs;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   470
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   471
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   472
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   473
     * Set the left hand side expression for this node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   474
     * @param lhs new left hand side expression
16530
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16269
diff changeset
   475
     * @return a node equivalent to this one except for the requested change.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   476
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   477
    public BinaryNode setLHS(final Expression lhs) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   478
        if (this.lhs == lhs) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   479
            return this;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   480
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   481
        return new BinaryNode(this, lhs, rhs, type, programPoint);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   482
    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   483
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   484
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   485
     * Set the right hand side expression for this node
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   486
     * @param rhs new right hand side expression
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   487
     * @return a node equivalent to this one except for the requested change.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   488
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   489
    public BinaryNode setRHS(final Expression rhs) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   490
        if (this.rhs == rhs) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   491
            return this;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   492
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   493
        return new BinaryNode(this, lhs, rhs, type, programPoint);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   494
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   495
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   496
    /**
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   497
     * Set both the left and the right hand side expression for this node
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   498
     * @param lhs new left hand side expression
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   499
     * @param rhs new left hand side expression
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   500
     * @return a node equivalent to this one except for the requested change.
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   501
     */
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   502
    public BinaryNode setOperands(final Expression lhs, final Expression rhs) {
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   503
        if (this.lhs == lhs && this.rhs == rhs) {
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   504
            return this;
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   505
        }
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   506
        return new BinaryNode(this, lhs, rhs, type, programPoint);
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   507
    }
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   508
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   509
    @Override
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   510
    public int getProgramPoint() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   511
        return programPoint;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   512
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   513
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   514
    @Override
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   515
    public boolean canBeOptimistic() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   516
        return isTokenType(TokenType.ADD) || (getMostOptimisticType() != getMostPessimisticType());
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   517
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   518
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   519
    @Override
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   520
    public BinaryNode setProgramPoint(final int programPoint) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   521
        if (this.programPoint == programPoint) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   522
            return this;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   523
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   524
        return new BinaryNode(this, lhs, rhs, type, programPoint);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   525
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   526
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   527
    @Override
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   528
    public Type getMostOptimisticType() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   529
        final TokenType tokenType = tokenType();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   530
        if(tokenType == TokenType.ADD || tokenType == TokenType.ASSIGN_ADD) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   531
            return OPTIMISTIC_UNDECIDED_TYPE;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   532
        } else if (CAN_OVERFLOW.contains(tokenType())) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   533
            return Type.INT;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   534
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   535
        return getMostPessimisticType();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   536
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   537
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   538
    @Override
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   539
    public Type getMostPessimisticType() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   540
        return getWidestOperationType();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   541
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   542
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   543
    /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   544
     * Returns true if the node has the optimistic type of the node is not yet decided. Optimistic ADD nodes start out
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   545
     * as undecided until we can figure out if they're numeric or not.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   546
     * @return true if the node has the optimistic type of the node is not yet decided.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   547
     */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   548
    public boolean isOptimisticUndecidedType() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   549
        return type == OPTIMISTIC_UNDECIDED_TYPE;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   550
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   551
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   552
    @Override
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   553
    public Type getType() {
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   554
        if (cachedType == null) {
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   555
            cachedType = getTypeUncached();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   556
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   557
        return cachedType;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   558
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   559
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   560
    private Type getTypeUncached() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   561
        if(type == OPTIMISTIC_UNDECIDED_TYPE) {
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   562
            return decideType(lhs.getType(), rhs.getType());
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   563
        }
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   564
        final Type widest = getWidestOperationType();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   565
        if(type == null) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   566
            return widest;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   567
        }
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   568
        return Type.narrowest(widest, Type.widest(type, Type.widest(lhs.getType(), rhs.getType())));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   569
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   570
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   571
    private static Type decideType(final Type lhsType, final Type rhsType) {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   572
        // Compare this to getWidestOperationType() for ADD and ASSIGN_ADD cases. There's some similar logic, but these
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   573
        // are optimistic decisions, meaning that we don't have to treat boolean addition separately (as it'll become
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   574
        // int addition in the general case anyway), and that we also don't conservatively widen sums of ints to
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   575
        // longs, or sums of longs to doubles.
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   576
        if(isString(lhsType) || isString(rhsType)) {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   577
            return Type.CHARSEQUENCE;
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   578
        }
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   579
        // NOTE: We don't have optimistic object-to-(int, long) conversions. Therefore, if any operand is an Object, we
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   580
        // bail out of optimism here and presume a conservative Object return value, as the object's ToPrimitive() can
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   581
        // end up returning either a number or a string, and their common supertype is Object, for better or worse.
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   582
        final Type widest = Type.widest(undefinedToNumber(booleanToInt(lhsType)), undefinedToNumber(booleanToInt(rhsType)));
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   583
        return widest.isObject() ? Type.OBJECT : widest;
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   584
    }
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   585
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   586
    /**
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   587
     * If the node is a node representing an add operation and has {@link #isOptimisticUndecidedType() optimistic
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   588
     * undecided type}, decides its type. Should be invoked after its operands types have been finalized.
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   589
     * @return returns a new node similar to this node, but with its type set to the type decided from the type of its
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   590
     * operands.
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   591
     */
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   592
    public BinaryNode decideType() {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   593
        assert type == OPTIMISTIC_UNDECIDED_TYPE;
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   594
        return setType(decideType(lhs.getType(), rhs.getType()));
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   595
    }
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   596
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   597
    @Override
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   598
    public BinaryNode setType(final Type type) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   599
        if (this.type == type) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   600
            return this;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   601
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   602
        return new BinaryNode(this, lhs, rhs, type, programPoint);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   603
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   604
}