src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BinaryNode.java
author attila
Sun, 11 Feb 2018 12:41:56 +0100
changeset 48844 09e128cfff3e
parent 47216 71c04702a3d5
permissions -rw-r--r--
8193295: Remove no longer used COMMALEFT Reviewed-by: hannesw, mhaupt
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,
34732
6605efbe8447 8144020: Remove long as an internal numeric type
hannesw
parents: 30392
diff changeset
    73
                TokenType.ASSIGN_SUB,
6605efbe8447 8144020: Remove long as an internal numeric type
hannesw
parents: 30392
diff changeset
    74
                TokenType.SHR,
6605efbe8447 8144020: Remove long as an internal numeric type
hannesw
parents: 30392
diff changeset
    75
                TokenType.ASSIGN_SHR
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    76
            })));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    77
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
     * @param token  token
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    82
     * @param lhs    left hand side
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    83
     * @param rhs    right hand side
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    84
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
    85
    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
    86
        super(token, lhs.getStart(), rhs.getFinish());
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    87
        assert !(isTokenType(TokenType.AND) || isTokenType(TokenType.OR)) || lhs instanceof JoinPredecessorExpression;
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    88
        this.lhs   = lhs;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    89
        this.rhs   = rhs;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    90
        this.programPoint = INVALID_PROGRAM_POINT;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    91
        this.type = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    92
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    93
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
    94
    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
    95
        super(binaryNode);
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    96
        this.lhs = lhs;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
    97
        this.rhs = rhs;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    98
        this.programPoint = programPoint;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
    99
        this.type = type;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   101
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   102
    /**
29283
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   103
     * 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
   104
     * @return true if the node is a comparison operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   105
     */
17756
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   106
    public boolean isComparison() {
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   107
        switch (tokenType()) {
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   108
        case EQ:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   109
        case EQ_STRICT:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   110
        case NE:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   111
        case NE_STRICT:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   112
        case LE:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   113
        case LT:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   114
        case GE:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   115
        case GT:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   116
            return true;
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   117
        default:
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   118
            return false;
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   119
        }
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   120
    }
daaa1e643f71 8006069: Range analysis first iteration, runtime specializations
lagergren
parents: 17523
diff changeset
   121
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
    /**
29283
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   123
     * 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
   124
     * @return true if the node is a relational operation.
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   125
     */
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   126
    public boolean isRelational() {
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   127
        switch (tokenType()) {
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   128
        case LT:
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   129
        case GT:
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   130
        case LE:
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   131
        case GE:
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   132
            return true;
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   133
        default:
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   134
            return false;
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
    }
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   137
fb47e4d25a9f 8035712: Restore some of the RuntimeCallSite specializations
attila
parents: 28130
diff changeset
   138
    /**
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   139
     * Returns true if the node is a logical operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   140
     * @return true if the node is a logical operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   141
     */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   142
    public boolean isLogical() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   143
        return isLogical(tokenType());
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   144
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   145
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   146
    /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   147
     * Returns true if the token type represents a logical operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   148
     * @param tokenType the token type
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   149
     * @return true if the token type represents a logical operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   150
     */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   151
    public static boolean isLogical(final TokenType tokenType) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   152
        switch (tokenType) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   153
        case AND:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   154
        case OR:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   155
            return true;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   156
        default:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   157
            return false;
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
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 the widest possible operand type for this operation.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   163
     *
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   164
     * @return Type
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   165
     */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   166
    public Type getWidestOperandType() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   167
        switch (tokenType()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   168
        case SHR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   169
        case ASSIGN_SHR:
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   170
            return Type.INT;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   171
        case INSTANCEOF:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   172
            return Type.OBJECT;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   173
        default:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   174
            if (isComparison()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   175
                return Type.OBJECT;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   176
            }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   177
            return getWidestOperationType();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   178
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   179
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   180
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   181
    @Override
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   182
    public Type getWidestOperationType() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   183
        switch (tokenType()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   184
        case ADD:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   185
        case ASSIGN_ADD: {
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   186
            // 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
   187
            // 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
   188
            final Type lhsType = lhs.getType();
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   189
            final Type rhsType = rhs.getType();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   190
            if(lhsType == Type.BOOLEAN && rhsType == Type.BOOLEAN) {
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   191
                // 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
   192
                // 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
   193
                // 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
   194
                return Type.INT;
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   195
            } else if(isString(lhsType) || isString(rhsType)) {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   196
                // 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
   197
                // CHARSEQUENCE to prevent it from being proactively flattened.
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   198
                return Type.CHARSEQUENCE;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   199
            }
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   200
            final Type widestOperandType = Type.widest(undefinedToNumber(booleanToInt(lhsType)), undefinedToNumber(booleanToInt(rhsType)));
34732
6605efbe8447 8144020: Remove long as an internal numeric type
hannesw
parents: 30392
diff changeset
   201
            if (widestOperandType.isNumeric()) {
24751
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:
34732
6605efbe8447 8144020: Remove long as an internal numeric type
hannesw
parents: 30392
diff changeset
   213
            return Type.NUMBER;
16147
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
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   242
            return Type.NUMBER;
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   243
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   244
        case VOID: {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   245
            return Type.UNDEFINED;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   246
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   247
        case ASSIGN: {
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   248
            return rhs.getType();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   249
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   250
        case INSTANCEOF: {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   251
            return Type.BOOLEAN;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   252
        }
24769
attila
parents: 24759
diff changeset
   253
        case COMMARIGHT: {
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   254
            return rhs.getType();
24769
attila
parents: 24759
diff changeset
   255
        }
27524
f34b84c9f880 8062799: Binary logical expressions can have numeric types
attila
parents: 27204
diff changeset
   256
        case AND:
f34b84c9f880 8062799: Binary logical expressions can have numeric types
attila
parents: 27204
diff changeset
   257
        case OR:{
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   258
            return Type.widestReturnType(lhs.getType(), rhs.getType());
27524
f34b84c9f880 8062799: Binary logical expressions can have numeric types
attila
parents: 27204
diff changeset
   259
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   260
        default:
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   261
            if (isComparison()) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   262
                return Type.BOOLEAN;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   263
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   264
            return Type.OBJECT;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   265
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   266
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   267
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   268
    private static boolean isString(final Type type) {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   269
        return type == Type.STRING || type == Type.CHARSEQUENCE;
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   270
    }
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   271
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   272
    private static Type booleanToInt(final Type type) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   273
        return type == Type.BOOLEAN ? Type.INT : type;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   274
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   275
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   276
    private static Type undefinedToNumber(final Type type) {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   277
        return type == Type.UNDEFINED ? Type.NUMBER : type;
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   278
    }
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   279
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   280
    /**
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   281
     * Check if this node is an assignment
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   282
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   283
     * @return true if this node assigns a value
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   284
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   285
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   286
    public boolean isAssignment() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   287
        switch (tokenType()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   288
        case ASSIGN:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   289
        case ASSIGN_ADD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   290
        case ASSIGN_BIT_AND:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   291
        case ASSIGN_BIT_OR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   292
        case ASSIGN_BIT_XOR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   293
        case ASSIGN_DIV:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   294
        case ASSIGN_MOD:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   295
        case ASSIGN_MUL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   296
        case ASSIGN_SAR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   297
        case ASSIGN_SHL:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   298
        case ASSIGN_SHR:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   299
        case ASSIGN_SUB:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   300
           return true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   301
        default:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   302
           return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   303
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   304
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   305
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   306
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   307
    public boolean isSelfModifying() {
30392
dc4a419b2982 8079362: Enforce best practices for Node token API usage
attila
parents: 29283
diff changeset
   308
        return isAssignment() && !isTokenType(TokenType.ASSIGN);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   309
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   310
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   311
    @Override
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   312
    public Expression getAssignmentDest() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   313
        return isAssignment() ? lhs() : null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   314
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   315
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   316
    @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
   317
    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
   318
        return setLHS(n);
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16269
diff changeset
   319
    }
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16269
diff changeset
   320
201d682e75f4 8010652: Eliminate non-child references in Block/FunctionNode, and make few node types immutable
attila
parents: 16269
diff changeset
   321
    @Override
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   322
    public Expression getAssignmentSource() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   323
        return rhs();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   324
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   325
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   326
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   327
     * Assist in IR navigation.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   328
     * @param visitor IR navigating visitor.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   329
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   330
    @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
   331
    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   332
        if (visitor.enterBinaryNode(this)) {
27969
c03b64ccbd0f 8066227: CodeGenerator load unitialized slot
attila
parents: 27524
diff changeset
   333
            return visitor.leaveBinaryNode(setLHS((Expression)lhs.accept(visitor)).setRHS((Expression)rhs.accept(visitor)));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   334
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   335
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   336
        return this;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   337
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   338
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   339
    @Override
21457
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   340
    public boolean isLocal() {
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   341
        switch (tokenType()) {
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   342
        case SAR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   343
        case SHL:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   344
        case SHR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   345
        case BIT_AND:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   346
        case BIT_OR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   347
        case BIT_XOR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   348
        case ADD:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   349
        case DIV:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   350
        case MOD:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   351
        case MUL:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   352
        case SUB:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   353
            return lhs.isLocal() && lhs.getType().isJSPrimitive()
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   354
                && rhs.isLocal() && rhs.getType().isJSPrimitive();
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   355
        case ASSIGN_ADD:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   356
        case ASSIGN_BIT_AND:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   357
        case ASSIGN_BIT_OR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   358
        case ASSIGN_BIT_XOR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   359
        case ASSIGN_DIV:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   360
        case ASSIGN_MOD:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   361
        case ASSIGN_MUL:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   362
        case ASSIGN_SAR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   363
        case ASSIGN_SHL:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   364
        case ASSIGN_SHR:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   365
        case ASSIGN_SUB:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   366
            return lhs instanceof IdentNode && lhs.isLocal() && lhs.getType().isJSPrimitive()
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   367
                    && rhs.isLocal() && rhs.getType().isJSPrimitive();
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   368
        case ASSIGN:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   369
            return lhs instanceof IdentNode && lhs.isLocal() && rhs.isLocal();
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   370
        default:
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   371
            return false;
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   372
        }
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   373
    }
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   374
381acbd07fe5 8027042: Evaluation order for binary operators can be improved
hannesw
parents: 19472
diff changeset
   375
    @Override
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   376
    public boolean isAlwaysFalse() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   377
        switch (tokenType()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   378
        case COMMARIGHT:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   379
            return rhs.isAlwaysFalse();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   380
        default:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   381
            return false;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   382
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   383
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   384
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   385
    @Override
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   386
    public boolean isAlwaysTrue() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   387
        switch (tokenType()) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   388
        case COMMARIGHT:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   389
            return rhs.isAlwaysTrue();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   390
        default:
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   391
            return false;
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
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   395
    @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
   396
    public void toString(final StringBuilder sb, final boolean printType) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   397
        final TokenType tokenType = tokenType();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   398
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   399
        final boolean lhsParen = tokenType.needsParens(lhs().tokenType(), true);
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   400
        final boolean rhsParen = tokenType.needsParens(rhs().tokenType(), false);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   401
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   402
        if (lhsParen) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   403
            sb.append('(');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   404
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   405
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   406
        lhs().toString(sb, printType);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   407
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   408
        if (lhsParen) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   409
            sb.append(')');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   410
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   411
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   412
        sb.append(' ');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   413
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   414
        switch (tokenType) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
        case COMMARIGHT:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   416
            sb.append(",>");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   417
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   418
        case INCPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
        case DECPREFIX:
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   420
            sb.append("++");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   421
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   422
        default:
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   423
            sb.append(tokenType.getName());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   424
            break;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   425
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   427
        if (isOptimistic()) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   428
            sb.append(Expression.OPT_IDENTIFIER);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   429
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   430
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   431
        sb.append(' ');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   432
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   433
        if (rhsParen) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   434
            sb.append('(');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   435
        }
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24751
diff changeset
   436
        rhs().toString(sb, printType);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   437
        if (rhsParen) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   438
            sb.append(')');
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   439
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   440
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   441
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   442
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   443
     * Get the left hand side expression for this node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   444
     * @return the left hand side expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   445
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   446
    public Expression lhs() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   447
        return lhs;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   448
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   449
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   450
    /**
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   451
     * Get the right hand side expression for this node
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   452
     * @return the left hand side expression
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   453
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   454
    public Expression rhs() {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   455
        return rhs;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   456
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   457
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   458
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   459
     * Set the left hand side expression for this node
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   460
     * @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
   461
     * @return a node equivalent to this one except for the requested change.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   462
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   463
    public BinaryNode setLHS(final Expression lhs) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   464
        if (this.lhs == lhs) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   465
            return this;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   466
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   467
        return new BinaryNode(this, lhs, rhs, type, programPoint);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   468
    }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   469
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   470
    /**
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   471
     * 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
   472
     * @param rhs new right hand side expression
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   473
     * @return a node equivalent to this one except for the requested change.
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   474
     */
18867
bc91e3fcc5ba 8013925: Remove symbol fields from nodes that don't need them
attila
parents: 17769
diff changeset
   475
    public BinaryNode setRHS(final Expression rhs) {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   476
        if (this.rhs == rhs) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   477
            return this;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   478
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   479
        return new BinaryNode(this, lhs, rhs, type, programPoint);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   480
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   481
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   482
    /**
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   483
     * 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
   484
     * @param lhs new left hand side expression
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   485
     * @param rhs new left hand side expression
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   486
     * @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
   487
     */
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   488
    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
   489
        if (this.lhs == lhs && this.rhs == rhs) {
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   490
            return this;
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   491
        }
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   492
        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
   493
    }
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   494
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   495
    @Override
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   496
    public int getProgramPoint() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   497
        return programPoint;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   498
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   499
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   500
    @Override
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   501
    public boolean canBeOptimistic() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   502
        return isTokenType(TokenType.ADD) || (getMostOptimisticType() != getMostPessimisticType());
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   503
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   504
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   505
    @Override
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   506
    public BinaryNode setProgramPoint(final int programPoint) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   507
        if (this.programPoint == programPoint) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   508
            return this;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   509
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   510
        return new BinaryNode(this, lhs, rhs, type, programPoint);
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   511
    }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16530
diff changeset
   512
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   513
    @Override
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   514
    public Type getMostOptimisticType() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   515
        final TokenType tokenType = tokenType();
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   516
        if(tokenType == TokenType.ADD || tokenType == TokenType.ASSIGN_ADD) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   517
            return OPTIMISTIC_UNDECIDED_TYPE;
30392
dc4a419b2982 8079362: Enforce best practices for Node token API usage
attila
parents: 29283
diff changeset
   518
        } else if (CAN_OVERFLOW.contains(tokenType)) {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   519
            return Type.INT;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   520
        }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   521
        return getMostPessimisticType();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   522
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   523
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   524
    @Override
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   525
    public Type getMostPessimisticType() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   526
        return getWidestOperationType();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   527
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   528
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   529
    /**
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   530
     * 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
   531
     * as undecided until we can figure out if they're numeric or not.
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   532
     * @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
   533
     */
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   534
    public boolean isOptimisticUndecidedType() {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   535
        return type == OPTIMISTIC_UNDECIDED_TYPE;
24719
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
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   539
    public Type getType() {
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   540
        if (cachedType == null) {
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   541
            cachedType = getTypeUncached();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   542
        }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   543
        return cachedType;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   544
    }
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   545
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   546
    private Type getTypeUncached() {
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   547
        if(type == OPTIMISTIC_UNDECIDED_TYPE) {
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   548
            return decideType(lhs.getType(), rhs.getType());
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   549
        }
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   550
        final Type widest = getWidestOperationType();
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   551
        if(type == null) {
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   552
            return widest;
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   553
        }
34732
6605efbe8447 8144020: Remove long as an internal numeric type
hannesw
parents: 30392
diff changeset
   554
        if (tokenType() == TokenType.ASSIGN_SHR || tokenType() == TokenType.SHR) {
6605efbe8447 8144020: Remove long as an internal numeric type
hannesw
parents: 30392
diff changeset
   555
            return type;
6605efbe8447 8144020: Remove long as an internal numeric type
hannesw
parents: 30392
diff changeset
   556
        }
28130
433d6755c5f8 8067774: Use a stack of types when calculating local variable types
attila
parents: 27969
diff changeset
   557
        return Type.narrowest(widest, Type.widest(type, Type.widest(lhs.getType(), rhs.getType())));
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   558
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   559
25829
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   560
    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
   561
        // 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
   562
        // 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
   563
        // 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
   564
        // longs, or sums of longs to doubles.
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   565
        if(isString(lhsType) || isString(rhsType)) {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   566
            return Type.CHARSEQUENCE;
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   567
        }
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   568
        // 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
   569
        // 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
   570
        // 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
   571
        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
   572
        return widest.isObject() ? Type.OBJECT : widest;
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   573
    }
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   574
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   575
    /**
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   576
     * 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
   577
     * 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
   578
     * @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
   579
     * operands.
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   580
     */
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   581
    public BinaryNode decideType() {
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   582
        assert type == OPTIMISTIC_UNDECIDED_TYPE;
1a5e1de71e57 8051439: Wrong type calculated for ADD operator with undefined operand
attila
parents: 24993
diff changeset
   583
        return setType(decideType(lhs.getType(), rhs.getType()));
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
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   586
    @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
   587
    public BinaryNode setType(final Type type) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   588
        if (this.type == type) {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   589
            return this;
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   590
        }
24751
ccbd9cd3f720 8042118: Separate types from symbols
attila
parents: 24719
diff changeset
   591
        return new BinaryNode(this, lhs, rhs, type, programPoint);
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 21457
diff changeset
   592
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   593
}