8013925: Remove symbol fields from nodes that don't need them

Thu, 11 Jul 2013 18:33:33 +0200

author
attila
date
Thu, 11 Jul 2013 18:33:33 +0200
changeset 430
2c007a8bb0e7
parent 429
58614b556a0d
child 431
9083af56bbcb

8013925: Remove symbol fields from nodes that don't need them
Reviewed-by: jlaskey, lagergren

src/jdk/nashorn/internal/codegen/Attr.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/BranchOptimizer.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/CodeGenerator.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/CompilationPhase.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/FinalizeTypes.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/FoldConstants.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/FunctionSignature.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/Lower.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/RangeAnalyzer.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/SpillObjectCreator.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/Splitter.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/WeighNodes.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/AccessNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/Assignment.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/BaseNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/BinaryNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/Block.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/BlockStatement.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/BreakableNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/BreakableStatement.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/CallNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/CaseNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/CatchNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/ExecuteNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/Expression.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/ExpressionStatement.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/ForNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/FunctionNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/IdentNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/IfNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/IndexNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/LabelNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/LexicalContext.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/LexicalContextExpression.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/LexicalContextNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/LexicalContextStatement.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/LiteralNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/LoopNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/Node.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/ObjectNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/PropertyNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/ReturnNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/RuntimeNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/SplitNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/SwitchNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/TemporarySymbols.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/TernaryNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/ThrowNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/UnaryNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/VarNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/WhileNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/WithNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/debug/ASTWriter.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/debug/JSONWriter.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/debug/PrintVisitor.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/parser/JSONParser.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/parser/Parser.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java file | annotate | diff | comparison | revisions
test/script/trusted/JDK-8006529.js file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/internal/codegen/Attr.java	Thu Jul 11 18:23:13 2013 +0530
     1.2 +++ b/src/jdk/nashorn/internal/codegen/Attr.java	Thu Jul 11 18:33:33 2013 +0200
     1.3 @@ -61,6 +61,7 @@
     1.4  import jdk.nashorn.internal.ir.CallNode;
     1.5  import jdk.nashorn.internal.ir.CaseNode;
     1.6  import jdk.nashorn.internal.ir.CatchNode;
     1.7 +import jdk.nashorn.internal.ir.Expression;
     1.8  import jdk.nashorn.internal.ir.ForNode;
     1.9  import jdk.nashorn.internal.ir.FunctionNode;
    1.10  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    1.11 @@ -72,7 +73,6 @@
    1.12  import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
    1.13  import jdk.nashorn.internal.ir.Node;
    1.14  import jdk.nashorn.internal.ir.ObjectNode;
    1.15 -import jdk.nashorn.internal.ir.PropertyNode;
    1.16  import jdk.nashorn.internal.ir.ReturnNode;
    1.17  import jdk.nashorn.internal.ir.RuntimeNode;
    1.18  import jdk.nashorn.internal.ir.RuntimeNode.Request;
    1.19 @@ -512,7 +512,6 @@
    1.20              assert nameSymbol != null;
    1.21  
    1.22              selfInit = selfInit.setName((IdentNode)name.setSymbol(lc, nameSymbol));
    1.23 -            selfInit = (VarNode)selfInit.setSymbol(lc, nameSymbol);
    1.24  
    1.25              newStatements.add(selfInit);
    1.26              newStatements.addAll(body.getStatements());
    1.27 @@ -740,14 +739,8 @@
    1.28      }
    1.29  
    1.30      @Override
    1.31 -    public Node leavePropertyNode(final PropertyNode propertyNode) {
    1.32 -        // assign a pseudo symbol to property name, see NASHORN-710
    1.33 -        return propertyNode.setSymbol(lc, new Symbol(propertyNode.getKeyName(), 0, Type.OBJECT));
    1.34 -    }
    1.35 -
    1.36 -    @Override
    1.37      public Node leaveReturnNode(final ReturnNode returnNode) {
    1.38 -        final Node expr = returnNode.getExpression();
    1.39 +        final Expression expr = returnNode.getExpression();
    1.40          final Type returnType;
    1.41  
    1.42          if (expr != null) {
    1.43 @@ -784,7 +777,7 @@
    1.44                      final LiteralNode<?> lit = (LiteralNode<?>)test;
    1.45                      if (lit.isNumeric() && !(lit.getValue() instanceof Integer)) {
    1.46                          if (JSType.isRepresentableAsInt(lit.getNumber())) {
    1.47 -                            newCaseNode = caseNode.setTest(LiteralNode.newInstance(lit, lit.getInt32()).accept(this));
    1.48 +                            newCaseNode = caseNode.setTest((Expression)LiteralNode.newInstance(lit, lit.getInt32()).accept(this));
    1.49                          }
    1.50                      }
    1.51                  } else {
    1.52 @@ -847,19 +840,18 @@
    1.53  
    1.54      @Override
    1.55      public Node leaveVarNode(final VarNode varNode) {
    1.56 -        VarNode newVarNode = varNode;
    1.57 +        final Expression init  = varNode.getInit();
    1.58 +        final IdentNode  ident = varNode.getName();
    1.59 +        final String     name  = ident.getName();
    1.60  
    1.61 -        final Node      init  = newVarNode.getInit();
    1.62 -        final IdentNode ident = newVarNode.getName();
    1.63 -        final String    name  = ident.getName();
    1.64 -
    1.65 -        final Symbol  symbol = findSymbol(lc.getCurrentBlock(), ident.getName());
    1.66 +        final Symbol  symbol = findSymbol(lc.getCurrentBlock(), name);
    1.67 +        assert ident.getSymbol() == symbol;
    1.68  
    1.69          if (init == null) {
    1.70              // var x; with no init will be treated like a use of x by
    1.71              // leaveIdentNode unless we remove the name from the localdef list.
    1.72              removeLocalDef(name);
    1.73 -            return end(newVarNode.setSymbol(lc, symbol));
    1.74 +            return end(varNode);
    1.75          }
    1.76  
    1.77          addLocalDef(name);
    1.78 @@ -868,8 +860,7 @@
    1.79  
    1.80          final IdentNode newIdent = (IdentNode)ident.setSymbol(lc, symbol);
    1.81  
    1.82 -        newVarNode = newVarNode.setName(newIdent);
    1.83 -        newVarNode = (VarNode)newVarNode.setSymbol(lc, symbol);
    1.84 +        final VarNode newVarNode = varNode.setName(newIdent);
    1.85  
    1.86          final boolean isScript = lc.getDefiningFunction(symbol).isProgram(); //see NASHORN-56
    1.87          if ((init.getType().isNumeric() || init.getType().isBoolean()) && !isScript) {
    1.88 @@ -879,7 +870,7 @@
    1.89              newType(symbol, Type.OBJECT);
    1.90          }
    1.91  
    1.92 -        assert newVarNode.hasType() : newVarNode + " has no type";
    1.93 +        assert newVarNode.getName().hasType() : newVarNode + " has no type";
    1.94  
    1.95          return end(newVarNode);
    1.96      }
    1.97 @@ -907,11 +898,11 @@
    1.98      public Node leaveDELETE(final UnaryNode unaryNode) {
    1.99          final FunctionNode   currentFunctionNode = lc.getCurrentFunction();
   1.100          final boolean        strictMode          = currentFunctionNode.isStrict();
   1.101 -        final Node           rhs                 = unaryNode.rhs();
   1.102 -        final Node           strictFlagNode      = LiteralNode.newInstance(unaryNode, strictMode).accept(this);
   1.103 +        final Expression     rhs                 = unaryNode.rhs();
   1.104 +        final Expression     strictFlagNode      = (Expression)LiteralNode.newInstance(unaryNode, strictMode).accept(this);
   1.105  
   1.106          Request request = Request.DELETE;
   1.107 -        final List<Node> args = new ArrayList<>();
   1.108 +        final List<Expression> args = new ArrayList<>();
   1.109  
   1.110          if (rhs instanceof IdentNode) {
   1.111              // If this is a declared variable or a function parameter, delete always fails (except for globals).
   1.112 @@ -922,7 +913,7 @@
   1.113              if (failDelete && rhs.getSymbol().isThis()) {
   1.114                  return LiteralNode.newInstance(unaryNode, true).accept(this);
   1.115              }
   1.116 -            final Node literalNode = LiteralNode.newInstance(unaryNode, name).accept(this);
   1.117 +            final Expression literalNode = (Expression)LiteralNode.newInstance(unaryNode, name).accept(this);
   1.118  
   1.119              if (!failDelete) {
   1.120                  args.add(compilerConstant(SCOPE));
   1.121 @@ -934,16 +925,17 @@
   1.122                  request = Request.FAIL_DELETE;
   1.123              }
   1.124          } else if (rhs instanceof AccessNode) {
   1.125 -            final Node      base     = ((AccessNode)rhs).getBase();
   1.126 -            final IdentNode property = ((AccessNode)rhs).getProperty();
   1.127 +            final Expression base     = ((AccessNode)rhs).getBase();
   1.128 +            final IdentNode  property = ((AccessNode)rhs).getProperty();
   1.129  
   1.130              args.add(base);
   1.131 -            args.add(LiteralNode.newInstance(unaryNode, property.getName()).accept(this));
   1.132 +            args.add((Expression)LiteralNode.newInstance(unaryNode, property.getName()).accept(this));
   1.133              args.add(strictFlagNode);
   1.134  
   1.135          } else if (rhs instanceof IndexNode) {
   1.136 -            final Node base  = ((IndexNode)rhs).getBase();
   1.137 -            final Node index = ((IndexNode)rhs).getIndex();
   1.138 +            final IndexNode indexNode = (IndexNode)rhs;
   1.139 +            final Expression base  = indexNode.getBase();
   1.140 +            final Expression index = indexNode.getIndex();
   1.141  
   1.142              args.add(base);
   1.143              args.add(index);
   1.144 @@ -998,15 +990,15 @@
   1.145  
   1.146      @Override
   1.147      public Node leaveTYPEOF(final UnaryNode unaryNode) {
   1.148 -        final Node rhs = unaryNode.rhs();
   1.149 +        final Expression rhs = unaryNode.rhs();
   1.150  
   1.151 -        List<Node> args = new ArrayList<>();
   1.152 +        List<Expression> args = new ArrayList<>();
   1.153          if (rhs instanceof IdentNode && !rhs.getSymbol().isParam() && !rhs.getSymbol().isVar()) {
   1.154              args.add(compilerConstant(SCOPE));
   1.155 -            args.add(LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName()).accept(this)); //null
   1.156 +            args.add((Expression)LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName()).accept(this)); //null
   1.157          } else {
   1.158              args.add(rhs);
   1.159 -            args.add(LiteralNode.newInstance(unaryNode).accept(this)); //null, do not reuse token of identifier rhs, it can be e.g. 'this'
   1.160 +            args.add((Expression)LiteralNode.newInstance(unaryNode).accept(this)); //null, do not reuse token of identifier rhs, it can be e.g. 'this'
   1.161          }
   1.162  
   1.163          RuntimeNode runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args);
   1.164 @@ -1040,8 +1032,8 @@
   1.165       */
   1.166      @Override
   1.167      public Node leaveADD(final BinaryNode binaryNode) {
   1.168 -        final Node lhs = binaryNode.lhs();
   1.169 -        final Node rhs = binaryNode.rhs();
   1.170 +        final Expression lhs = binaryNode.lhs();
   1.171 +        final Expression rhs = binaryNode.rhs();
   1.172  
   1.173          ensureTypeNotUnknown(lhs);
   1.174          ensureTypeNotUnknown(rhs);
   1.175 @@ -1096,8 +1088,8 @@
   1.176      private Node leaveAssignmentNode(final BinaryNode binaryNode) {
   1.177          BinaryNode newBinaryNode = binaryNode;
   1.178  
   1.179 -        final Node lhs = binaryNode.lhs();
   1.180 -        final Node rhs = binaryNode.rhs();
   1.181 +        final Expression lhs = binaryNode.lhs();
   1.182 +        final Expression rhs = binaryNode.rhs();
   1.183          final Type type;
   1.184  
   1.185          if (rhs.getType().isNumeric()) {
   1.186 @@ -1133,8 +1125,8 @@
   1.187  
   1.188      @Override
   1.189      public Node leaveASSIGN_ADD(final BinaryNode binaryNode) {
   1.190 -        final Node lhs = binaryNode.lhs();
   1.191 -        final Node rhs = binaryNode.rhs();
   1.192 +        final Expression lhs = binaryNode.lhs();
   1.193 +        final Expression rhs = binaryNode.rhs();
   1.194  
   1.195          final Type widest = Type.widest(lhs.getType(), rhs.getType());
   1.196          //Type.NUMBER if we can't prove that the add doesn't overflow. todo
   1.197 @@ -1413,13 +1405,13 @@
   1.198  
   1.199      @Override
   1.200      public Node leaveTernaryNode(final TernaryNode ternaryNode) {
   1.201 -        final Node lhs  = ternaryNode.rhs();
   1.202 -        final Node rhs  = ternaryNode.third();
   1.203 +        final Expression trueExpr  = ternaryNode.getTrueExpression();
   1.204 +        final Expression falseExpr = ternaryNode.getFalseExpression();
   1.205  
   1.206 -        ensureTypeNotUnknown(lhs);
   1.207 -        ensureTypeNotUnknown(rhs);
   1.208 +        ensureTypeNotUnknown(trueExpr);
   1.209 +        ensureTypeNotUnknown(falseExpr);
   1.210  
   1.211 -        final Type type = Type.widest(lhs.getType(), rhs.getType());
   1.212 +        final Type type = Type.widest(trueExpr.getType(), falseExpr.getType());
   1.213          return end(ensureSymbol(type, ternaryNode));
   1.214      }
   1.215  
   1.216 @@ -1537,7 +1529,7 @@
   1.217          }
   1.218      }
   1.219  
   1.220 -    private static void ensureTypeNotUnknown(final Node node) {
   1.221 +    private static void ensureTypeNotUnknown(final Expression node) {
   1.222  
   1.223          final Symbol symbol = node.getSymbol();
   1.224  
   1.225 @@ -1594,13 +1586,13 @@
   1.226       *
   1.227       * @param assignmentDest the destination node of the assignment, e.g. lhs for binary nodes
   1.228       */
   1.229 -    private Node ensureAssignmentSlots(final Node assignmentDest) {
   1.230 +    private Expression ensureAssignmentSlots(final Expression assignmentDest) {
   1.231          final LexicalContext attrLexicalContext = lc;
   1.232 -        return assignmentDest.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   1.233 +        return (Expression)assignmentDest.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   1.234              @Override
   1.235              public Node leaveIndexNode(final IndexNode indexNode) {
   1.236                  assert indexNode.getSymbol().isTemp();
   1.237 -                final Node index = indexNode.getIndex();
   1.238 +                final Expression index = indexNode.getIndex();
   1.239                  //only temps can be set as needing slots. the others will self resolve
   1.240                  //it is illegal to take a scope var and force it to be a slot, that breaks
   1.241                  Symbol indexSymbol = index.getSymbol();
   1.242 @@ -1642,7 +1634,7 @@
   1.243              changed.clear();
   1.244              final FunctionNode newFunctionNode = (FunctionNode)currentFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
   1.245  
   1.246 -                private Node widen(final Node node, final Type to) {
   1.247 +                private Expression widen(final Expression node, final Type to) {
   1.248                      if (node instanceof LiteralNode) {
   1.249                          return node;
   1.250                      }
   1.251 @@ -1654,7 +1646,7 @@
   1.252                              symbol = temporarySymbols.getTypedTemporarySymbol(to);
   1.253                          }
   1.254                          newType(symbol, to);
   1.255 -                        final Node newNode = node.setSymbol(lc, symbol);
   1.256 +                        final Expression newNode = node.setSymbol(lc, symbol);
   1.257                          changed.add(newNode);
   1.258                          return newNode;
   1.259                      }
   1.260 @@ -1709,7 +1701,7 @@
   1.261  
   1.262      private Node leaveSelfModifyingAssignmentNode(final BinaryNode binaryNode, final Type destType) {
   1.263          //e.g. for -=, Number, no wider, destType (binaryNode.getWidestOperationType())  is the coerce type
   1.264 -        final Node lhs = binaryNode.lhs();
   1.265 +        final Expression lhs = binaryNode.lhs();
   1.266  
   1.267          newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType
   1.268  //        ensureSymbol(destType, binaryNode); //for OP= nodes, the node can carry a narrower types than its lhs rhs. This is perfectly fine
   1.269 @@ -1717,9 +1709,9 @@
   1.270          return end(ensureSymbol(destType, ensureAssignmentSlots(binaryNode)));
   1.271      }
   1.272  
   1.273 -    private Node ensureSymbol(final Type type, final Node node) {
   1.274 +    private Expression ensureSymbol(final Type type, final Expression expr) {
   1.275          LOG.info("New TEMPORARY added to ", lc.getCurrentFunction().getName(), " type=", type);
   1.276 -        return temporarySymbols.ensureSymbol(lc, type, node);
   1.277 +        return temporarySymbols.ensureSymbol(lc, type, expr);
   1.278      }
   1.279  
   1.280      private Symbol newInternal(final String name, final Type type) {
   1.281 @@ -1841,11 +1833,11 @@
   1.282          return true;
   1.283      }
   1.284  
   1.285 -    private Node end(final Node node) {
   1.286 +    private <T extends Node> T end(final T node) {
   1.287          return end(node, true);
   1.288      }
   1.289  
   1.290 -    private Node end(final Node node, final boolean printNode) {
   1.291 +    private <T extends Node> T end(final T node, final boolean printNode) {
   1.292          if(node instanceof Statement) {
   1.293              // If we're done with a statement, all temporaries can be reused.
   1.294              temporarySymbols.reuse();
   1.295 @@ -1860,10 +1852,13 @@
   1.296                  append(" in '").
   1.297                  append(lc.getCurrentFunction().getName());
   1.298  
   1.299 -            if (node.getSymbol() == null) {
   1.300 -                sb.append(" <NO SYMBOL>");
   1.301 -            } else {
   1.302 -                sb.append(" <symbol=").append(node.getSymbol()).append('>');
   1.303 +            if(node instanceof Expression) {
   1.304 +                final Symbol symbol = ((Expression)node).getSymbol();
   1.305 +                if (symbol == null) {
   1.306 +                    sb.append(" <NO SYMBOL>");
   1.307 +                } else {
   1.308 +                    sb.append(" <symbol=").append(symbol).append('>');
   1.309 +                }
   1.310              }
   1.311  
   1.312              LOG.unindent();
     2.1 --- a/src/jdk/nashorn/internal/codegen/BranchOptimizer.java	Thu Jul 11 18:23:13 2013 +0530
     2.2 +++ b/src/jdk/nashorn/internal/codegen/BranchOptimizer.java	Thu Jul 11 18:33:33 2013 +0200
     2.3 @@ -34,7 +34,7 @@
     2.4  
     2.5  import jdk.nashorn.internal.codegen.types.Type;
     2.6  import jdk.nashorn.internal.ir.BinaryNode;
     2.7 -import jdk.nashorn.internal.ir.Node;
     2.8 +import jdk.nashorn.internal.ir.Expression;
     2.9  import jdk.nashorn.internal.ir.TernaryNode;
    2.10  import jdk.nashorn.internal.ir.UnaryNode;
    2.11  
    2.12 @@ -52,16 +52,16 @@
    2.13          this.method  = method;
    2.14      }
    2.15  
    2.16 -    void execute(final Node node, final Label label, final boolean state) {
    2.17 +    void execute(final Expression node, final Label label, final boolean state) {
    2.18          branchOptimizer(node, label, state);
    2.19      }
    2.20  
    2.21 -    private void load(final Node node) {
    2.22 +    private void load(final Expression node) {
    2.23          codegen.load(node);
    2.24      }
    2.25  
    2.26      private void branchOptimizer(final UnaryNode unaryNode, final Label label, final boolean state) {
    2.27 -        final Node rhs = unaryNode.rhs();
    2.28 +        final Expression rhs = unaryNode.rhs();
    2.29  
    2.30          switch (unaryNode.tokenType()) {
    2.31          case NOT:
    2.32 @@ -88,8 +88,8 @@
    2.33      }
    2.34  
    2.35      private void branchOptimizer(final BinaryNode binaryNode, final Label label, final boolean state) {
    2.36 -        final Node lhs = binaryNode.lhs();
    2.37 -        final Node rhs = binaryNode.rhs();
    2.38 +        final Expression lhs = binaryNode.lhs();
    2.39 +        final Expression rhs = binaryNode.rhs();
    2.40  
    2.41          switch (binaryNode.tokenType()) {
    2.42          case AND:
    2.43 @@ -173,7 +173,7 @@
    2.44          }
    2.45      }
    2.46  
    2.47 -    private void branchOptimizer(final Node node, final Label label, final boolean state) {
    2.48 +    private void branchOptimizer(final Expression node, final Label label, final boolean state) {
    2.49          if (!(node instanceof TernaryNode)) {
    2.50  
    2.51              if (node instanceof BinaryNode) {
     3.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Jul 11 18:23:13 2013 +0530
     3.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Jul 11 18:33:33 2013 +0200
     3.3 @@ -69,6 +69,7 @@
     3.4  import jdk.nashorn.internal.ir.BaseNode;
     3.5  import jdk.nashorn.internal.ir.BinaryNode;
     3.6  import jdk.nashorn.internal.ir.Block;
     3.7 +import jdk.nashorn.internal.ir.BlockStatement;
     3.8  import jdk.nashorn.internal.ir.BreakNode;
     3.9  import jdk.nashorn.internal.ir.BreakableNode;
    3.10  import jdk.nashorn.internal.ir.CallNode;
    3.11 @@ -76,7 +77,8 @@
    3.12  import jdk.nashorn.internal.ir.CatchNode;
    3.13  import jdk.nashorn.internal.ir.ContinueNode;
    3.14  import jdk.nashorn.internal.ir.EmptyNode;
    3.15 -import jdk.nashorn.internal.ir.ExecuteNode;
    3.16 +import jdk.nashorn.internal.ir.Expression;
    3.17 +import jdk.nashorn.internal.ir.ExpressionStatement;
    3.18  import jdk.nashorn.internal.ir.ForNode;
    3.19  import jdk.nashorn.internal.ir.FunctionNode;
    3.20  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    3.21 @@ -350,11 +352,11 @@
    3.22       *
    3.23       * @return the method emitter used
    3.24       */
    3.25 -    MethodEmitter load(final Node node) {
    3.26 +    MethodEmitter load(final Expression node) {
    3.27          return load(node, false);
    3.28      }
    3.29  
    3.30 -    private MethodEmitter load(final Node node, final boolean baseAlreadyOnStack) {
    3.31 +    private MethodEmitter load(final Expression node, final boolean baseAlreadyOnStack) {
    3.32          final Symbol symbol = node.getSymbol();
    3.33  
    3.34          // If we lack symbols, we just generate what we see.
    3.35 @@ -539,11 +541,11 @@
    3.36          return false;
    3.37      }
    3.38  
    3.39 -    private int loadArgs(final List<Node> args) {
    3.40 +    private int loadArgs(final List<Expression> args) {
    3.41          return loadArgs(args, null, false, args.size());
    3.42      }
    3.43  
    3.44 -    private int loadArgs(final List<Node> args, final String signature, final boolean isVarArg, final int argCount) {
    3.45 +    private int loadArgs(final List<Expression> args, final String signature, final boolean isVarArg, final int argCount) {
    3.46          // arg have already been converted to objects here.
    3.47          if (isVarArg || argCount > LinkerCallSite.ARGLIMIT) {
    3.48              loadArgsArray(args);
    3.49 @@ -553,7 +555,7 @@
    3.50          // pad with undefined if size is too short. argCount is the real number of args
    3.51          int n = 0;
    3.52          final Type[] params = signature == null ? null : Type.getMethodArguments(signature);
    3.53 -        for (final Node arg : args) {
    3.54 +        for (final Expression arg : args) {
    3.55              assert arg != null;
    3.56              load(arg);
    3.57              if (n >= argCount) {
    3.58 @@ -574,13 +576,13 @@
    3.59  
    3.60      @Override
    3.61      public boolean enterCallNode(final CallNode callNode) {
    3.62 -        lineNumber(callNode);
    3.63 -
    3.64 -        final List<Node>   args            = callNode.getArgs();
    3.65 -        final Node         function        = callNode.getFunction();
    3.66 -        final Block        currentBlock    = lc.getCurrentBlock();
    3.67 +        lineNumber(callNode.getLineNumber());
    3.68 +
    3.69 +        final List<Expression> args = callNode.getArgs();
    3.70 +        final Expression function = callNode.getFunction();
    3.71 +        final Block currentBlock = lc.getCurrentBlock();
    3.72          final CodeGeneratorLexicalContext codegenLexicalContext = lc;
    3.73 -        final Type         callNodeType    = callNode.getType();
    3.74 +        final Type callNodeType = callNode.getType();
    3.75  
    3.76          function.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
    3.77  
    3.78 @@ -771,11 +773,19 @@
    3.79      }
    3.80  
    3.81      @Override
    3.82 -    public boolean enterExecuteNode(final ExecuteNode executeNode) {
    3.83 -        lineNumber(executeNode);
    3.84 -
    3.85 -        final Node expression = executeNode.getExpression();
    3.86 -        expression.accept(this);
    3.87 +    public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
    3.88 +        lineNumber(expressionStatement);
    3.89 +
    3.90 +        expressionStatement.getExpression().accept(this);
    3.91 +
    3.92 +        return false;
    3.93 +    }
    3.94 +
    3.95 +    @Override
    3.96 +    public boolean enterBlockStatement(final BlockStatement blockStatement) {
    3.97 +        lineNumber(blockStatement);
    3.98 +
    3.99 +        blockStatement.getBlock().accept(this);
   3.100  
   3.101          return false;
   3.102      }
   3.103 @@ -794,10 +804,10 @@
   3.104      }
   3.105  
   3.106      private void enterFor(final ForNode forNode) {
   3.107 -        final Node  init   = forNode.getInit();
   3.108 -        final Node  test   = forNode.getTest();
   3.109 -        final Block body   = forNode.getBody();
   3.110 -        final Node  modify = forNode.getModify();
   3.111 +        final Expression init   = forNode.getInit();
   3.112 +        final Expression test   = forNode.getTest();
   3.113 +        final Block      body   = forNode.getBody();
   3.114 +        final Expression modify = forNode.getModify();
   3.115  
   3.116          if (init != null) {
   3.117              init.accept(this);
   3.118 @@ -827,19 +837,13 @@
   3.119  
   3.120      private void enterForIn(final ForNode forNode) {
   3.121          final Block body   = forNode.getBody();
   3.122 -        final Node  modify = forNode.getModify();
   3.123 +        final Expression  modify = forNode.getModify();
   3.124  
   3.125          final Symbol iter      = forNode.getIterator();
   3.126          final Label  loopLabel = new Label("loop");
   3.127  
   3.128 -        Node init = forNode.getInit();
   3.129 -
   3.130 -        // We have to evaluate the optional initializer expression
   3.131 -        // of the iterator variable of the for-in statement.
   3.132 -        if (init instanceof VarNode) {
   3.133 -            init.accept(this);
   3.134 -            init = ((VarNode)init).getName();
   3.135 -        }
   3.136 +        final Expression init = forNode.getInit();
   3.137 +        assert init instanceof IdentNode;
   3.138  
   3.139          load(modify);
   3.140          assert modify.getType().isObject();
   3.141 @@ -848,7 +852,7 @@
   3.142          method._goto(forNode.getContinueLabel());
   3.143          method.label(loopLabel);
   3.144  
   3.145 -        new Store<Node>(init) {
   3.146 +        new Store<Expression>(init) {
   3.147              @Override
   3.148              protected void storeNonDiscard() {
   3.149                  return;
   3.150 @@ -1047,7 +1051,7 @@
   3.151      public boolean enterIfNode(final IfNode ifNode) {
   3.152          lineNumber(ifNode);
   3.153  
   3.154 -        final Node  test = ifNode.getTest();
   3.155 +        final Expression test = ifNode.getTest();
   3.156          final Block pass = ifNode.getPass();
   3.157          final Block fail = ifNode.getFail();
   3.158  
   3.159 @@ -1087,7 +1091,10 @@
   3.160      }
   3.161  
   3.162      private void lineNumber(final Statement statement) {
   3.163 -        final int lineNumber = statement.getLineNumber();
   3.164 +        lineNumber(statement.getLineNumber());
   3.165 +    }
   3.166 +
   3.167 +    private void lineNumber(int lineNumber) {
   3.168          if (lineNumber != lastLineNumber) {
   3.169              method.lineNumber(lineNumber);
   3.170          }
   3.171 @@ -1106,7 +1113,7 @@
   3.172      private MethodEmitter loadArray(final ArrayLiteralNode arrayLiteralNode, final ArrayType arrayType) {
   3.173          assert arrayType == Type.INT_ARRAY || arrayType == Type.LONG_ARRAY || arrayType == Type.NUMBER_ARRAY || arrayType == Type.OBJECT_ARRAY;
   3.174  
   3.175 -        final Node[]          nodes    = arrayLiteralNode.getValue();
   3.176 +        final Expression[]    nodes    = arrayLiteralNode.getValue();
   3.177          final Object          presets  = arrayLiteralNode.getPresets();
   3.178          final int[]           postsets = arrayLiteralNode.getPostsets();
   3.179          final Class<?>        type     = arrayType.getTypeClass();
   3.180 @@ -1166,11 +1173,11 @@
   3.181          return method;
   3.182      }
   3.183  
   3.184 -    private void storeElement(final Node[] nodes, final Type elementType, final int index) {
   3.185 +    private void storeElement(final Expression[] nodes, final Type elementType, final int index) {
   3.186          method.dup();
   3.187          method.load(index);
   3.188  
   3.189 -        final Node element = nodes[index];
   3.190 +        final Expression element = nodes[index];
   3.191  
   3.192          if (element == null) {
   3.193              method.loadEmpty(elementType);
   3.194 @@ -1182,7 +1189,7 @@
   3.195          method.arraystore();
   3.196      }
   3.197  
   3.198 -    private MethodEmitter loadArgsArray(final List<Node> args) {
   3.199 +    private MethodEmitter loadArgsArray(final List<Expression> args) {
   3.200          final Object[] array = new Object[args.size()];
   3.201          loadConstant(array);
   3.202  
   3.203 @@ -1323,16 +1330,16 @@
   3.204      public boolean enterObjectNode(final ObjectNode objectNode) {
   3.205          final List<PropertyNode> elements = objectNode.getElements();
   3.206  
   3.207 -        final List<String> keys    = new ArrayList<>();
   3.208 -        final List<Symbol> symbols = new ArrayList<>();
   3.209 -        final List<Node>   values  = new ArrayList<>();
   3.210 +        final List<String>     keys    = new ArrayList<>();
   3.211 +        final List<Symbol>     symbols = new ArrayList<>();
   3.212 +        final List<Expression> values  = new ArrayList<>();
   3.213  
   3.214          boolean hasGettersSetters = false;
   3.215  
   3.216          for (PropertyNode propertyNode: elements) {
   3.217 -            final Node         value        = propertyNode.getValue();
   3.218 +            final Expression   value        = propertyNode.getValue();
   3.219              final String       key          = propertyNode.getKeyName();
   3.220 -            final Symbol       symbol       = value == null ? null : propertyNode.getSymbol();
   3.221 +            final Symbol       symbol       = value == null ? null : propertyNode.getKey().getSymbol();
   3.222  
   3.223              if (value == null) {
   3.224                  hasGettersSetters = true;
   3.225 @@ -1346,9 +1353,9 @@
   3.226          if (elements.size() > OBJECT_SPILL_THRESHOLD) {
   3.227              new SpillObjectCreator(this, keys, symbols, values).makeObject(method);
   3.228          } else {
   3.229 -            new FieldObjectCreator<Node>(this, keys, symbols, values) {
   3.230 +            new FieldObjectCreator<Expression>(this, keys, symbols, values) {
   3.231                  @Override
   3.232 -                protected void loadValue(final Node node) {
   3.233 +                protected void loadValue(final Expression node) {
   3.234                      load(node);
   3.235                  }
   3.236  
   3.237 @@ -1419,7 +1426,7 @@
   3.238  
   3.239          final Type returnType = lc.getCurrentFunction().getReturnType();
   3.240  
   3.241 -        final Node expression = returnNode.getExpression();
   3.242 +        final Expression expression = returnNode.getExpression();
   3.243          if (expression != null) {
   3.244              load(expression);
   3.245          } else {
   3.246 @@ -1435,7 +1442,7 @@
   3.247          return node instanceof LiteralNode<?> && ((LiteralNode<?>) node).isNull();
   3.248      }
   3.249  
   3.250 -    private boolean nullCheck(final RuntimeNode runtimeNode, final List<Node> args, final String signature) {
   3.251 +    private boolean nullCheck(final RuntimeNode runtimeNode, final List<Expression> args, final String signature) {
   3.252          final Request request = runtimeNode.getRequest();
   3.253  
   3.254          if (!Request.isEQ(request) && !Request.isNE(request)) {
   3.255 @@ -1444,11 +1451,11 @@
   3.256  
   3.257          assert args.size() == 2 : "EQ or NE or TYPEOF need two args";
   3.258  
   3.259 -        Node lhs = args.get(0);
   3.260 -        Node rhs = args.get(1);
   3.261 +        Expression lhs = args.get(0);
   3.262 +        Expression rhs = args.get(1);
   3.263  
   3.264          if (isNullLiteral(lhs)) {
   3.265 -            final Node tmp = lhs;
   3.266 +            final Expression tmp = lhs;
   3.267              lhs = rhs;
   3.268              rhs = tmp;
   3.269          }
   3.270 @@ -1502,7 +1509,7 @@
   3.271          return false;
   3.272      }
   3.273  
   3.274 -    private boolean specializationCheck(final RuntimeNode.Request request, final Node node, final List<Node> args) {
   3.275 +    private boolean specializationCheck(final RuntimeNode.Request request, final Expression node, final List<Expression> args) {
   3.276          if (!request.canSpecialize()) {
   3.277              return false;
   3.278          }
   3.279 @@ -1555,10 +1562,11 @@
   3.280           *
   3.281           * TODO - remove this - Access Specializer will always know after Attr/Lower
   3.282           */
   3.283 +        final List<Expression> args = runtimeNode.getArgs();
   3.284          if (runtimeNode.isPrimitive() && !runtimeNode.isFinal() && isReducible(runtimeNode.getRequest())) {
   3.285 -            final Node lhs = runtimeNode.getArgs().get(0);
   3.286 -            assert runtimeNode.getArgs().size() > 1 : runtimeNode + " must have two args";
   3.287 -            final Node rhs = runtimeNode.getArgs().get(1);
   3.288 +            final Expression lhs = args.get(0);
   3.289 +            assert args.size() > 1 : runtimeNode + " must have two args";
   3.290 +            final Expression rhs = args.get(1);
   3.291  
   3.292              final Type   type   = runtimeNode.getType();
   3.293              final Symbol symbol = runtimeNode.getSymbol();
   3.294 @@ -1595,9 +1603,6 @@
   3.295              }
   3.296          }
   3.297  
   3.298 -        // Get the request arguments.
   3.299 -        final List<Node> args = runtimeNode.getArgs();
   3.300 -
   3.301          if (nullCheck(runtimeNode, args, new FunctionSignature(false, false, runtimeNode.getType(), args).toString())) {
   3.302              return false;
   3.303          }
   3.304 @@ -1606,7 +1611,7 @@
   3.305              return false;
   3.306          }
   3.307  
   3.308 -        for (final Node arg : runtimeNode.getArgs()) {
   3.309 +        for (final Expression arg : args) {
   3.310              load(arg).convert(Type.OBJECT); //TODO this should not be necessary below Lower
   3.311          }
   3.312  
   3.313 @@ -1617,7 +1622,7 @@
   3.314                  false,
   3.315                  false,
   3.316                  runtimeNode.getType(),
   3.317 -                runtimeNode.getArgs().size()).toString());
   3.318 +                args.size()).toString());
   3.319          method.convert(runtimeNode.getType());
   3.320          method.store(runtimeNode.getSymbol());
   3.321  
   3.322 @@ -1626,8 +1631,6 @@
   3.323  
   3.324      @Override
   3.325      public boolean enterSplitNode(final SplitNode splitNode) {
   3.326 -        lineNumber(splitNode);
   3.327 -
   3.328          final CompileUnit splitCompileUnit = splitNode.getCompileUnit();
   3.329  
   3.330          final FunctionNode fn   = lc.getCurrentFunction();
   3.331 @@ -1772,7 +1775,7 @@
   3.332      public boolean enterSwitchNode(final SwitchNode switchNode) {
   3.333          lineNumber(switchNode);
   3.334  
   3.335 -        final Node           expression  = switchNode.getExpression();
   3.336 +        final Expression     expression  = switchNode.getExpression();
   3.337          final Symbol         tag         = switchNode.getTag();
   3.338          final boolean        allInteger  = tag.getSymbolType().isInteger();
   3.339          final List<CaseNode> cases       = switchNode.getCases();
   3.340 @@ -1875,7 +1878,7 @@
   3.341              }
   3.342  
   3.343              for (final CaseNode caseNode : cases) {
   3.344 -                final Node test = caseNode.getTest();
   3.345 +                final Expression test = caseNode.getTest();
   3.346  
   3.347                  if (test != null) {
   3.348                      method.load(tag);
   3.349 @@ -1915,10 +1918,10 @@
   3.350  
   3.351          final Source source     = lc.getCurrentFunction().getSource();
   3.352  
   3.353 -        final Node   expression = throwNode.getExpression();
   3.354 -        final int    position   = throwNode.position();
   3.355 -        final int    line       = source.getLine(position);
   3.356 -        final int    column     = source.getColumn(position);
   3.357 +        final Expression expression = throwNode.getExpression();
   3.358 +        final int        position   = throwNode.position();
   3.359 +        final int        line       = source.getLine(position);
   3.360 +        final int        column     = source.getColumn(position);
   3.361  
   3.362          load(expression);
   3.363          assert expression.getType().isObject();
   3.364 @@ -1967,10 +1970,10 @@
   3.365              lc.push(catchBlock);
   3.366              enterBlock(catchBlock);
   3.367  
   3.368 -            final CatchNode catchNode          = (CatchNode)catchBlocks.get(i).getStatements().get(0);
   3.369 -            final IdentNode exception          = catchNode.getException();
   3.370 -            final Node      exceptionCondition = catchNode.getExceptionCondition();
   3.371 -            final Block     catchBody          = catchNode.getBody();
   3.372 +            final CatchNode  catchNode          = (CatchNode)catchBlocks.get(i).getStatements().get(0);
   3.373 +            final IdentNode  exception          = catchNode.getException();
   3.374 +            final Expression exceptionCondition = catchNode.getExceptionCondition();
   3.375 +            final Block      catchBody          = catchNode.getBody();
   3.376  
   3.377              new Store<IdentNode>(exception) {
   3.378                  @Override
   3.379 @@ -2038,7 +2041,7 @@
   3.380      @Override
   3.381      public boolean enterVarNode(final VarNode varNode) {
   3.382  
   3.383 -        final Node init = varNode.getInit();
   3.384 +        final Expression init = varNode.getInit();
   3.385  
   3.386          if (init == null) {
   3.387              return false;
   3.388 @@ -2046,8 +2049,8 @@
   3.389  
   3.390          lineNumber(varNode);
   3.391  
   3.392 -        final Symbol varSymbol = varNode.getSymbol();
   3.393 -        assert varSymbol != null : "variable node " + varNode + " requires a symbol";
   3.394 +        final Symbol varSymbol = varNode.getName().getSymbol();
   3.395 +        assert varSymbol != null : "variable node " + varNode + " requires a name with a symbol";
   3.396  
   3.397          assert method != null;
   3.398  
   3.399 @@ -2067,9 +2070,7 @@
   3.400                  method.dynamicSet(type, identNode.getName(), flags);
   3.401              }
   3.402          } else {
   3.403 -            assert varNode.getType() == varNode.getName().getType() : "varNode type=" + varNode.getType() + " nametype=" + varNode.getName().getType() + " inittype=" + init.getType();
   3.404 -
   3.405 -            method.convert(varNode.getType()); // aw: convert moved here
   3.406 +            method.convert(varNode.getName().getType()); // aw: convert moved here
   3.407              method.store(varSymbol);
   3.408          }
   3.409  
   3.410 @@ -2080,11 +2081,11 @@
   3.411      public boolean enterWhileNode(final WhileNode whileNode) {
   3.412          lineNumber(whileNode);
   3.413  
   3.414 -        final Node  test          = whileNode.getTest();
   3.415 -        final Block body          = whileNode.getBody();
   3.416 -        final Label breakLabel    = whileNode.getBreakLabel();
   3.417 -        final Label continueLabel = whileNode.getContinueLabel();
   3.418 -        final Label loopLabel     = new Label("loop");
   3.419 +        final Expression test          = whileNode.getTest();
   3.420 +        final Block      body          = whileNode.getBody();
   3.421 +        final Label      breakLabel    = whileNode.getBreakLabel();
   3.422 +        final Label      continueLabel = whileNode.getContinueLabel();
   3.423 +        final Label      loopLabel     = new Label("loop");
   3.424  
   3.425          if (!whileNode.isDoWhile()) {
   3.426              method._goto(continueLabel);
   3.427 @@ -2111,8 +2112,8 @@
   3.428  
   3.429      @Override
   3.430      public boolean enterWithNode(final WithNode withNode) {
   3.431 -        final Node expression = withNode.getExpression();
   3.432 -        final Node body       = withNode.getBody();
   3.433 +        final Expression expression = withNode.getExpression();
   3.434 +        final Node       body       = withNode.getBody();
   3.435  
   3.436          // It is possible to have a "pathological" case where the with block does not reference *any* identifiers. It's
   3.437          // pointless, but legal. In that case, if nothing else in the method forced the assignment of a slot to the
   3.438 @@ -2187,7 +2188,7 @@
   3.439      // do this better with convert calls to method. TODO
   3.440      @Override
   3.441      public boolean enterCONVERT(final UnaryNode unaryNode) {
   3.442 -        final Node rhs = unaryNode.rhs();
   3.443 +        final Expression rhs = unaryNode.rhs();
   3.444          final Type to  = unaryNode.getType();
   3.445  
   3.446          if (to.isObject() && rhs instanceof LiteralNode) {
   3.447 @@ -2224,11 +2225,11 @@
   3.448  
   3.449      @Override
   3.450      public boolean enterDECINC(final UnaryNode unaryNode) {
   3.451 -        final Node      rhs         = unaryNode.rhs();
   3.452 -        final Type      type        = unaryNode.getType();
   3.453 -        final TokenType tokenType   = unaryNode.tokenType();
   3.454 -        final boolean   isPostfix   = tokenType == TokenType.DECPOSTFIX || tokenType == TokenType.INCPOSTFIX;
   3.455 -        final boolean   isIncrement = tokenType == TokenType.INCPREFIX || tokenType == TokenType.INCPOSTFIX;
   3.456 +        final Expression rhs         = unaryNode.rhs();
   3.457 +        final Type       type        = unaryNode.getType();
   3.458 +        final TokenType  tokenType   = unaryNode.tokenType();
   3.459 +        final boolean    isPostfix   = tokenType == TokenType.DECPOSTFIX || tokenType == TokenType.INCPOSTFIX;
   3.460 +        final boolean    isIncrement = tokenType == TokenType.INCPREFIX || tokenType == TokenType.INCPOSTFIX;
   3.461  
   3.462          assert !type.isObject();
   3.463  
   3.464 @@ -2272,7 +2273,7 @@
   3.465  
   3.466      @Override
   3.467      public boolean enterDISCARD(final UnaryNode unaryNode) {
   3.468 -        final Node rhs = unaryNode.rhs();
   3.469 +        final Expression rhs = unaryNode.rhs();
   3.470  
   3.471          lc.pushDiscard(rhs);
   3.472          load(rhs);
   3.473 @@ -2289,7 +2290,7 @@
   3.474      @Override
   3.475      public boolean enterNEW(final UnaryNode unaryNode) {
   3.476          final CallNode callNode = (CallNode)unaryNode.rhs();
   3.477 -        final List<Node> args   = callNode.getArgs();
   3.478 +        final List<Expression> args   = callNode.getArgs();
   3.479  
   3.480          // Load function reference.
   3.481          load(callNode.getFunction()).convert(Type.OBJECT); // must detect type error
   3.482 @@ -2302,7 +2303,7 @@
   3.483  
   3.484      @Override
   3.485      public boolean enterNOT(final UnaryNode unaryNode) {
   3.486 -        final Node rhs = unaryNode.rhs();
   3.487 +        final Expression rhs = unaryNode.rhs();
   3.488  
   3.489          load(rhs);
   3.490  
   3.491 @@ -2336,19 +2337,18 @@
   3.492          return false;
   3.493      }
   3.494  
   3.495 -    private Node enterNumericAdd(final Node lhs, final Node rhs, final Type type, final Symbol symbol) {
   3.496 +    private void enterNumericAdd(final Expression lhs, final Expression rhs, final Type type, final Symbol symbol) {
   3.497          assert lhs.getType().equals(rhs.getType()) && lhs.getType().equals(type) : lhs.getType() + " != " + rhs.getType() + " != " + type + " " + new ASTWriter(lhs) + " " + new ASTWriter(rhs);
   3.498          load(lhs);
   3.499          load(rhs);
   3.500          method.add(); //if the symbol is optimistic, it always needs to be written, not on the stack?
   3.501          method.store(symbol);
   3.502 -        return null;
   3.503      }
   3.504  
   3.505      @Override
   3.506      public boolean enterADD(final BinaryNode binaryNode) {
   3.507 -        final Node lhs = binaryNode.lhs();
   3.508 -        final Node rhs = binaryNode.rhs();
   3.509 +        final Expression lhs = binaryNode.lhs();
   3.510 +        final Expression rhs = binaryNode.rhs();
   3.511  
   3.512          final Type type = binaryNode.getType();
   3.513          if (type.isNumeric()) {
   3.514 @@ -2364,8 +2364,8 @@
   3.515      }
   3.516  
   3.517      private boolean enterAND_OR(final BinaryNode binaryNode) {
   3.518 -        final Node lhs = binaryNode.lhs();
   3.519 -        final Node rhs = binaryNode.rhs();
   3.520 +        final Expression lhs = binaryNode.lhs();
   3.521 +        final Expression rhs = binaryNode.rhs();
   3.522  
   3.523          final Label skip = new Label("skip");
   3.524  
   3.525 @@ -2392,8 +2392,8 @@
   3.526  
   3.527      @Override
   3.528      public boolean enterASSIGN(final BinaryNode binaryNode) {
   3.529 -        final Node lhs = binaryNode.lhs();
   3.530 -        final Node rhs = binaryNode.rhs();
   3.531 +        final Expression lhs = binaryNode.lhs();
   3.532 +        final Expression rhs = binaryNode.rhs();
   3.533  
   3.534          final Type lhsType = lhs.getType();
   3.535          final Type rhsType = rhs.getType();
   3.536 @@ -2661,8 +2661,8 @@
   3.537      }
   3.538  
   3.539      private boolean enterComma(final BinaryNode binaryNode) {
   3.540 -        final Node lhs = binaryNode.lhs();
   3.541 -        final Node rhs = binaryNode.rhs();
   3.542 +        final Expression lhs = binaryNode.lhs();
   3.543 +        final Expression rhs = binaryNode.rhs();
   3.544  
   3.545          load(lhs);
   3.546          load(rhs);
   3.547 @@ -2693,7 +2693,7 @@
   3.548          return false;
   3.549      }
   3.550  
   3.551 -    private boolean enterCmp(final Node lhs, final Node rhs, final Condition cond, final Type type, final Symbol symbol) {
   3.552 +    private boolean enterCmp(final Expression lhs, final Expression rhs, final Condition cond, final Type type, final Symbol symbol) {
   3.553          final Type lhsType = lhs.getType();
   3.554          final Type rhsType = rhs.getType();
   3.555  
   3.556 @@ -2846,21 +2846,21 @@
   3.557  
   3.558      @Override
   3.559      public boolean enterTernaryNode(final TernaryNode ternaryNode) {
   3.560 -        final Node lhs   = ternaryNode.lhs();
   3.561 -        final Node rhs   = ternaryNode.rhs();
   3.562 -        final Node third = ternaryNode.third();
   3.563 +        final Expression test      = ternaryNode.getTest();
   3.564 +        final Expression trueExpr  = ternaryNode.getTrueExpression();
   3.565 +        final Expression falseExpr = ternaryNode.getFalseExpression();
   3.566  
   3.567          final Symbol symbol     = ternaryNode.getSymbol();
   3.568          final Label  falseLabel = new Label("ternary_false");
   3.569          final Label  exitLabel  = new Label("ternary_exit");
   3.570  
   3.571 -        Type widest = Type.widest(rhs.getType(), third.getType());
   3.572 -        if (rhs.getType().isArray() || third.getType().isArray()) { //loadArray creates a Java array type on the stack, calls global allocate, which creates a native array type
   3.573 +        Type widest = Type.widest(trueExpr.getType(), falseExpr.getType());
   3.574 +        if (trueExpr.getType().isArray() || falseExpr.getType().isArray()) { //loadArray creates a Java array type on the stack, calls global allocate, which creates a native array type
   3.575              widest = Type.OBJECT;
   3.576          }
   3.577  
   3.578 -        load(lhs);
   3.579 -        assert lhs.getType().isBoolean() : "lhs in ternary must be boolean";
   3.580 +        load(test);
   3.581 +        assert test.getType().isBoolean() : "lhs in ternary must be boolean";
   3.582  
   3.583          // we still keep the conversion here as the AccessSpecializer can have separated the types, e.g. var y = x ? x=55 : 17
   3.584          // will left as (Object)x=55 : (Object)17 by Lower. Then the first term can be {I}x=55 of type int, which breaks the
   3.585 @@ -2868,11 +2868,11 @@
   3.586          // to early, or Apply the AccessSpecializer too late. We are mostly probably looking for a separate type pass to
   3.587          // do this property. Then we never need any conversions in CodeGenerator
   3.588          method.ifeq(falseLabel);
   3.589 -        load(rhs);
   3.590 +        load(trueExpr);
   3.591          method.convert(widest);
   3.592          method._goto(exitLabel);
   3.593          method.label(falseLabel);
   3.594 -        load(third);
   3.595 +        load(falseExpr);
   3.596          method.convert(widest);
   3.597          method.label(exitLabel);
   3.598          method.store(symbol);
   3.599 @@ -2925,8 +2925,8 @@
   3.600       *
   3.601       * @param <T>
   3.602       */
   3.603 -    private abstract class SelfModifyingStore<T extends Node> extends Store<T> {
   3.604 -        protected SelfModifyingStore(final T assignNode, final Node target) {
   3.605 +    private abstract class SelfModifyingStore<T extends Expression> extends Store<T> {
   3.606 +        protected SelfModifyingStore(final T assignNode, final Expression target) {
   3.607              super(assignNode, target);
   3.608          }
   3.609  
   3.610 @@ -2939,13 +2939,13 @@
   3.611      /**
   3.612       * Helper class to generate stores
   3.613       */
   3.614 -    private abstract class Store<T extends Node> {
   3.615 +    private abstract class Store<T extends Expression> {
   3.616  
   3.617          /** An assignment node, e.g. x += y */
   3.618          protected final T assignNode;
   3.619  
   3.620          /** The target node to store to, e.g. x */
   3.621 -        private final Node target;
   3.622 +        private final Expression target;
   3.623  
   3.624          /** How deep on the stack do the arguments go if this generates an indy call */
   3.625          private int depth;
   3.626 @@ -2959,7 +2959,7 @@
   3.627           * @param assignNode the node representing the whole assignment
   3.628           * @param target     the target node of the assignment (destination)
   3.629           */
   3.630 -        protected Store(final T assignNode, final Node target) {
   3.631 +        protected Store(final T assignNode, final Expression target) {
   3.632              this.assignNode = assignNode;
   3.633              this.target = target;
   3.634          }
   3.635 @@ -3002,8 +3002,8 @@
   3.636  
   3.637                  private void enterBaseNode() {
   3.638                      assert target instanceof BaseNode : "error - base node " + target + " must be instanceof BaseNode";
   3.639 -                    final BaseNode baseNode = (BaseNode)target;
   3.640 -                    final Node     base     = baseNode.getBase();
   3.641 +                    final BaseNode   baseNode = (BaseNode)target;
   3.642 +                    final Expression base     = baseNode.getBase();
   3.643  
   3.644                      load(base);
   3.645                      method.convert(Type.OBJECT);
   3.646 @@ -3024,7 +3024,7 @@
   3.647                  public boolean enterIndexNode(final IndexNode node) {
   3.648                      enterBaseNode();
   3.649  
   3.650 -                    final Node index = node.getIndex();
   3.651 +                    final Expression index = node.getIndex();
   3.652                      // could be boolean here as well
   3.653                      load(index);
   3.654                      if (!index.getType().isNumeric()) {
     4.1 --- a/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Thu Jul 11 18:23:13 2013 +0530
     4.2 +++ b/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Thu Jul 11 18:33:33 2013 +0200
     4.3 @@ -21,6 +21,7 @@
     4.4  import jdk.nashorn.internal.codegen.types.Range;
     4.5  import jdk.nashorn.internal.codegen.types.Type;
     4.6  import jdk.nashorn.internal.ir.CallNode;
     4.7 +import jdk.nashorn.internal.ir.Expression;
     4.8  import jdk.nashorn.internal.ir.FunctionNode;
     4.9  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    4.10  import jdk.nashorn.internal.ir.LexicalContext;
    4.11 @@ -256,17 +257,20 @@
    4.12  
    4.13                  @Override
    4.14                  public Node leaveDefault(final Node node) {
    4.15 -                    final Symbol symbol = node.getSymbol();
    4.16 -                    if (symbol != null) {
    4.17 -                        final Range range  = symbol.getRange();
    4.18 -                        final Type  symbolType = symbol.getSymbolType();
    4.19 -                        if (!symbolType.isNumeric()) {
    4.20 -                            return node;
    4.21 -                        }
    4.22 -                        final Type  rangeType  = range.getType();
    4.23 -                        if (!Type.areEquivalent(symbolType, rangeType) && Type.widest(symbolType, rangeType) == symbolType) { //we can narrow range
    4.24 -                            RangeAnalyzer.LOG.info("[", lc.getCurrentFunction().getName(), "] ", symbol, " can be ", range.getType(), " ", symbol.getRange());
    4.25 -                            return node.setSymbol(lc, symbol.setTypeOverrideShared(range.getType(), compiler.getTemporarySymbols()));
    4.26 +                    if(node instanceof Expression) {
    4.27 +                        final Expression expr = (Expression)node;
    4.28 +                        final Symbol symbol = expr.getSymbol();
    4.29 +                        if (symbol != null) {
    4.30 +                            final Range range  = symbol.getRange();
    4.31 +                            final Type  symbolType = symbol.getSymbolType();
    4.32 +                            if (!symbolType.isNumeric()) {
    4.33 +                                return expr;
    4.34 +                            }
    4.35 +                            final Type  rangeType  = range.getType();
    4.36 +                            if (!Type.areEquivalent(symbolType, rangeType) && Type.widest(symbolType, rangeType) == symbolType) { //we can narrow range
    4.37 +                                RangeAnalyzer.LOG.info("[", lc.getCurrentFunction().getName(), "] ", symbol, " can be ", range.getType(), " ", symbol.getRange());
    4.38 +                                return expr.setSymbol(lc, symbol.setTypeOverrideShared(range.getType(), compiler.getTemporarySymbols()));
    4.39 +                            }
    4.40                          }
    4.41                      }
    4.42                      return node;
     5.1 --- a/src/jdk/nashorn/internal/codegen/FinalizeTypes.java	Thu Jul 11 18:23:13 2013 +0530
     5.2 +++ b/src/jdk/nashorn/internal/codegen/FinalizeTypes.java	Thu Jul 11 18:33:33 2013 +0200
     5.3 @@ -39,7 +39,8 @@
     5.4  import jdk.nashorn.internal.ir.CallNode;
     5.5  import jdk.nashorn.internal.ir.CaseNode;
     5.6  import jdk.nashorn.internal.ir.CatchNode;
     5.7 -import jdk.nashorn.internal.ir.ExecuteNode;
     5.8 +import jdk.nashorn.internal.ir.Expression;
     5.9 +import jdk.nashorn.internal.ir.ExpressionStatement;
    5.10  import jdk.nashorn.internal.ir.ForNode;
    5.11  import jdk.nashorn.internal.ir.FunctionNode;
    5.12  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    5.13 @@ -146,9 +147,9 @@
    5.14       * strings etc as well.
    5.15       */
    5.16      @Override
    5.17 -    public Node leaveADD(final BinaryNode binaryNode) {
    5.18 -        final Node lhs = binaryNode.lhs();
    5.19 -        final Node rhs = binaryNode.rhs();
    5.20 +    public Expression leaveADD(final BinaryNode binaryNode) {
    5.21 +        final Expression lhs = binaryNode.lhs();
    5.22 +        final Expression rhs = binaryNode.rhs();
    5.23  
    5.24          final Type type = binaryNode.getType();
    5.25  
    5.26 @@ -240,7 +241,7 @@
    5.27          return leaveASSIGN(binaryNode);
    5.28      }
    5.29  
    5.30 -    private boolean symbolIsInteger(Node node) {
    5.31 +    private boolean symbolIsInteger(final Expression node) {
    5.32          final Symbol symbol = node.getSymbol();
    5.33          assert symbol != null && symbol.getSymbolType().isInteger() : "int coercion expected: " + Debug.id(symbol) + " " + symbol + " " + lc.getCurrentFunction().getSource();
    5.34          return true;
    5.35 @@ -372,7 +373,7 @@
    5.36  
    5.37      @Override
    5.38      public Node leaveCatchNode(final CatchNode catchNode) {
    5.39 -        final Node exceptionCondition = catchNode.getExceptionCondition();
    5.40 +        final Expression exceptionCondition = catchNode.getExceptionCondition();
    5.41          if (exceptionCondition != null) {
    5.42              return catchNode.setExceptionCondition(convert(exceptionCondition, Type.BOOLEAN));
    5.43          }
    5.44 @@ -380,16 +381,16 @@
    5.45      }
    5.46  
    5.47      @Override
    5.48 -    public Node leaveExecuteNode(final ExecuteNode executeNode) {
    5.49 +    public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) {
    5.50          temporarySymbols.reuse();
    5.51 -        return executeNode.setExpression(discard(executeNode.getExpression()));
    5.52 +        return expressionStatement.setExpression(discard(expressionStatement.getExpression()));
    5.53      }
    5.54  
    5.55      @Override
    5.56      public Node leaveForNode(final ForNode forNode) {
    5.57 -        final Node init   = forNode.getInit();
    5.58 -        final Node test   = forNode.getTest();
    5.59 -        final Node modify = forNode.getModify();
    5.60 +        final Expression init   = forNode.getInit();
    5.61 +        final Expression test   = forNode.getTest();
    5.62 +        final Expression modify = forNode.getModify();
    5.63  
    5.64          if (forNode.isForIn()) {
    5.65              return forNode.setModify(lc, convert(forNode.getModify(), Type.OBJECT)); // NASHORN-400
    5.66 @@ -439,13 +440,13 @@
    5.67      public boolean enterLiteralNode(final LiteralNode literalNode) {
    5.68          if (literalNode instanceof ArrayLiteralNode) {
    5.69              final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode;
    5.70 -            final Node[]           array            = arrayLiteralNode.getValue();
    5.71 +            final Expression[]     array            = arrayLiteralNode.getValue();
    5.72              final Type             elementType      = arrayLiteralNode.getElementType();
    5.73  
    5.74              for (int i = 0; i < array.length; i++) {
    5.75                  final Node element = array[i];
    5.76                  if (element != null) {
    5.77 -                    array[i] = convert(element.accept(this), elementType);
    5.78 +                    array[i] = convert((Expression)element.accept(this), elementType);
    5.79                  }
    5.80              }
    5.81          }
    5.82 @@ -455,7 +456,7 @@
    5.83  
    5.84      @Override
    5.85      public Node leaveReturnNode(final ReturnNode returnNode) {
    5.86 -        final Node expr = returnNode.getExpression();
    5.87 +        final Expression expr = returnNode.getExpression();
    5.88          if (expr != null) {
    5.89              return returnNode.setExpression(convert(expr, lc.getCurrentFunction().getReturnType()));
    5.90          }
    5.91 @@ -464,8 +465,8 @@
    5.92  
    5.93      @Override
    5.94      public Node leaveRuntimeNode(final RuntimeNode runtimeNode) {
    5.95 -        final List<Node> args = runtimeNode.getArgs();
    5.96 -        for (final Node arg : args) {
    5.97 +        final List<Expression> args = runtimeNode.getArgs();
    5.98 +        for (final Expression arg : args) {
    5.99              assert !arg.getType().isUnknown();
   5.100          }
   5.101          return runtimeNode;
   5.102 @@ -479,12 +480,12 @@
   5.103              return switchNode;
   5.104          }
   5.105  
   5.106 -        final Node           expression  = switchNode.getExpression();
   5.107 +        final Expression     expression  = switchNode.getExpression();
   5.108          final List<CaseNode> cases       = switchNode.getCases();
   5.109          final List<CaseNode> newCases    = new ArrayList<>();
   5.110  
   5.111          for (final CaseNode caseNode : cases) {
   5.112 -            final Node test = caseNode.getTest();
   5.113 +            final Expression test = caseNode.getTest();
   5.114              newCases.add(test != null ? caseNode.setTest(convert(test, Type.OBJECT)) : caseNode);
   5.115          }
   5.116  
   5.117 @@ -495,7 +496,7 @@
   5.118  
   5.119      @Override
   5.120      public Node leaveTernaryNode(final TernaryNode ternaryNode) {
   5.121 -        return ternaryNode.setLHS(convert(ternaryNode.lhs(), Type.BOOLEAN));
   5.122 +        return ternaryNode.setTest(convert(ternaryNode.getTest(), Type.BOOLEAN));
   5.123      }
   5.124  
   5.125      @Override
   5.126 @@ -505,16 +506,16 @@
   5.127  
   5.128      @Override
   5.129      public Node leaveVarNode(final VarNode varNode) {
   5.130 -        final Node init = varNode.getInit();
   5.131 +        final Expression init = varNode.getInit();
   5.132          if (init != null) {
   5.133              final SpecializedNode specialized = specialize(varNode);
   5.134              final VarNode specVarNode = (VarNode)specialized.node;
   5.135              Type destType = specialized.type;
   5.136              if (destType == null) {
   5.137 -                destType = specVarNode.getType();
   5.138 +                destType = specVarNode.getName().getType();
   5.139              }
   5.140 -            assert specVarNode.hasType() : specVarNode + " doesn't have a type";
   5.141 -            final Node convertedInit = convert(init, destType);
   5.142 +            assert specVarNode.getName().hasType() : specVarNode + " doesn't have a type";
   5.143 +            final Expression convertedInit = convert(init, destType);
   5.144              temporarySymbols.reuse();
   5.145              return specVarNode.setInit(convertedInit);
   5.146          }
   5.147 @@ -524,7 +525,7 @@
   5.148  
   5.149      @Override
   5.150      public Node leaveWhileNode(final WhileNode whileNode) {
   5.151 -        final Node test = whileNode.getTest();
   5.152 +        final Expression test = whileNode.getTest();
   5.153          if (test != null) {
   5.154              return whileNode.setTest(lc, convert(test, Type.BOOLEAN));
   5.155          }
   5.156 @@ -599,8 +600,8 @@
   5.157       */
   5.158      @SuppressWarnings("fallthrough")
   5.159      private Node leaveCmp(final BinaryNode binaryNode, final RuntimeNode.Request request) {
   5.160 -        final Node lhs    = binaryNode.lhs();
   5.161 -        final Node rhs    = binaryNode.rhs();
   5.162 +        final Expression lhs    = binaryNode.lhs();
   5.163 +        final Expression rhs    = binaryNode.rhs();
   5.164  
   5.165          Type widest = Type.widest(lhs.getType(), rhs.getType());
   5.166  
   5.167 @@ -696,10 +697,10 @@
   5.168          }
   5.169      }
   5.170  
   5.171 -    <T extends Node> SpecializedNode specialize(final Assignment<T> assignment) {
   5.172 +    <T extends Expression> SpecializedNode specialize(final Assignment<T> assignment) {
   5.173          final Node node = ((Node)assignment);
   5.174          final T lhs = assignment.getAssignmentDest();
   5.175 -        final Node rhs = assignment.getAssignmentSource();
   5.176 +        final Expression rhs = assignment.getAssignmentSource();
   5.177  
   5.178          if (!canHaveCallSiteType(lhs)) {
   5.179              return new SpecializedNode(node, null);
   5.180 @@ -718,8 +719,16 @@
   5.181          }
   5.182  
   5.183          final Node newNode = assignment.setAssignmentDest(setTypeOverride(lhs, to));
   5.184 -        final Node typePropagatedNode = propagateType(newNode, to);
   5.185 -
   5.186 +        final Node typePropagatedNode;
   5.187 +        if(newNode instanceof Expression) {
   5.188 +            typePropagatedNode = propagateType((Expression)newNode, to);
   5.189 +        } else if(newNode instanceof VarNode) {
   5.190 +            // VarNode, being a statement, doesn't have its own symbol; it uses the symbol of its name instead.
   5.191 +            final VarNode varNode = (VarNode)newNode;
   5.192 +            typePropagatedNode = varNode.setName((IdentNode)propagateType(varNode.getName(), to));
   5.193 +        } else {
   5.194 +            throw new AssertionError();
   5.195 +        }
   5.196          return new SpecializedNode(typePropagatedNode, to);
   5.197      }
   5.198  
   5.199 @@ -759,7 +768,7 @@
   5.200       * @param to      new type
   5.201       */
   5.202      @SuppressWarnings("unchecked")
   5.203 -    <T extends Node> T setTypeOverride(final T node, final Type to) {
   5.204 +    <T extends Expression> T setTypeOverride(final T node, final Type to) {
   5.205          final Type from = node.getType();
   5.206          if (!node.getType().equals(to)) {
   5.207              LOG.info("Changing call override type for '", node, "' from ", node.getType(), " to ", to);
   5.208 @@ -788,7 +797,7 @@
   5.209       * @param to   destination type
   5.210       * @return     conversion node
   5.211       */
   5.212 -    private Node convert(final Node node, final Type to) {
   5.213 +    private Expression convert(final Expression node, final Type to) {
   5.214          assert !to.isUnknown() : "unknown type for " + node + " class=" + node.getClass();
   5.215          assert node != null : "node is null";
   5.216          assert node.getSymbol() != null : "node " + node + " " + node.getClass() + " has no symbol! " + lc.getCurrentFunction();
   5.217 @@ -804,7 +813,7 @@
   5.218              return node;
   5.219          }
   5.220  
   5.221 -        Node resultNode = node;
   5.222 +        Expression resultNode = node;
   5.223  
   5.224          if (node instanceof LiteralNode && !(node instanceof ArrayLiteralNode) && !to.isObject()) {
   5.225              final LiteralNode<?> newNode = new LiteralNodeConstantEvaluator((LiteralNode<?>)node, to).eval();
   5.226 @@ -828,9 +837,9 @@
   5.227          return temporarySymbols.ensureSymbol(lc, to, resultNode);
   5.228      }
   5.229  
   5.230 -    private static Node discard(final Node node) {
   5.231 +    private static Expression discard(final Expression node) {
   5.232          if (node.getSymbol() != null) {
   5.233 -            final Node discard = new UnaryNode(Token.recast(node.getToken(), TokenType.DISCARD), node);
   5.234 +            final UnaryNode discard = new UnaryNode(Token.recast(node.getToken(), TokenType.DISCARD), node);
   5.235              //discard never has a symbol in the discard node - then it would be a nop
   5.236              assert !node.isTerminal();
   5.237              return discard;
   5.238 @@ -853,7 +862,7 @@
   5.239       * @param node
   5.240       * @param to
   5.241       */
   5.242 -    private Node propagateType(final Node node, final Type to) {
   5.243 +    private Expression propagateType(final Expression node, final Type to) {
   5.244          Symbol symbol = node.getSymbol();
   5.245          if (symbol.isTemp() && symbol.getSymbolType() != to) {
   5.246              symbol = symbol.setTypeOverrideShared(to, temporarySymbols);
     6.1 --- a/src/jdk/nashorn/internal/codegen/FoldConstants.java	Thu Jul 11 18:23:13 2013 +0530
     6.2 +++ b/src/jdk/nashorn/internal/codegen/FoldConstants.java	Thu Jul 11 18:33:33 2013 +0200
     6.3 @@ -28,8 +28,8 @@
     6.4  import jdk.nashorn.internal.codegen.types.Type;
     6.5  import jdk.nashorn.internal.ir.BinaryNode;
     6.6  import jdk.nashorn.internal.ir.Block;
     6.7 +import jdk.nashorn.internal.ir.BlockStatement;
     6.8  import jdk.nashorn.internal.ir.EmptyNode;
     6.9 -import jdk.nashorn.internal.ir.ExecuteNode;
    6.10  import jdk.nashorn.internal.ir.FunctionNode;
    6.11  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    6.12  import jdk.nashorn.internal.ir.IfNode;
    6.13 @@ -91,7 +91,7 @@
    6.14          if (test instanceof LiteralNode) {
    6.15              final Block shortCut = ((LiteralNode<?>)test).isTrue() ? ifNode.getPass() : ifNode.getFail();
    6.16              if (shortCut != null) {
    6.17 -                return new ExecuteNode(shortCut.getLineNumber(), shortCut.getToken(), shortCut.getFinish(), shortCut);
    6.18 +                return new BlockStatement(ifNode.getLineNumber(), shortCut);
    6.19              }
    6.20              return new EmptyNode(ifNode);
    6.21          }
    6.22 @@ -100,9 +100,9 @@
    6.23  
    6.24      @Override
    6.25      public Node leaveTernaryNode(final TernaryNode ternaryNode) {
    6.26 -        final Node test = ternaryNode.lhs();
    6.27 +        final Node test = ternaryNode.getTest();
    6.28          if (test instanceof LiteralNode) {
    6.29 -            return ((LiteralNode<?>)test).isTrue() ? ternaryNode.rhs() : ternaryNode.third();
    6.30 +            return ((LiteralNode<?>)test).isTrue() ? ternaryNode.getTrueExpression() : ternaryNode.getFalseExpression();
    6.31          }
    6.32          return ternaryNode;
    6.33      }
     7.1 --- a/src/jdk/nashorn/internal/codegen/FunctionSignature.java	Thu Jul 11 18:23:13 2013 +0530
     7.2 +++ b/src/jdk/nashorn/internal/codegen/FunctionSignature.java	Thu Jul 11 18:33:33 2013 +0200
     7.3 @@ -31,8 +31,8 @@
     7.4  import java.util.ArrayList;
     7.5  import java.util.List;
     7.6  import jdk.nashorn.internal.codegen.types.Type;
     7.7 +import jdk.nashorn.internal.ir.Expression;
     7.8  import jdk.nashorn.internal.ir.FunctionNode;
     7.9 -import jdk.nashorn.internal.ir.Node;
    7.10  import jdk.nashorn.internal.runtime.ScriptFunction;
    7.11  import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
    7.12  
    7.13 @@ -63,7 +63,7 @@
    7.14       * @param retType   what is the return type
    7.15       * @param args      argument list of AST Nodes
    7.16       */
    7.17 -    public FunctionSignature(final boolean hasSelf, final boolean hasCallee, final Type retType, final List<? extends Node> args) {
    7.18 +    public FunctionSignature(final boolean hasSelf, final boolean hasCallee, final Type retType, final List<? extends Expression> args) {
    7.19          this(hasSelf, hasCallee, retType, FunctionSignature.typeArray(args));
    7.20      }
    7.21  
    7.22 @@ -167,7 +167,7 @@
    7.23       *
    7.24       * @return the array of types
    7.25       */
    7.26 -    private static Type[] typeArray(final List<? extends Node> args) {
    7.27 +    private static Type[] typeArray(final List<? extends Expression> args) {
    7.28          if (args == null) {
    7.29              return null;
    7.30          }
    7.31 @@ -175,7 +175,7 @@
    7.32          final Type[] typeArray = new Type[args.size()];
    7.33  
    7.34          int pos = 0;
    7.35 -        for (final Node arg : args) {
    7.36 +        for (final Expression arg : args) {
    7.37              typeArray[pos++] = arg.getType();
    7.38          }
    7.39  
     8.1 --- a/src/jdk/nashorn/internal/codegen/Lower.java	Thu Jul 11 18:23:13 2013 +0530
     8.2 +++ b/src/jdk/nashorn/internal/codegen/Lower.java	Thu Jul 11 18:33:33 2013 +0200
     8.3 @@ -37,12 +37,14 @@
     8.4  import jdk.nashorn.internal.ir.BinaryNode;
     8.5  import jdk.nashorn.internal.ir.Block;
     8.6  import jdk.nashorn.internal.ir.BlockLexicalContext;
     8.7 +import jdk.nashorn.internal.ir.BlockStatement;
     8.8  import jdk.nashorn.internal.ir.BreakNode;
     8.9  import jdk.nashorn.internal.ir.CallNode;
    8.10  import jdk.nashorn.internal.ir.CatchNode;
    8.11  import jdk.nashorn.internal.ir.ContinueNode;
    8.12  import jdk.nashorn.internal.ir.EmptyNode;
    8.13 -import jdk.nashorn.internal.ir.ExecuteNode;
    8.14 +import jdk.nashorn.internal.ir.Expression;
    8.15 +import jdk.nashorn.internal.ir.ExpressionStatement;
    8.16  import jdk.nashorn.internal.ir.ForNode;
    8.17  import jdk.nashorn.internal.ir.FunctionNode;
    8.18  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    8.19 @@ -138,7 +140,7 @@
    8.20      public boolean enterBlock(final Block block) {
    8.21          final FunctionNode   function = lc.getCurrentFunction();
    8.22          if (lc.isFunctionBody() && function.isProgram() && !function.hasDeclaredFunctions()) {
    8.23 -            new ExecuteNode(block.getLineNumber(), block.getToken(), block.getFinish(), LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)).accept(this);
    8.24 +            new ExpressionStatement(function.getLineNumber(), block.getToken(), block.getFinish(), LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)).accept(this);
    8.25          }
    8.26          return true;
    8.27      }
    8.28 @@ -154,7 +156,7 @@
    8.29              final boolean isProgram = currentFunction.isProgram();
    8.30              final Statement last = lc.getLastStatement();
    8.31              final ReturnNode returnNode = new ReturnNode(
    8.32 -                last == null ? block.getLineNumber() : last.getLineNumber(), //TODO?
    8.33 +                last == null ? currentFunction.getLineNumber() : last.getLineNumber(), //TODO?
    8.34                  currentFunction.getToken(),
    8.35                  currentFunction.getFinish(),
    8.36                  isProgram ?
    8.37 @@ -195,23 +197,21 @@
    8.38      }
    8.39  
    8.40      @Override
    8.41 -    public Node leaveExecuteNode(final ExecuteNode executeNode) {
    8.42 -        final Node expr = executeNode.getExpression();
    8.43 -        ExecuteNode node = executeNode;
    8.44 +    public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) {
    8.45 +        final Expression expr = expressionStatement.getExpression();
    8.46 +        ExpressionStatement node = expressionStatement;
    8.47  
    8.48          final FunctionNode currentFunction = lc.getCurrentFunction();
    8.49  
    8.50          if (currentFunction.isProgram()) {
    8.51 -            if (!(expr instanceof Block) || expr instanceof FunctionNode) { // it's not a block, but can be a function
    8.52 -                if (!isInternalExpression(expr) && !isEvalResultAssignment(expr)) {
    8.53 -                    node = executeNode.setExpression(
    8.54 -                        new BinaryNode(
    8.55 -                            Token.recast(
    8.56 -                                executeNode.getToken(),
    8.57 -                                TokenType.ASSIGN),
    8.58 -                            compilerConstant(RETURN),
    8.59 -                        expr));
    8.60 -                }
    8.61 +            if (!isInternalExpression(expr) && !isEvalResultAssignment(expr)) {
    8.62 +                node = expressionStatement.setExpression(
    8.63 +                    new BinaryNode(
    8.64 +                        Token.recast(
    8.65 +                            expressionStatement.getToken(),
    8.66 +                            TokenType.ASSIGN),
    8.67 +                        compilerConstant(RETURN),
    8.68 +                    expr));
    8.69              }
    8.70          }
    8.71  
    8.72 @@ -219,6 +219,11 @@
    8.73      }
    8.74  
    8.75      @Override
    8.76 +    public Node leaveBlockStatement(BlockStatement blockStatement) {
    8.77 +        return addStatement(blockStatement);
    8.78 +    }
    8.79 +
    8.80 +    @Override
    8.81      public Node leaveForNode(final ForNode forNode) {
    8.82          ForNode newForNode = forNode;
    8.83  
    8.84 @@ -302,11 +307,11 @@
    8.85  
    8.86          final IdentNode exception = new IdentNode(token, finish, lc.getCurrentFunction().uniqueName("catch_all"));
    8.87  
    8.88 -        final Block catchBody = new Block(lineNumber, token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception), ThrowNode.IS_SYNTHETIC_RETHROW)).
    8.89 +        final Block catchBody = new Block(token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception), ThrowNode.IS_SYNTHETIC_RETHROW)).
    8.90                  setIsTerminal(lc, true); //ends with throw, so terminal
    8.91  
    8.92          final CatchNode catchAllNode  = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody, CatchNode.IS_SYNTHETIC_RETHROW);
    8.93 -        final Block     catchAllBlock = new Block(lineNumber, token, finish, catchAllNode);
    8.94 +        final Block     catchAllBlock = new Block(token, finish, catchAllNode);
    8.95  
    8.96          //catchallblock -> catchallnode (catchnode) -> exception -> throw
    8.97  
    8.98 @@ -355,14 +360,14 @@
    8.99                      if (!isTerminal(newStatements)) {
   8.100                          newStatements.add(throwNode);
   8.101                      }
   8.102 -                    return new Block(throwNode.getLineNumber(), throwNode.getToken(), throwNode.getFinish(), newStatements);
   8.103 +                    return BlockStatement.createReplacement(throwNode, newStatements);
   8.104                  }
   8.105                  return throwNode;
   8.106              }
   8.107  
   8.108              @Override
   8.109              public Node leaveBreakNode(final BreakNode breakNode) {
   8.110 -                return copy(breakNode, Lower.this.lc.getBreakable(breakNode.getLabel()));
   8.111 +                return copy(breakNode, (Node)Lower.this.lc.getBreakable(breakNode.getLabel()));
   8.112              }
   8.113  
   8.114              @Override
   8.115 @@ -372,15 +377,15 @@
   8.116  
   8.117              @Override
   8.118              public Node leaveReturnNode(final ReturnNode returnNode) {
   8.119 -                final Node  expr  = returnNode.getExpression();
   8.120 +                final Expression expr  = returnNode.getExpression();
   8.121                  final List<Statement> newStatements = new ArrayList<>();
   8.122  
   8.123 -                final Node resultNode;
   8.124 +                final Expression resultNode;
   8.125                  if (expr != null) {
   8.126                      //we need to evaluate the result of the return in case it is complex while
   8.127                      //still in the try block, store it in a result value and return it afterwards
   8.128                      resultNode = new IdentNode(Lower.this.compilerConstant(RETURN));
   8.129 -                    newStatements.add(new ExecuteNode(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new BinaryNode(Token.recast(returnNode.getToken(), TokenType.ASSIGN), resultNode, expr)));
   8.130 +                    newStatements.add(new ExpressionStatement(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new BinaryNode(Token.recast(returnNode.getToken(), TokenType.ASSIGN), resultNode, expr)));
   8.131                  } else {
   8.132                      resultNode = null;
   8.133                  }
   8.134 @@ -390,7 +395,7 @@
   8.135                      newStatements.add(expr == null ? returnNode : returnNode.setExpression(resultNode));
   8.136                  }
   8.137  
   8.138 -                return new ExecuteNode(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new Block(returnNode.getLineNumber(), returnNode.getToken(), lc.getCurrentBlock().getFinish(), newStatements));
   8.139 +                return BlockStatement.createReplacement(returnNode, lc.getCurrentBlock().getFinish(), newStatements);
   8.140              }
   8.141  
   8.142              private Node copy(final Statement endpoint, final Node targetNode) {
   8.143 @@ -399,7 +404,7 @@
   8.144                      if (!isTerminal(newStatements)) {
   8.145                          newStatements.add(endpoint);
   8.146                      }
   8.147 -                    return new ExecuteNode(endpoint.getLineNumber(), endpoint.getToken(), endpoint.getFinish(), new Block(endpoint.getLineNumber(), endpoint.getToken(), finish, newStatements));
   8.148 +                    return BlockStatement.createReplacement(endpoint, finish, newStatements);
   8.149                  }
   8.150                  return endpoint;
   8.151              }
   8.152 @@ -461,7 +466,7 @@
   8.153          if (tryNode.getCatchBlocks().isEmpty()) {
   8.154              newTryNode = tryNode.setFinallyBody(null);
   8.155          } else {
   8.156 -            Block outerBody = new Block(tryNode.getLineNumber(), tryNode.getToken(), tryNode.getFinish(), new ArrayList<Statement>(Arrays.asList(tryNode.setFinallyBody(null))));
   8.157 +            Block outerBody = new Block(tryNode.getToken(), tryNode.getFinish(), new ArrayList<Statement>(Arrays.asList(tryNode.setFinallyBody(null))));
   8.158              newTryNode = tryNode.setBody(outerBody).setCatchBlocks(null);
   8.159          }
   8.160  
   8.161 @@ -478,7 +483,7 @@
   8.162      public Node leaveVarNode(final VarNode varNode) {
   8.163          addStatement(varNode);
   8.164          if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION) && lc.getCurrentFunction().isProgram()) {
   8.165 -            new ExecuteNode(varNode.getLineNumber(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this);
   8.166 +            new ExpressionStatement(varNode.getLineNumber(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this);
   8.167          }
   8.168          return varNode;
   8.169      }
   8.170 @@ -511,7 +516,7 @@
   8.171       * @param function function called by a CallNode
   8.172       * @return transformed node to marker function or identity if not ident/access/indexnode
   8.173       */
   8.174 -    private static Node markerFunction(final Node function) {
   8.175 +    private static Expression markerFunction(final Expression function) {
   8.176          if (function instanceof IdentNode) {
   8.177              return ((IdentNode)function).setIsFunction();
   8.178          } else if (function instanceof BaseNode) {
   8.179 @@ -553,15 +558,15 @@
   8.180      private CallNode checkEval(final CallNode callNode) {
   8.181          if (callNode.getFunction() instanceof IdentNode) {
   8.182  
   8.183 -            final List<Node> args   = callNode.getArgs();
   8.184 -            final IdentNode  callee = (IdentNode)callNode.getFunction();
   8.185 +            final List<Expression> args = callNode.getArgs();
   8.186 +            final IdentNode callee = (IdentNode)callNode.getFunction();
   8.187  
   8.188              // 'eval' call with at least one argument
   8.189              if (args.size() >= 1 && EVAL.symbolName().equals(callee.getName())) {
   8.190                  final FunctionNode currentFunction = lc.getCurrentFunction();
   8.191                  return callNode.setEvalArgs(
   8.192                      new CallNode.EvalArgs(
   8.193 -                        ensureUniqueNamesIn(args.get(0)).accept(this),
   8.194 +                        (Expression)ensureUniqueNamesIn(args.get(0)).accept(this),
   8.195                          compilerConstant(THIS),
   8.196                          evalLocation(callee),
   8.197                          currentFunction.isStrict()));
   8.198 @@ -630,7 +635,7 @@
   8.199       * @param expression expression to check for internal symbol
   8.200       * @return true if internal, false otherwise
   8.201       */
   8.202 -    private static boolean isInternalExpression(final Node expression) {
   8.203 +    private static boolean isInternalExpression(final Expression expression) {
   8.204          final Symbol symbol = expression.getSymbol();
   8.205          return symbol != null && symbol.isInternal();
   8.206      }
     9.1 --- a/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java	Thu Jul 11 18:23:13 2013 +0530
     9.2 +++ b/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java	Thu Jul 11 18:33:33 2013 +0200
     9.3 @@ -28,11 +28,11 @@
     9.4  import java.util.HashMap;
     9.5  import java.util.HashSet;
     9.6  import java.util.Map;
     9.7 -
     9.8  import jdk.nashorn.internal.codegen.types.Range;
     9.9  import jdk.nashorn.internal.codegen.types.Type;
    9.10  import jdk.nashorn.internal.ir.Assignment;
    9.11  import jdk.nashorn.internal.ir.BinaryNode;
    9.12 +import jdk.nashorn.internal.ir.Expression;
    9.13  import jdk.nashorn.internal.ir.ForNode;
    9.14  import jdk.nashorn.internal.ir.IdentNode;
    9.15  import jdk.nashorn.internal.ir.LexicalContext;
    9.16 @@ -87,7 +87,7 @@
    9.17      }
    9.18  
    9.19      //destination visited
    9.20 -    private Symbol setRange(final Node dest, final Range range) {
    9.21 +    private Symbol setRange(final Expression dest, final Range range) {
    9.22          if (range.isUnknown()) {
    9.23              return null;
    9.24          }
    9.25 @@ -352,7 +352,6 @@
    9.26              range = range.isUnknown() ? Range.createGenericRange() : range;
    9.27  
    9.28              setRange(node.getName(), range);
    9.29 -            setRange(node, range);
    9.30          }
    9.31  
    9.32          return node;
    9.33 @@ -438,12 +437,12 @@
    9.34       * @return
    9.35       */
    9.36      private static Symbol findLoopCounter(final LoopNode node) {
    9.37 -        final Node test = node.getTest();
    9.38 +        final Expression test = node.getTest();
    9.39  
    9.40          if (test != null && test.isComparison()) {
    9.41              final BinaryNode binaryNode = (BinaryNode)test;
    9.42 -            final Node lhs = binaryNode.lhs();
    9.43 -            final Node rhs = binaryNode.rhs();
    9.44 +            final Expression lhs = binaryNode.lhs();
    9.45 +            final Expression rhs = binaryNode.rhs();
    9.46  
    9.47              //detect ident cmp int_literal
    9.48              if (lhs instanceof IdentNode && rhs instanceof LiteralNode && ((LiteralNode<?>)rhs).getType().isInteger()) {
    10.1 --- a/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Thu Jul 11 18:23:13 2013 +0530
    10.2 +++ b/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java	Thu Jul 11 18:33:33 2013 +0200
    10.3 @@ -25,26 +25,25 @@
    10.4  
    10.5  package jdk.nashorn.internal.codegen;
    10.6  
    10.7 +import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
    10.8 +import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
    10.9 +
   10.10 +import java.util.List;
   10.11  import jdk.nashorn.internal.codegen.types.Type;
   10.12 +import jdk.nashorn.internal.ir.Expression;
   10.13  import jdk.nashorn.internal.ir.LiteralNode;
   10.14 -import jdk.nashorn.internal.ir.Node;
   10.15  import jdk.nashorn.internal.ir.Symbol;
   10.16  import jdk.nashorn.internal.runtime.Property;
   10.17  import jdk.nashorn.internal.runtime.PropertyMap;
   10.18  import jdk.nashorn.internal.runtime.ScriptObject;
   10.19  import jdk.nashorn.internal.scripts.JO;
   10.20  
   10.21 -import java.util.List;
   10.22 -
   10.23 -import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
   10.24 -import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
   10.25 -
   10.26  /**
   10.27   * An object creator that uses spill properties.
   10.28   */
   10.29  public class SpillObjectCreator extends ObjectCreator {
   10.30  
   10.31 -    private final List<Node> values;
   10.32 +    private final List<Expression> values;
   10.33  
   10.34      /**
   10.35       * Constructor
   10.36 @@ -54,7 +53,7 @@
   10.37       * @param symbols  symbols for fields in object
   10.38       * @param values   list of values corresponding to keys
   10.39       */
   10.40 -    protected SpillObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<Node> values) {
   10.41 +    protected SpillObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<Expression> values) {
   10.42          super(codegen, keys, symbols, false, false);
   10.43          this.values = values;
   10.44          makeMap();
   10.45 @@ -107,7 +106,7 @@
   10.46          for (int i = 0; i < length; i++) {
   10.47              final String key = keys.get(i);
   10.48              final Property property = propertyMap.findProperty(key);
   10.49 -            final Node value = values.get(i);
   10.50 +            final Expression value = values.get(i);
   10.51  
   10.52              if (property == null && value != null) {
   10.53                  method.dup();
    11.1 --- a/src/jdk/nashorn/internal/codegen/Splitter.java	Thu Jul 11 18:23:13 2013 +0530
    11.2 +++ b/src/jdk/nashorn/internal/codegen/Splitter.java	Thu Jul 11 18:33:33 2013 +0200
    11.3 @@ -31,7 +31,6 @@
    11.4  import java.util.HashMap;
    11.5  import java.util.List;
    11.6  import java.util.Map;
    11.7 -
    11.8  import jdk.nashorn.internal.ir.Block;
    11.9  import jdk.nashorn.internal.ir.FunctionNode;
   11.10  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
   11.11 @@ -221,14 +220,13 @@
   11.12       * @return New split node.
   11.13       */
   11.14      private SplitNode createBlockSplitNode(final Block parent, final FunctionNode function, final List<Statement> statements, final long weight) {
   11.15 -        final int    lineNumber = parent.getLineNumber();
   11.16          final long   token      = parent.getToken();
   11.17          final int    finish     = parent.getFinish();
   11.18          final String name       = function.uniqueName(SPLIT_PREFIX.symbolName());
   11.19  
   11.20 -        final Block newBlock = new Block(lineNumber, token, finish, statements);
   11.21 +        final Block newBlock = new Block(token, finish, statements);
   11.22  
   11.23 -        return new SplitNode(lineNumber, name, newBlock, compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT));
   11.24 +        return new SplitNode(name, newBlock, compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT));
   11.25      }
   11.26  
   11.27      @Override
    12.1 --- a/src/jdk/nashorn/internal/codegen/WeighNodes.java	Thu Jul 11 18:23:13 2013 +0530
    12.2 +++ b/src/jdk/nashorn/internal/codegen/WeighNodes.java	Thu Jul 11 18:33:33 2013 +0200
    12.3 @@ -27,7 +27,6 @@
    12.4  
    12.5  import java.util.List;
    12.6  import java.util.Map;
    12.7 -
    12.8  import jdk.nashorn.internal.codegen.types.Type;
    12.9  import jdk.nashorn.internal.ir.AccessNode;
   12.10  import jdk.nashorn.internal.ir.BinaryNode;
   12.11 @@ -36,7 +35,7 @@
   12.12  import jdk.nashorn.internal.ir.CallNode;
   12.13  import jdk.nashorn.internal.ir.CatchNode;
   12.14  import jdk.nashorn.internal.ir.ContinueNode;
   12.15 -import jdk.nashorn.internal.ir.ExecuteNode;
   12.16 +import jdk.nashorn.internal.ir.ExpressionStatement;
   12.17  import jdk.nashorn.internal.ir.ForNode;
   12.18  import jdk.nashorn.internal.ir.FunctionNode;
   12.19  import jdk.nashorn.internal.ir.IdentNode;
   12.20 @@ -158,8 +157,8 @@
   12.21      }
   12.22  
   12.23      @Override
   12.24 -    public Node leaveExecuteNode(final ExecuteNode executeNode) {
   12.25 -        return executeNode;
   12.26 +    public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) {
   12.27 +        return expressionStatement;
   12.28      }
   12.29  
   12.30      @Override
    13.1 --- a/src/jdk/nashorn/internal/ir/AccessNode.java	Thu Jul 11 18:23:13 2013 +0530
    13.2 +++ b/src/jdk/nashorn/internal/ir/AccessNode.java	Thu Jul 11 18:33:33 2013 +0200
    13.3 @@ -45,12 +45,12 @@
    13.4       * @param base      base node
    13.5       * @param property  property
    13.6       */
    13.7 -    public AccessNode(final long token, final int finish, final Node base, final IdentNode property) {
    13.8 +    public AccessNode(final long token, final int finish, final Expression base, final IdentNode property) {
    13.9          super(token, finish, base, false, false);
   13.10          this.property = property.setIsPropertyName();
   13.11      }
   13.12  
   13.13 -    private AccessNode(final AccessNode accessNode, final Node base, final IdentNode property, final boolean isFunction, final boolean hasCallSiteType) {
   13.14 +    private AccessNode(final AccessNode accessNode, final Expression base, final IdentNode property, final boolean isFunction, final boolean hasCallSiteType) {
   13.15          super(accessNode, base, isFunction, hasCallSiteType);
   13.16          this.property = property;
   13.17      }
   13.18 @@ -63,7 +63,7 @@
   13.19      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   13.20          if (visitor.enterAccessNode(this)) {
   13.21              return visitor.leaveAccessNode(
   13.22 -                setBase(base.accept(visitor)).
   13.23 +                setBase((Expression)base.accept(visitor)).
   13.24                  setProperty((IdentNode)property.accept(visitor)));
   13.25          }
   13.26          return this;
   13.27 @@ -103,7 +103,7 @@
   13.28          return property;
   13.29      }
   13.30  
   13.31 -    private AccessNode setBase(final Node base) {
   13.32 +    private AccessNode setBase(final Expression base) {
   13.33          if (this.base == base) {
   13.34              return this;
   13.35          }
    14.1 --- a/src/jdk/nashorn/internal/ir/Assignment.java	Thu Jul 11 18:23:13 2013 +0530
    14.2 +++ b/src/jdk/nashorn/internal/ir/Assignment.java	Thu Jul 11 18:33:33 2013 +0200
    14.3 @@ -31,7 +31,7 @@
    14.4   *
    14.5   * @param <D> the destination type
    14.6   */
    14.7 -public interface Assignment<D extends Node> {
    14.8 +public interface Assignment<D extends Expression> {
    14.9  
   14.10      /**
   14.11       * Get assignment destination
   14.12 @@ -45,7 +45,7 @@
   14.13       *
   14.14       * @return get the assignment source node
   14.15       */
   14.16 -    public Node getAssignmentSource();
   14.17 +    public Expression getAssignmentSource();
   14.18  
   14.19      /**
   14.20       * Set assignment destination node.
    15.1 --- a/src/jdk/nashorn/internal/ir/BaseNode.java	Thu Jul 11 18:23:13 2013 +0530
    15.2 +++ b/src/jdk/nashorn/internal/ir/BaseNode.java	Thu Jul 11 18:33:33 2013 +0200
    15.3 @@ -26,6 +26,7 @@
    15.4  package jdk.nashorn.internal.ir;
    15.5  
    15.6  import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
    15.7 +
    15.8  import jdk.nashorn.internal.codegen.ObjectClassGenerator;
    15.9  import jdk.nashorn.internal.codegen.types.Type;
   15.10  import jdk.nashorn.internal.ir.annotations.Immutable;
   15.11 @@ -37,10 +38,10 @@
   15.12   * @see IndexNode
   15.13   */
   15.14  @Immutable
   15.15 -public abstract class BaseNode extends Node implements FunctionCall, TypeOverride<BaseNode> {
   15.16 +public abstract class BaseNode extends Expression implements FunctionCall, TypeOverride<BaseNode> {
   15.17  
   15.18      /** Base Node. */
   15.19 -    protected final Node base;
   15.20 +    protected final Expression base;
   15.21  
   15.22      private final boolean isFunction;
   15.23  
   15.24 @@ -55,7 +56,7 @@
   15.25       * @param isFunction is this a function
   15.26       * @param hasCallSiteType does this access have a callsite type
   15.27       */
   15.28 -    public BaseNode(final long token, final int finish, final Node base, final boolean isFunction, final boolean hasCallSiteType) {
   15.29 +    public BaseNode(final long token, final int finish, final Expression base, final boolean isFunction, final boolean hasCallSiteType) {
   15.30          super(token, base.getStart(), finish);
   15.31          this.base            = base;
   15.32          this.isFunction      = isFunction;
   15.33 @@ -69,7 +70,7 @@
   15.34       * @param isFunction is this a function
   15.35       * @param hasCallSiteType does this access have a callsite type
   15.36       */
   15.37 -    protected BaseNode(final BaseNode baseNode, final Node base, final boolean isFunction, final boolean hasCallSiteType) {
   15.38 +    protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction, final boolean hasCallSiteType) {
   15.39          super(baseNode);
   15.40          this.base            = base;
   15.41          this.isFunction      = isFunction;
   15.42 @@ -80,7 +81,7 @@
   15.43       * Get the base node for this access
   15.44       * @return the base node
   15.45       */
   15.46 -    public Node getBase() {
   15.47 +    public Expression getBase() {
   15.48          return base;
   15.49      }
   15.50  
    16.1 --- a/src/jdk/nashorn/internal/ir/BinaryNode.java	Thu Jul 11 18:23:13 2013 +0530
    16.2 +++ b/src/jdk/nashorn/internal/ir/BinaryNode.java	Thu Jul 11 18:33:33 2013 +0200
    16.3 @@ -34,11 +34,11 @@
    16.4   * BinaryNode nodes represent two operand operations.
    16.5   */
    16.6  @Immutable
    16.7 -public final class BinaryNode extends Node implements Assignment<Node> {
    16.8 +public final class BinaryNode extends Expression implements Assignment<Expression> {
    16.9      /** Left hand side argument. */
   16.10 -    private final Node lhs;
   16.11 +    private final Expression lhs;
   16.12  
   16.13 -    private final Node rhs;
   16.14 +    private final Expression rhs;
   16.15  
   16.16      /**
   16.17       * Constructor
   16.18 @@ -47,13 +47,13 @@
   16.19       * @param lhs    left hand side
   16.20       * @param rhs    right hand side
   16.21       */
   16.22 -    public BinaryNode(final long token, final Node lhs, final Node rhs) {
   16.23 +    public BinaryNode(final long token, final Expression lhs, final Expression rhs) {
   16.24          super(token, lhs.getStart(), rhs.getFinish());
   16.25          this.lhs   = lhs;
   16.26          this.rhs   = rhs;
   16.27      }
   16.28  
   16.29 -    private BinaryNode(final BinaryNode binaryNode, final Node lhs, final Node rhs) {
   16.30 +    private BinaryNode(final BinaryNode binaryNode, final Expression lhs, final Expression rhs) {
   16.31          super(binaryNode);
   16.32          this.lhs = lhs;
   16.33          this.rhs = rhs;
   16.34 @@ -141,17 +141,17 @@
   16.35      }
   16.36  
   16.37      @Override
   16.38 -    public Node getAssignmentDest() {
   16.39 +    public Expression getAssignmentDest() {
   16.40          return isAssignment() ? lhs() : null;
   16.41      }
   16.42  
   16.43      @Override
   16.44 -    public Node setAssignmentDest(Node n) {
   16.45 +    public BinaryNode setAssignmentDest(Expression n) {
   16.46          return setLHS(n);
   16.47      }
   16.48  
   16.49      @Override
   16.50 -    public Node getAssignmentSource() {
   16.51 +    public Expression getAssignmentSource() {
   16.52          return rhs();
   16.53      }
   16.54  
   16.55 @@ -162,7 +162,7 @@
   16.56      @Override
   16.57      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   16.58          if (visitor.enterBinaryNode(this)) {
   16.59 -            return visitor.leaveBinaryNode(setLHS(lhs.accept(visitor)).setRHS(rhs.accept(visitor)));
   16.60 +            return visitor.leaveBinaryNode(setLHS((Expression)lhs.accept(visitor)).setRHS((Expression)rhs.accept(visitor)));
   16.61          }
   16.62  
   16.63          return this;
   16.64 @@ -218,7 +218,7 @@
   16.65       * Get the left hand side expression for this node
   16.66       * @return the left hand side expression
   16.67       */
   16.68 -    public Node lhs() {
   16.69 +    public Expression lhs() {
   16.70          return lhs;
   16.71      }
   16.72  
   16.73 @@ -226,7 +226,7 @@
   16.74       * Get the right hand side expression for this node
   16.75       * @return the left hand side expression
   16.76       */
   16.77 -    public Node rhs() {
   16.78 +    public Expression rhs() {
   16.79          return rhs;
   16.80      }
   16.81  
   16.82 @@ -235,7 +235,7 @@
   16.83       * @param lhs new left hand side expression
   16.84       * @return a node equivalent to this one except for the requested change.
   16.85       */
   16.86 -    public BinaryNode setLHS(final Node lhs) {
   16.87 +    public BinaryNode setLHS(final Expression lhs) {
   16.88          if (this.lhs == lhs) {
   16.89              return this;
   16.90          }
   16.91 @@ -247,7 +247,7 @@
   16.92       * @param rhs new left hand side expression
   16.93       * @return a node equivalent to this one except for the requested change.
   16.94       */
   16.95 -    public BinaryNode setRHS(final Node rhs) {
   16.96 +    public BinaryNode setRHS(final Expression rhs) {
   16.97          if (this.rhs == rhs) {
   16.98              return this;
   16.99          }
    17.1 --- a/src/jdk/nashorn/internal/ir/Block.java	Thu Jul 11 18:23:13 2013 +0530
    17.2 +++ b/src/jdk/nashorn/internal/ir/Block.java	Thu Jul 11 18:33:33 2013 +0200
    17.3 @@ -38,11 +38,10 @@
    17.4  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    17.5  
    17.6  /**
    17.7 - * IR representation for a list of statements and functions. All provides the
    17.8 - * basis for script body.
    17.9 + * IR representation for a list of statements.
   17.10   */
   17.11  @Immutable
   17.12 -public class Block extends BreakableNode implements Flags<Block> {
   17.13 +public class Block extends Node implements BreakableNode, Flags<Block> {
   17.14      /** List of statements */
   17.15      protected final List<Statement> statements;
   17.16  
   17.17 @@ -52,6 +51,9 @@
   17.18      /** Entry label. */
   17.19      protected final Label entryLabel;
   17.20  
   17.21 +    /** Break label. */
   17.22 +    private final Label breakLabel;
   17.23 +
   17.24      /** Does the block/function need a new scope? */
   17.25      protected final int flags;
   17.26  
   17.27 @@ -76,17 +78,17 @@
   17.28      /**
   17.29       * Constructor
   17.30       *
   17.31 -     * @param lineNumber line number
   17.32       * @param token      token
   17.33       * @param finish     finish
   17.34       * @param statements statements
   17.35       */
   17.36 -    public Block(final int lineNumber, final long token, final int finish, final Statement... statements) {
   17.37 -        super(lineNumber, token, finish, new Label("block_break"));
   17.38 +    public Block(final long token, final int finish, final Statement... statements) {
   17.39 +        super(token, finish);
   17.40  
   17.41          this.statements = Arrays.asList(statements);
   17.42          this.symbols    = new LinkedHashMap<>();
   17.43          this.entryLabel = new Label("block_entry");
   17.44 +        this.breakLabel = new Label("block_break");
   17.45          this.flags     =  0;
   17.46      }
   17.47  
   17.48 @@ -98,8 +100,8 @@
   17.49       * @param finish     finish
   17.50       * @param statements statements
   17.51       */
   17.52 -    public Block(final int lineNumber, final long token, final int finish, final List<Statement> statements) {
   17.53 -        this(lineNumber, token, finish, statements.toArray(new Statement[statements.size()]));
   17.54 +    public Block(final long token, final int finish, final List<Statement> statements) {
   17.55 +        this(token, finish, statements.toArray(new Statement[statements.size()]));
   17.56      }
   17.57  
   17.58      private Block(final Block block, final int finish, final List<Statement> statements, final int flags, final Map<String, Symbol> symbols) {
   17.59 @@ -108,6 +110,7 @@
   17.60          this.flags      = flags;
   17.61          this.symbols    = new LinkedHashMap<>(symbols); //todo - symbols have no dependencies on any IR node and can as far as we understand it be shallow copied now
   17.62          this.entryLabel = new Label(block.entryLabel);
   17.63 +        this.breakLabel = new Label(block.breakLabel);
   17.64          this.finish     = finish;
   17.65      }
   17.66  
   17.67 @@ -223,6 +226,11 @@
   17.68          return entryLabel;
   17.69      }
   17.70  
   17.71 +    @Override
   17.72 +    public Label getBreakLabel() {
   17.73 +        return breakLabel;
   17.74 +    }
   17.75 +
   17.76      /**
   17.77       * Get the list of statements in this block
   17.78       *
   17.79 @@ -322,7 +330,17 @@
   17.80      }
   17.81  
   17.82      @Override
   17.83 -    protected boolean isBreakableWithoutLabel() {
   17.84 +    public boolean isBreakableWithoutLabel() {
   17.85          return false;
   17.86      }
   17.87 +
   17.88 +    @Override
   17.89 +    public List<Label> getLabels() {
   17.90 +        return Collections.singletonList(breakLabel);
   17.91 +    }
   17.92 +
   17.93 +    @Override
   17.94 +    public Node accept(NodeVisitor<? extends LexicalContext> visitor) {
   17.95 +        return Acceptor.accept(this, visitor);
   17.96 +    }
   17.97  }
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/jdk/nashorn/internal/ir/BlockStatement.java	Thu Jul 11 18:33:33 2013 +0200
    18.3 @@ -0,0 +1,115 @@
    18.4 +/*
    18.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    18.7 + *
    18.8 + * This code is free software; you can redistribute it and/or modify it
    18.9 + * under the terms of the GNU General Public License version 2 only, as
   18.10 + * published by the Free Software Foundation.  Oracle designates this
   18.11 + * particular file as subject to the "Classpath" exception as provided
   18.12 + * by Oracle in the LICENSE file that accompanied this code.
   18.13 + *
   18.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   18.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   18.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   18.17 + * version 2 for more details (a copy is included in the LICENSE file that
   18.18 + * accompanied this code).
   18.19 + *
   18.20 + * You should have received a copy of the GNU General Public License version
   18.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   18.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18.23 + *
   18.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   18.25 + * or visit www.oracle.com if you need additional information or have any
   18.26 + * questions.
   18.27 + */
   18.28 +
   18.29 +package jdk.nashorn.internal.ir;
   18.30 +
   18.31 +import java.util.List;
   18.32 +import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   18.33 +
   18.34 +/**
   18.35 + * Represents a block used as a statement.
   18.36 + */
   18.37 +public class BlockStatement extends Statement {
   18.38 +    /** Block to execute. */
   18.39 +    private final Block block;
   18.40 +
   18.41 +    /**
   18.42 +     * Constructor
   18.43 +     *
   18.44 +     * @param lineNumber line number
   18.45 +     * @param block the block to execute
   18.46 +     */
   18.47 +    public BlockStatement(final int lineNumber, final Block block) {
   18.48 +        super(lineNumber, block.getToken(), block.getFinish());
   18.49 +        this.block = block;
   18.50 +    }
   18.51 +
   18.52 +    private BlockStatement(final BlockStatement blockStatement, final Block block) {
   18.53 +        super(blockStatement);
   18.54 +        this.block = block;
   18.55 +    }
   18.56 +
   18.57 +    /**
   18.58 +     * Use this method to create a block statement meant to replace a single statement.
   18.59 +     * @param stmt the statement to replace
   18.60 +     * @param newStmts the statements for the new block statement
   18.61 +     * @return a block statement with the new statements. It will have the line number, token, and finish of the
   18.62 +     * original statement.
   18.63 +     */
   18.64 +    public static Statement createReplacement(final Statement stmt, final List<Statement> newStmts) {
   18.65 +        return createReplacement(stmt, stmt.getFinish(), newStmts);
   18.66 +    }
   18.67 +
   18.68 +    /**
   18.69 +     * Use this method to create a block statement meant to replace a single statement.
   18.70 +     * @param stmt the statement to replace
   18.71 +     * @param finish the new finish for the block
   18.72 +     * @param newStmts the statements for the new block statement
   18.73 +     * @return a block statement with the new statements. It will have the line number, and token of the
   18.74 +     * original statement.
   18.75 +     */
   18.76 +    public static Statement createReplacement(final Statement stmt, int finish, final List<Statement> newStmts) {
   18.77 +        return new BlockStatement(stmt.getLineNumber(), new Block(stmt.getToken(), finish, newStmts));
   18.78 +    }
   18.79 +
   18.80 +    @Override
   18.81 +    public boolean isTerminal() {
   18.82 +        return block.isTerminal();
   18.83 +    }
   18.84 +
   18.85 +    @Override
   18.86 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   18.87 +        if (visitor.enterBlockStatement(this)) {
   18.88 +            return visitor.leaveBlockStatement(setBlock((Block)block.accept(visitor)));
   18.89 +        }
   18.90 +
   18.91 +        return this;
   18.92 +    }
   18.93 +
   18.94 +    @Override
   18.95 +    public void toString(final StringBuilder sb) {
   18.96 +        block.toString(sb);
   18.97 +    }
   18.98 +
   18.99 +    /**
  18.100 +     * Return the block to be executed
  18.101 +     * @return the block
  18.102 +     */
  18.103 +    public Block getBlock() {
  18.104 +        return block;
  18.105 +    }
  18.106 +
  18.107 +    /**
  18.108 +     * Reset the block to be executed
  18.109 +     * @param block the block
  18.110 +     * @return new or same execute node
  18.111 +     */
  18.112 +    public BlockStatement setBlock(final Block block) {
  18.113 +        if (this.block == block) {
  18.114 +            return this;
  18.115 +        }
  18.116 +        return new BlockStatement(this, block);
  18.117 +    }
  18.118 +}
    19.1 --- a/src/jdk/nashorn/internal/ir/BreakableNode.java	Thu Jul 11 18:23:13 2013 +0530
    19.2 +++ b/src/jdk/nashorn/internal/ir/BreakableNode.java	Thu Jul 11 18:33:33 2013 +0200
    19.3 @@ -25,46 +25,14 @@
    19.4  
    19.5  package jdk.nashorn.internal.ir;
    19.6  
    19.7 -import java.util.Arrays;
    19.8  import java.util.List;
    19.9 -
   19.10  import jdk.nashorn.internal.codegen.Label;
   19.11 -import jdk.nashorn.internal.ir.annotations.Immutable;
   19.12  
   19.13  /**
   19.14   * This class represents a node from which control flow can execute
   19.15   * a {@code break} statement
   19.16   */
   19.17 -@Immutable
   19.18 -public abstract class BreakableNode extends LexicalContextNode {
   19.19 -
   19.20 -    /** break label. */
   19.21 -    protected final Label breakLabel;
   19.22 -
   19.23 -    /**
   19.24 -     * Constructor
   19.25 -     *
   19.26 -     * @param lineNumber line number
   19.27 -     * @param token      token
   19.28 -     * @param finish     finish
   19.29 -     * @param breakLabel break label
   19.30 -     */
   19.31 -    protected BreakableNode(final int lineNumber, final long token, final int finish, final Label breakLabel) {
   19.32 -        super(lineNumber, token, finish);
   19.33 -        this.breakLabel = breakLabel;
   19.34 -    }
   19.35 -
   19.36 -    /**
   19.37 -     * Copy constructor
   19.38 -     *
   19.39 -     * @param breakableNode source node
   19.40 -     */
   19.41 -    protected BreakableNode(final BreakableNode breakableNode) {
   19.42 -        super(breakableNode);
   19.43 -        this.breakLabel = new Label(breakableNode.getBreakLabel());
   19.44 -    }
   19.45 -
   19.46 -    @Override
   19.47 +public interface BreakableNode extends LexicalContextNode {
   19.48      public abstract Node ensureUniqueLabels(final LexicalContext lc);
   19.49  
   19.50      /**
   19.51 @@ -72,17 +40,13 @@
   19.52       * e.g. everything but Blocks, basically
   19.53       * @return true if breakable without label
   19.54       */
   19.55 -    protected boolean isBreakableWithoutLabel() {
   19.56 -        return true;
   19.57 -    }
   19.58 +    public boolean isBreakableWithoutLabel();
   19.59  
   19.60      /**
   19.61       * Return the break label, i.e. the location to go to on break.
   19.62       * @return the break label
   19.63       */
   19.64 -    public Label getBreakLabel() {
   19.65 -        return breakLabel;
   19.66 -    }
   19.67 +    public Label getBreakLabel();
   19.68  
   19.69      /**
   19.70       * Return the labels associated with this node. Breakable nodes that
   19.71 @@ -90,8 +54,5 @@
   19.72       * afterwards the node in code
   19.73       * @return list of labels representing locations around this node
   19.74       */
   19.75 -    public List<Label> getLabels() {
   19.76 -        return Arrays.asList(breakLabel);
   19.77 -    }
   19.78 -
   19.79 +    public List<Label> getLabels();
   19.80  }
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/jdk/nashorn/internal/ir/BreakableStatement.java	Thu Jul 11 18:33:33 2013 +0200
    20.3 @@ -0,0 +1,91 @@
    20.4 +/*
    20.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    20.7 + *
    20.8 + * This code is free software; you can redistribute it and/or modify it
    20.9 + * under the terms of the GNU General Public License version 2 only, as
   20.10 + * published by the Free Software Foundation.  Oracle designates this
   20.11 + * particular file as subject to the "Classpath" exception as provided
   20.12 + * by Oracle in the LICENSE file that accompanied this code.
   20.13 + *
   20.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   20.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   20.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   20.17 + * version 2 for more details (a copy is included in the LICENSE file that
   20.18 + * accompanied this code).
   20.19 + *
   20.20 + * You should have received a copy of the GNU General Public License version
   20.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   20.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20.23 + *
   20.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   20.25 + * or visit www.oracle.com if you need additional information or have any
   20.26 + * questions.
   20.27 + */
   20.28 +
   20.29 +package jdk.nashorn.internal.ir;
   20.30 +
   20.31 +import java.util.Collections;
   20.32 +import java.util.List;
   20.33 +import jdk.nashorn.internal.codegen.Label;
   20.34 +import jdk.nashorn.internal.ir.annotations.Immutable;
   20.35 +
   20.36 +@Immutable
   20.37 +abstract class BreakableStatement extends LexicalContextStatement implements BreakableNode {
   20.38 +
   20.39 +    /** break label. */
   20.40 +    protected final Label breakLabel;
   20.41 +
   20.42 +    /**
   20.43 +     * Constructor
   20.44 +     *
   20.45 +     * @param lineNumber line number
   20.46 +     * @param token      token
   20.47 +     * @param finish     finish
   20.48 +     * @param breakLabel break label
   20.49 +     */
   20.50 +    protected BreakableStatement(final int lineNumber, final long token, final int finish, final Label breakLabel) {
   20.51 +        super(lineNumber, token, finish);
   20.52 +        this.breakLabel = breakLabel;
   20.53 +    }
   20.54 +
   20.55 +    /**
   20.56 +     * Copy constructor
   20.57 +     *
   20.58 +     * @param breakableNode source node
   20.59 +     */
   20.60 +    protected BreakableStatement(final BreakableStatement breakableNode) {
   20.61 +        super(breakableNode);
   20.62 +        this.breakLabel = new Label(breakableNode.getBreakLabel());
   20.63 +    }
   20.64 +
   20.65 +    /**
   20.66 +     * Check whether this can be broken out from without using a label,
   20.67 +     * e.g. everything but Blocks, basically
   20.68 +     * @return true if breakable without label
   20.69 +     */
   20.70 +    @Override
   20.71 +    public boolean isBreakableWithoutLabel() {
   20.72 +        return true;
   20.73 +    }
   20.74 +
   20.75 +    /**
   20.76 +     * Return the break label, i.e. the location to go to on break.
   20.77 +     * @return the break label
   20.78 +     */
   20.79 +    @Override
   20.80 +    public Label getBreakLabel() {
   20.81 +        return breakLabel;
   20.82 +    }
   20.83 +
   20.84 +    /**
   20.85 +     * Return the labels associated with this node. Breakable nodes that
   20.86 +     * aren't LoopNodes only have a break label - the location immediately
   20.87 +     * afterwards the node in code
   20.88 +     * @return list of labels representing locations around this node
   20.89 +     */
   20.90 +    @Override
   20.91 +    public List<Label> getLabels() {
   20.92 +        return Collections.singletonList(breakLabel);
   20.93 +    }
   20.94 +}
    21.1 --- a/src/jdk/nashorn/internal/ir/CallNode.java	Thu Jul 11 18:23:13 2013 +0530
    21.2 +++ b/src/jdk/nashorn/internal/ir/CallNode.java	Thu Jul 11 18:33:33 2013 +0200
    21.3 @@ -27,7 +27,6 @@
    21.4  
    21.5  import java.util.Collections;
    21.6  import java.util.List;
    21.7 -
    21.8  import jdk.nashorn.internal.codegen.types.Type;
    21.9  import jdk.nashorn.internal.ir.annotations.Ignore;
   21.10  import jdk.nashorn.internal.ir.annotations.Immutable;
   21.11 @@ -37,27 +36,29 @@
   21.12   * IR representation for a function call.
   21.13   */
   21.14  @Immutable
   21.15 -public final class CallNode extends LexicalContextNode implements TypeOverride<CallNode> {
   21.16 +public final class CallNode extends LexicalContextExpression implements TypeOverride<CallNode> {
   21.17  
   21.18      private final Type type;
   21.19  
   21.20      /** Function identifier or function body. */
   21.21 -    private final Node function;
   21.22 +    private final Expression function;
   21.23  
   21.24      /** Call arguments. */
   21.25 -    private final List<Node> args;
   21.26 +    private final List<Expression> args;
   21.27  
   21.28      /** Is this a "new" operation */
   21.29      public static final int IS_NEW        = 0x1;
   21.30  
   21.31      private final int flags;
   21.32  
   21.33 +    private final int lineNumber;
   21.34 +
   21.35      /**
   21.36       * Arguments to be passed to builtin {@code eval} function
   21.37       */
   21.38      public static class EvalArgs {
   21.39          /** evaluated code */
   21.40 -        private final Node code;
   21.41 +        private final Expression code;
   21.42  
   21.43          /** 'this' passed to evaluated code */
   21.44          private final IdentNode evalThis;
   21.45 @@ -76,7 +77,7 @@
   21.46           * @param location   location for the eval call
   21.47           * @param strictMode is this a call from a strict context?
   21.48           */
   21.49 -        public EvalArgs(final Node code, final IdentNode evalThis, final String location, final boolean strictMode) {
   21.50 +        public EvalArgs(final Expression code, final IdentNode evalThis, final String location, final boolean strictMode) {
   21.51              this.code = code;
   21.52              this.evalThis = evalThis;
   21.53              this.location = location;
   21.54 @@ -87,11 +88,11 @@
   21.55           * Return the code that is to be eval:ed by this eval function
   21.56           * @return code as an AST node
   21.57           */
   21.58 -        public Node getCode() {
   21.59 +        public Expression getCode() {
   21.60              return code;
   21.61          }
   21.62  
   21.63 -        private EvalArgs setCode(final Node code) {
   21.64 +        private EvalArgs setCode(final Expression code) {
   21.65              if (this.code == code) {
   21.66                  return this;
   21.67              }
   21.68 @@ -143,18 +144,20 @@
   21.69       * @param function   the function to call
   21.70       * @param args       args to the call
   21.71       */
   21.72 -    public CallNode(final int lineNumber, final long token, final int finish, final Node function, final List<Node> args) {
   21.73 -        super(lineNumber, token, finish);
   21.74 +    public CallNode(final int lineNumber, final long token, final int finish, final Expression function, final List<Expression> args) {
   21.75 +        super(token, finish);
   21.76  
   21.77 -        this.function = function;
   21.78 -        this.args     = args;
   21.79 -        this.flags    = 0;
   21.80 -        this.type     = null;
   21.81 -        this.evalArgs = null;
   21.82 +        this.function   = function;
   21.83 +        this.args       = args;
   21.84 +        this.flags      = 0;
   21.85 +        this.type       = null;
   21.86 +        this.evalArgs   = null;
   21.87 +        this.lineNumber = lineNumber;
   21.88      }
   21.89  
   21.90 -    private CallNode(final CallNode callNode, final Node function, final List<Node> args, final int flags, final Type type, final EvalArgs evalArgs) {
   21.91 +    private CallNode(final CallNode callNode, final Expression function, final List<Expression> args, final int flags, final Type type, final EvalArgs evalArgs) {
   21.92          super(callNode);
   21.93 +        this.lineNumber = callNode.lineNumber;
   21.94          this.function = function;
   21.95          this.args = args;
   21.96          this.flags = flags;
   21.97 @@ -162,6 +165,14 @@
   21.98          this.evalArgs = evalArgs;
   21.99      }
  21.100  
  21.101 +    /**
  21.102 +     * Returns the line number.
  21.103 +     * @return the line number.
  21.104 +     */
  21.105 +    public int getLineNumber() {
  21.106 +        return lineNumber;
  21.107 +    }
  21.108 +
  21.109      @Override
  21.110      public Type getType() {
  21.111          if (hasCallSiteType()) {
  21.112 @@ -198,13 +209,13 @@
  21.113      public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
  21.114          if (visitor.enterCallNode(this)) {
  21.115              final CallNode newCallNode = (CallNode)visitor.leaveCallNode(
  21.116 -                    setFunction(function.accept(visitor)).
  21.117 -                    setArgs(Node.accept(visitor, Node.class, args)).
  21.118 +                    setFunction((Expression)function.accept(visitor)).
  21.119 +                    setArgs(Node.accept(visitor, Expression.class, args)).
  21.120                      setFlags(flags).
  21.121                      setType(null, lc, type).
  21.122                      setEvalArgs(evalArgs == null ?
  21.123                              null :
  21.124 -                            evalArgs.setCode(evalArgs.getCode().accept(visitor)).
  21.125 +                            evalArgs.setCode((Expression)evalArgs.getCode().accept(visitor)).
  21.126                                  setThis((IdentNode)evalArgs.getThis().accept(visitor))));
  21.127              // Theoretically, we'd need to instead pass lc to every setter and do a replacement on each. In practice,
  21.128              // setType from TypeOverride can't accept a lc, and we don't necessarily want to go there now.
  21.129 @@ -248,7 +259,7 @@
  21.130       * Get the arguments for the call
  21.131       * @return a list of arguments
  21.132       */
  21.133 -    public List<Node> getArgs() {
  21.134 +    public List<Expression> getArgs() {
  21.135          return Collections.unmodifiableList(args);
  21.136      }
  21.137  
  21.138 @@ -256,7 +267,7 @@
  21.139       * Reset the arguments for the call
  21.140       * @param args new arguments list
  21.141       */
  21.142 -    private CallNode setArgs(final List<Node> args) {
  21.143 +    private CallNode setArgs(final List<Expression> args) {
  21.144          if (this.args == args) {
  21.145              return this;
  21.146          }
  21.147 @@ -297,7 +308,7 @@
  21.148       * Return the function expression that this call invokes
  21.149       * @return the function
  21.150       */
  21.151 -    public Node getFunction() {
  21.152 +    public Expression getFunction() {
  21.153          return function;
  21.154      }
  21.155  
  21.156 @@ -306,7 +317,7 @@
  21.157       * @param function the function
  21.158       * @return same node or new one on state change
  21.159       */
  21.160 -    public CallNode setFunction(final Node function) {
  21.161 +    public CallNode setFunction(final Expression function) {
  21.162          if (this.function == function) {
  21.163              return this;
  21.164          }
    22.1 --- a/src/jdk/nashorn/internal/ir/CaseNode.java	Thu Jul 11 18:23:13 2013 +0530
    22.2 +++ b/src/jdk/nashorn/internal/ir/CaseNode.java	Thu Jul 11 18:33:33 2013 +0200
    22.3 @@ -36,7 +36,7 @@
    22.4  @Immutable
    22.5  public final class CaseNode extends Node {
    22.6      /** Test expression. */
    22.7 -    private final Node test;
    22.8 +    private final Expression test;
    22.9  
   22.10      /** Statements. */
   22.11      private final Block body;
   22.12 @@ -52,7 +52,7 @@
   22.13       * @param test     case test node, can be any node in JavaScript
   22.14       * @param body     case body
   22.15       */
   22.16 -    public CaseNode(final long token, final int finish, final Node test, final Block body) {
   22.17 +    public CaseNode(final long token, final int finish, final Expression test, final Block body) {
   22.18          super(token, finish);
   22.19  
   22.20          this.test  = test;
   22.21 @@ -60,7 +60,7 @@
   22.22          this.entry = new Label("entry");
   22.23      }
   22.24  
   22.25 -    CaseNode(final CaseNode caseNode, final Node test, final Block body) {
   22.26 +    CaseNode(final CaseNode caseNode, final Expression test, final Block body) {
   22.27          super(caseNode);
   22.28  
   22.29          this.test  = test;
   22.30 @@ -80,7 +80,7 @@
   22.31      @Override
   22.32      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   22.33          if (visitor.enterCaseNode(this)) {
   22.34 -            final Node  newTest = test == null ? null : test.accept(visitor);
   22.35 +            final Expression newTest = test == null ? null : (Expression)test.accept(visitor);
   22.36              final Block newBody = body == null ? null : (Block)body.accept(visitor);
   22.37  
   22.38              return visitor.leaveCaseNode(setTest(newTest).setBody(newBody));
   22.39 @@ -120,7 +120,7 @@
   22.40       * Get the test expression for this case node
   22.41       * @return the test
   22.42       */
   22.43 -    public Node getTest() {
   22.44 +    public Expression getTest() {
   22.45          return test;
   22.46      }
   22.47  
   22.48 @@ -129,7 +129,7 @@
   22.49       * @param test new test expression
   22.50       * @return new or same CaseNode
   22.51       */
   22.52 -    public CaseNode setTest(final Node test) {
   22.53 +    public CaseNode setTest(final Expression test) {
   22.54          if (this.test == test) {
   22.55              return this;
   22.56          }
    23.1 --- a/src/jdk/nashorn/internal/ir/CatchNode.java	Thu Jul 11 18:23:13 2013 +0530
    23.2 +++ b/src/jdk/nashorn/internal/ir/CatchNode.java	Thu Jul 11 18:33:33 2013 +0200
    23.3 @@ -37,7 +37,7 @@
    23.4      private final IdentNode exception;
    23.5  
    23.6      /** Exception condition. */
    23.7 -    private final Node exceptionCondition;
    23.8 +    private final Expression exceptionCondition;
    23.9  
   23.10      /** Catch body. */
   23.11      private final Block body;
   23.12 @@ -58,7 +58,7 @@
   23.13       * @param body               catch body
   23.14       * @param flags              flags
   23.15       */
   23.16 -    public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, final Node exceptionCondition, final Block body, final int flags) {
   23.17 +    public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, final Expression exceptionCondition, final Block body, final int flags) {
   23.18          super(lineNumber, token, finish);
   23.19          this.exception          = exception;
   23.20          this.exceptionCondition = exceptionCondition;
   23.21 @@ -66,7 +66,7 @@
   23.22          this.flags              = flags;
   23.23      }
   23.24  
   23.25 -    private CatchNode(final CatchNode catchNode, final IdentNode exception, final Node exceptionCondition, final Block body, final int flags) {
   23.26 +    private CatchNode(final CatchNode catchNode, final IdentNode exception, final Expression exceptionCondition, final Block body, final int flags) {
   23.27          super(catchNode);
   23.28          this.exception          = exception;
   23.29          this.exceptionCondition = exceptionCondition;
   23.30 @@ -83,7 +83,7 @@
   23.31          if (visitor.enterCatchNode(this)) {
   23.32              return visitor.leaveCatchNode(
   23.33                  setException((IdentNode)exception.accept(visitor)).
   23.34 -                setExceptionCondition(exceptionCondition == null ? null : exceptionCondition.accept(visitor)).
   23.35 +                setExceptionCondition(exceptionCondition == null ? null : (Expression)exceptionCondition.accept(visitor)).
   23.36                  setBody((Block)body.accept(visitor)));
   23.37          }
   23.38  
   23.39 @@ -119,7 +119,7 @@
   23.40       * Get the exception condition for this catch block
   23.41       * @return the exception condition
   23.42       */
   23.43 -    public Node getExceptionCondition() {
   23.44 +    public Expression getExceptionCondition() {
   23.45          return exceptionCondition;
   23.46      }
   23.47  
   23.48 @@ -128,7 +128,7 @@
   23.49       * @param exceptionCondition the new exception condition
   23.50       * @return new or same CatchNode
   23.51       */
   23.52 -    public CatchNode setExceptionCondition(final Node exceptionCondition) {
   23.53 +    public CatchNode setExceptionCondition(final Expression exceptionCondition) {
   23.54          if (this.exceptionCondition == exceptionCondition) {
   23.55              return this;
   23.56          }
    24.1 --- a/src/jdk/nashorn/internal/ir/ExecuteNode.java	Thu Jul 11 18:23:13 2013 +0530
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,97 +0,0 @@
    24.4 -/*
    24.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    24.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    24.7 - *
    24.8 - * This code is free software; you can redistribute it and/or modify it
    24.9 - * under the terms of the GNU General Public License version 2 only, as
   24.10 - * published by the Free Software Foundation.  Oracle designates this
   24.11 - * particular file as subject to the "Classpath" exception as provided
   24.12 - * by Oracle in the LICENSE file that accompanied this code.
   24.13 - *
   24.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   24.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   24.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   24.17 - * version 2 for more details (a copy is included in the LICENSE file that
   24.18 - * accompanied this code).
   24.19 - *
   24.20 - * You should have received a copy of the GNU General Public License version
   24.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   24.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   24.23 - *
   24.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   24.25 - * or visit www.oracle.com if you need additional information or have any
   24.26 - * questions.
   24.27 - */
   24.28 -
   24.29 -package jdk.nashorn.internal.ir;
   24.30 -
   24.31 -import jdk.nashorn.internal.ir.annotations.Immutable;
   24.32 -import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   24.33 -
   24.34 -/**
   24.35 - * IR representation for executing bare expressions. Basically, an expression
   24.36 - * node means "this code will be executed" and evaluating it results in
   24.37 - * statements being added to the IR
   24.38 - */
   24.39 -@Immutable
   24.40 -public final class ExecuteNode extends Statement {
   24.41 -    /** Expression to execute. */
   24.42 -    private final Node expression;
   24.43 -
   24.44 -    /**
   24.45 -     * Constructor
   24.46 -     *
   24.47 -     * @param lineNumber line number
   24.48 -     * @param token      token
   24.49 -     * @param finish     finish
   24.50 -     * @param expression the expression to execute
   24.51 -     */
   24.52 -    public ExecuteNode(final int lineNumber, final long token, final int finish, final Node expression) {
   24.53 -        super(lineNumber, token, finish);
   24.54 -        this.expression = expression;
   24.55 -    }
   24.56 -
   24.57 -    private ExecuteNode(final ExecuteNode executeNode, final Node expression) {
   24.58 -        super(executeNode);
   24.59 -        this.expression = expression;
   24.60 -    }
   24.61 -
   24.62 -    @Override
   24.63 -    public boolean isTerminal() {
   24.64 -        return expression.isTerminal();
   24.65 -    }
   24.66 -
   24.67 -    @Override
   24.68 -    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   24.69 -        if (visitor.enterExecuteNode(this)) {
   24.70 -            return visitor.leaveExecuteNode(setExpression(expression.accept(visitor)));
   24.71 -        }
   24.72 -
   24.73 -        return this;
   24.74 -    }
   24.75 -
   24.76 -    @Override
   24.77 -    public void toString(final StringBuilder sb) {
   24.78 -        expression.toString(sb);
   24.79 -    }
   24.80 -
   24.81 -    /**
   24.82 -     * Return the expression to be executed
   24.83 -     * @return the expression
   24.84 -     */
   24.85 -    public Node getExpression() {
   24.86 -        return expression;
   24.87 -    }
   24.88 -
   24.89 -    /**
   24.90 -     * Reset the expression to be executed
   24.91 -     * @param expression the expression
   24.92 -     * @return new or same execute node
   24.93 -     */
   24.94 -    public ExecuteNode setExpression(final Node expression) {
   24.95 -        if (this.expression == expression) {
   24.96 -            return this;
   24.97 -        }
   24.98 -        return new ExecuteNode(this, expression);
   24.99 -    }
  24.100 -}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/src/jdk/nashorn/internal/ir/Expression.java	Thu Jul 11 18:33:33 2013 +0200
    25.3 @@ -0,0 +1,99 @@
    25.4 +/*
    25.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    25.7 + *
    25.8 + * This code is free software; you can redistribute it and/or modify it
    25.9 + * under the terms of the GNU General Public License version 2 only, as
   25.10 + * published by the Free Software Foundation.  Oracle designates this
   25.11 + * particular file as subject to the "Classpath" exception as provided
   25.12 + * by Oracle in the LICENSE file that accompanied this code.
   25.13 + *
   25.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   25.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   25.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   25.17 + * version 2 for more details (a copy is included in the LICENSE file that
   25.18 + * accompanied this code).
   25.19 + *
   25.20 + * You should have received a copy of the GNU General Public License version
   25.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   25.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   25.23 + *
   25.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   25.25 + * or visit www.oracle.com if you need additional information or have any
   25.26 + * questions.
   25.27 + */
   25.28 +
   25.29 +package jdk.nashorn.internal.ir;
   25.30 +
   25.31 +import jdk.nashorn.internal.codegen.types.Type;
   25.32 +
   25.33 +/**
   25.34 + * Common superclass for all expression nodes. Expression nodes can have
   25.35 + * an associated symbol as well as a type.
   25.36 + *
   25.37 + */
   25.38 +public abstract class Expression extends Node {
   25.39 +    private Symbol symbol;
   25.40 +
   25.41 +    Expression(long token, int start, int finish) {
   25.42 +        super(token, start, finish);
   25.43 +    }
   25.44 +
   25.45 +    Expression(long token, int finish) {
   25.46 +        super(token, finish);
   25.47 +    }
   25.48 +
   25.49 +    Expression(Expression expr) {
   25.50 +        super(expr);
   25.51 +        this.symbol = expr.symbol;
   25.52 +    }
   25.53 +
   25.54 +    /**
   25.55 +     * Return the Symbol the compiler has assigned to this Node. The symbol
   25.56 +     * is the place where it's expression value is stored after evaluation
   25.57 +     *
   25.58 +     * @return the symbol
   25.59 +     */
   25.60 +    public Symbol getSymbol() {
   25.61 +        return symbol;
   25.62 +    }
   25.63 +
   25.64 +    /**
   25.65 +     * Assign a symbol to this node. See {@link Expression#getSymbol()} for explanation
   25.66 +     * of what a symbol is
   25.67 +     *
   25.68 +     * @param lc lexical context
   25.69 +     * @param symbol the symbol
   25.70 +     * @return new node
   25.71 +     */
   25.72 +    public Expression setSymbol(final LexicalContext lc, final Symbol symbol) {
   25.73 +        if (this.symbol == symbol) {
   25.74 +            return this;
   25.75 +        }
   25.76 +        final Expression newExpr = (Expression)clone();
   25.77 +        newExpr.symbol = symbol;
   25.78 +        return newExpr;
   25.79 +    }
   25.80 +
   25.81 +    /**
   25.82 +     * Check if the expression has a type. The default behavior is to go into the symbol
   25.83 +     * and check the symbol type, but there may be overrides, for example in
   25.84 +     * getters that require a different type than the internal representation
   25.85 +     *
   25.86 +     * @return true if a type exists
   25.87 +     */
   25.88 +    public boolean hasType() {
   25.89 +        return getSymbol() != null;
   25.90 +    }
   25.91 +
   25.92 +    /**
   25.93 +     * Returns the type of the expression. Typically this is the symbol type. No types
   25.94 +     * are stored in the expression itself, unless it implements TypeOverride.
   25.95 +     *
   25.96 +     * @return the type of the node.
   25.97 +     */
   25.98 +    public Type getType() {
   25.99 +        assert hasType() : this + " has no type";
  25.100 +        return symbol.getSymbolType();
  25.101 +    }
  25.102 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/src/jdk/nashorn/internal/ir/ExpressionStatement.java	Thu Jul 11 18:33:33 2013 +0200
    26.3 @@ -0,0 +1,97 @@
    26.4 +/*
    26.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    26.7 + *
    26.8 + * This code is free software; you can redistribute it and/or modify it
    26.9 + * under the terms of the GNU General Public License version 2 only, as
   26.10 + * published by the Free Software Foundation.  Oracle designates this
   26.11 + * particular file as subject to the "Classpath" exception as provided
   26.12 + * by Oracle in the LICENSE file that accompanied this code.
   26.13 + *
   26.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   26.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   26.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   26.17 + * version 2 for more details (a copy is included in the LICENSE file that
   26.18 + * accompanied this code).
   26.19 + *
   26.20 + * You should have received a copy of the GNU General Public License version
   26.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   26.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   26.23 + *
   26.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   26.25 + * or visit www.oracle.com if you need additional information or have any
   26.26 + * questions.
   26.27 + */
   26.28 +
   26.29 +package jdk.nashorn.internal.ir;
   26.30 +
   26.31 +import jdk.nashorn.internal.ir.annotations.Immutable;
   26.32 +import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   26.33 +
   26.34 +/**
   26.35 + * IR representation for executing bare expressions. Basically, an expression
   26.36 + * node means "this code will be executed" and evaluating it results in
   26.37 + * statements being added to the IR
   26.38 + */
   26.39 +@Immutable
   26.40 +public final class ExpressionStatement extends Statement {
   26.41 +    /** Expression to execute. */
   26.42 +    private final Expression expression;
   26.43 +
   26.44 +    /**
   26.45 +     * Constructor
   26.46 +     *
   26.47 +     * @param lineNumber line number
   26.48 +     * @param token      token
   26.49 +     * @param finish     finish
   26.50 +     * @param expression the expression to execute
   26.51 +     */
   26.52 +    public ExpressionStatement(final int lineNumber, final long token, final int finish, final Expression expression) {
   26.53 +        super(lineNumber, token, finish);
   26.54 +        this.expression = expression;
   26.55 +    }
   26.56 +
   26.57 +    private ExpressionStatement(final ExpressionStatement expressionStatement, final Expression expression) {
   26.58 +        super(expressionStatement);
   26.59 +        this.expression = expression;
   26.60 +    }
   26.61 +
   26.62 +    @Override
   26.63 +    public boolean isTerminal() {
   26.64 +        return expression.isTerminal();
   26.65 +    }
   26.66 +
   26.67 +    @Override
   26.68 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   26.69 +        if (visitor.enterExpressionStatement(this)) {
   26.70 +            return visitor.leaveExpressionStatement(setExpression((Expression)expression.accept(visitor)));
   26.71 +        }
   26.72 +
   26.73 +        return this;
   26.74 +    }
   26.75 +
   26.76 +    @Override
   26.77 +    public void toString(final StringBuilder sb) {
   26.78 +        expression.toString(sb);
   26.79 +    }
   26.80 +
   26.81 +    /**
   26.82 +     * Return the expression to be executed
   26.83 +     * @return the expression
   26.84 +     */
   26.85 +    public Expression getExpression() {
   26.86 +        return expression;
   26.87 +    }
   26.88 +
   26.89 +    /**
   26.90 +     * Reset the expression to be executed
   26.91 +     * @param expression the expression
   26.92 +     * @return new or same execute node
   26.93 +     */
   26.94 +    public ExpressionStatement setExpression(final Expression expression) {
   26.95 +        if (this.expression == expression) {
   26.96 +            return this;
   26.97 +        }
   26.98 +        return new ExpressionStatement(this, expression);
   26.99 +    }
  26.100 +}
    27.1 --- a/src/jdk/nashorn/internal/ir/ForNode.java	Thu Jul 11 18:23:13 2013 +0530
    27.2 +++ b/src/jdk/nashorn/internal/ir/ForNode.java	Thu Jul 11 18:33:33 2013 +0200
    27.3 @@ -34,10 +34,10 @@
    27.4  @Immutable
    27.5  public final class ForNode extends LoopNode {
    27.6      /** Initialize expression. */
    27.7 -    private final Node init;
    27.8 +    private final Expression init;
    27.9  
   27.10      /** Test expression. */
   27.11 -    private final Node modify;
   27.12 +    private final Expression modify;
   27.13  
   27.14      /** Iterator symbol. */
   27.15      private Symbol iterator;
   27.16 @@ -65,14 +65,14 @@
   27.17       * @param modify     modify
   27.18       * @param flags      flags
   27.19       */
   27.20 -    public ForNode(final int lineNumber, final long token, final int finish, final Node init, final Node test, final Block body, final Node modify, final int flags) {
   27.21 +    public ForNode(final int lineNumber, final long token, final int finish, final Expression init, final Expression test, final Block body, final Expression modify, final int flags) {
   27.22          super(lineNumber, token, finish, test, body, false);
   27.23          this.init   = init;
   27.24          this.modify = modify;
   27.25          this.flags  = flags;
   27.26      }
   27.27  
   27.28 -    private ForNode(final ForNode forNode, final Node init, final Node test, final Block body, final Node modify, final int flags, final boolean controlFlowEscapes) {
   27.29 +    private ForNode(final ForNode forNode, final Expression init, final Expression test, final Block body, final Expression modify, final int flags, final boolean controlFlowEscapes) {
   27.30          super(forNode, test, body, controlFlowEscapes);
   27.31          this.init   = init;
   27.32          this.modify = modify;
   27.33 @@ -86,12 +86,12 @@
   27.34      }
   27.35  
   27.36      @Override
   27.37 -    protected Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
   27.38 +    public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
   27.39          if (visitor.enterForNode(this)) {
   27.40              return visitor.leaveForNode(
   27.41 -                setInit(lc, init == null ? null : init.accept(visitor)).
   27.42 -                setTest(lc, test == null ? null : test.accept(visitor)).
   27.43 -                setModify(lc, modify == null ? null : modify.accept(visitor)).
   27.44 +                setInit(lc, init == null ? null : (Expression)init.accept(visitor)).
   27.45 +                setTest(lc, test == null ? null : (Expression)test.accept(visitor)).
   27.46 +                setModify(lc, modify == null ? null : (Expression)modify.accept(visitor)).
   27.47                  setBody(lc, (Block)body.accept(visitor)));
   27.48          }
   27.49  
   27.50 @@ -140,7 +140,7 @@
   27.51       * Get the initialization expression for this for loop
   27.52       * @return the initialization expression
   27.53       */
   27.54 -    public Node getInit() {
   27.55 +    public Expression getInit() {
   27.56          return init;
   27.57      }
   27.58  
   27.59 @@ -150,7 +150,7 @@
   27.60       * @param init new initialization expression
   27.61       * @return new for node if changed or existing if not
   27.62       */
   27.63 -    public ForNode setInit(final LexicalContext lc, final Node init) {
   27.64 +    public ForNode setInit(final LexicalContext lc, final Expression init) {
   27.65          if (this.init == init) {
   27.66              return this;
   27.67          }
   27.68 @@ -212,7 +212,7 @@
   27.69       * Get the modification expression for this ForNode
   27.70       * @return the modification expression
   27.71       */
   27.72 -    public Node getModify() {
   27.73 +    public Expression getModify() {
   27.74          return modify;
   27.75      }
   27.76  
   27.77 @@ -222,7 +222,7 @@
   27.78       * @param modify new modification expression
   27.79       * @return new for node if changed or existing if not
   27.80       */
   27.81 -    public ForNode setModify(final LexicalContext lc, final Node modify) {
   27.82 +    public ForNode setModify(final LexicalContext lc, final Expression modify) {
   27.83          if (this.modify == modify) {
   27.84              return this;
   27.85          }
   27.86 @@ -230,12 +230,12 @@
   27.87      }
   27.88  
   27.89      @Override
   27.90 -    public Node getTest() {
   27.91 +    public Expression getTest() {
   27.92          return test;
   27.93      }
   27.94  
   27.95      @Override
   27.96 -    public ForNode setTest(final LexicalContext lc, final Node test) {
   27.97 +    public ForNode setTest(final LexicalContext lc, final Expression test) {
   27.98          if (this.test == test) {
   27.99              return this;
  27.100          }
    28.1 --- a/src/jdk/nashorn/internal/ir/FunctionNode.java	Thu Jul 11 18:23:13 2013 +0530
    28.2 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java	Thu Jul 11 18:33:33 2013 +0200
    28.3 @@ -47,7 +47,7 @@
    28.4   * IR representation for function (or script.)
    28.5   */
    28.6  @Immutable
    28.7 -public final class FunctionNode extends LexicalContextNode implements Flags<FunctionNode> {
    28.8 +public final class FunctionNode extends LexicalContextExpression implements Flags<FunctionNode> {
    28.9  
   28.10      /** Type used for all FunctionNodes */
   28.11      public static final Type FUNCTION_TYPE = Type.typeFor(ScriptFunction.class);
   28.12 @@ -138,6 +138,8 @@
   28.13      /** Function flags. */
   28.14      private final int flags;
   28.15  
   28.16 +    private final int lineNumber;
   28.17 +
   28.18      /** Is anonymous function flag. */
   28.19      public static final int IS_ANONYMOUS                = 1 << 0;
   28.20  
   28.21 @@ -234,9 +236,10 @@
   28.22          final List<IdentNode> parameters,
   28.23          final FunctionNode.Kind kind,
   28.24          final int flags) {
   28.25 -        super(lineNumber, token, finish);
   28.26 +        super(token, finish);
   28.27  
   28.28          this.source           = source;
   28.29 +        this.lineNumber       = lineNumber;
   28.30          this.ident            = ident;
   28.31          this.name             = name;
   28.32          this.kind             = kind;
   28.33 @@ -266,7 +269,7 @@
   28.34          final FunctionNode snapshot,
   28.35          final Compiler.Hints hints) {
   28.36          super(functionNode);
   28.37 -
   28.38 +        this.lineNumber       = functionNode.lineNumber;
   28.39          this.flags            = flags;
   28.40          this.name             = name;
   28.41          this.returnType       = returnType;
   28.42 @@ -305,6 +308,14 @@
   28.43      }
   28.44  
   28.45      /**
   28.46 +     * Returns the line number.
   28.47 +     * @return the line number.
   28.48 +     */
   28.49 +    public int getLineNumber() {
   28.50 +        return lineNumber;
   28.51 +    }
   28.52 +
   28.53 +    /**
   28.54       * Get the version of this function node's code as it looked upon construction
   28.55       * i.e typically parsed and nothing else
   28.56       * @return initial version of function node
    29.1 --- a/src/jdk/nashorn/internal/ir/IdentNode.java	Thu Jul 11 18:23:13 2013 +0530
    29.2 +++ b/src/jdk/nashorn/internal/ir/IdentNode.java	Thu Jul 11 18:33:33 2013 +0200
    29.3 @@ -29,6 +29,7 @@
    29.4  import static jdk.nashorn.internal.codegen.CompilerConstants.__FILE__;
    29.5  import static jdk.nashorn.internal.codegen.CompilerConstants.__LINE__;
    29.6  import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
    29.7 +
    29.8  import jdk.nashorn.internal.codegen.ObjectClassGenerator;
    29.9  import jdk.nashorn.internal.codegen.types.Type;
   29.10  import jdk.nashorn.internal.ir.annotations.Immutable;
   29.11 @@ -38,7 +39,7 @@
   29.12   * IR representation for an identifier.
   29.13   */
   29.14  @Immutable
   29.15 -public final class IdentNode extends Node implements PropertyKey, TypeOverride<IdentNode>, FunctionCall {
   29.16 +public final class IdentNode extends Expression implements PropertyKey, TypeOverride<IdentNode>, FunctionCall {
   29.17      private static final int PROPERTY_NAME    = 1 << 0;
   29.18      private static final int INITIALIZED_HERE = 1 << 1;
   29.19      private static final int FUNCTION         = 1 << 2;
    30.1 --- a/src/jdk/nashorn/internal/ir/IfNode.java	Thu Jul 11 18:23:13 2013 +0530
    30.2 +++ b/src/jdk/nashorn/internal/ir/IfNode.java	Thu Jul 11 18:33:33 2013 +0200
    30.3 @@ -34,7 +34,7 @@
    30.4  @Immutable
    30.5  public final class IfNode extends Statement {
    30.6      /** Test expression. */
    30.7 -    private final Node test;
    30.8 +    private final Expression test;
    30.9  
   30.10      /** Pass statements. */
   30.11      private final Block pass;
   30.12 @@ -52,14 +52,14 @@
   30.13       * @param pass       block to execute when test passes
   30.14       * @param fail       block to execute when test fails or null
   30.15       */
   30.16 -    public IfNode(final int lineNumber, final long token, final int finish, final Node test, final Block pass, final Block fail) {
   30.17 +    public IfNode(final int lineNumber, final long token, final int finish, final Expression test, final Block pass, final Block fail) {
   30.18          super(lineNumber, token, finish);
   30.19          this.test = test;
   30.20          this.pass = pass;
   30.21          this.fail = fail;
   30.22      }
   30.23  
   30.24 -    private IfNode(final IfNode ifNode, final Node test, final Block pass, final Block fail) {
   30.25 +    private IfNode(final IfNode ifNode, final Expression test, final Block pass, final Block fail) {
   30.26          super(ifNode);
   30.27          this.test = test;
   30.28          this.pass = pass;
   30.29 @@ -75,7 +75,7 @@
   30.30      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   30.31          if (visitor.enterIfNode(this)) {
   30.32              return visitor.leaveIfNode(
   30.33 -                setTest(test.accept(visitor)).
   30.34 +                setTest((Expression)test.accept(visitor)).
   30.35                  setPass((Block)pass.accept(visitor)).
   30.36                  setFail(fail == null ? null : (Block)fail.accept(visitor)));
   30.37          }
   30.38 @@ -124,7 +124,7 @@
   30.39       * Get the test expression for this IfNode
   30.40       * @return the test expression
   30.41       */
   30.42 -    public Node getTest() {
   30.43 +    public Expression getTest() {
   30.44          return test;
   30.45      }
   30.46  
   30.47 @@ -133,7 +133,7 @@
   30.48       * @param test a new test expression
   30.49       * @return new or same IfNode
   30.50       */
   30.51 -    public IfNode setTest(final Node test) {
   30.52 +    public IfNode setTest(final Expression test) {
   30.53          if (this.test == test) {
   30.54              return this;
   30.55          }
    31.1 --- a/src/jdk/nashorn/internal/ir/IndexNode.java	Thu Jul 11 18:23:13 2013 +0530
    31.2 +++ b/src/jdk/nashorn/internal/ir/IndexNode.java	Thu Jul 11 18:33:33 2013 +0200
    31.3 @@ -35,7 +35,7 @@
    31.4  @Immutable
    31.5  public final class IndexNode extends BaseNode {
    31.6      /** Property index. */
    31.7 -    private final Node index;
    31.8 +    private final Expression index;
    31.9  
   31.10      /**
   31.11       * Constructors
   31.12 @@ -45,12 +45,12 @@
   31.13       * @param base    base node for access
   31.14       * @param index   index for access
   31.15       */
   31.16 -    public IndexNode(final long token, final int finish, final Node base, final Node index) {
   31.17 +    public IndexNode(final long token, final int finish, final Expression base, final Expression index) {
   31.18          super(token, finish, base, false, false);
   31.19          this.index = index;
   31.20      }
   31.21  
   31.22 -    private IndexNode(final IndexNode indexNode, final Node base, final Node index, final boolean isFunction, final boolean hasCallSiteType) {
   31.23 +    private IndexNode(final IndexNode indexNode, final Expression base, final Expression index, final boolean isFunction, final boolean hasCallSiteType) {
   31.24          super(indexNode, base, isFunction, hasCallSiteType);
   31.25          this.index = index;
   31.26      }
   31.27 @@ -59,8 +59,8 @@
   31.28      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   31.29          if (visitor.enterIndexNode(this)) {
   31.30              return visitor.leaveIndexNode(
   31.31 -                setBase(base.accept(visitor)).
   31.32 -                setIndex(index.accept(visitor)));
   31.33 +                setBase((Expression)base.accept(visitor)).
   31.34 +                setIndex((Expression)index.accept(visitor)));
   31.35          }
   31.36          return this;
   31.37      }
   31.38 @@ -95,11 +95,11 @@
   31.39       * Get the index expression for this IndexNode
   31.40       * @return the index
   31.41       */
   31.42 -    public Node getIndex() {
   31.43 +    public Expression getIndex() {
   31.44          return index;
   31.45      }
   31.46  
   31.47 -    private IndexNode setBase(final Node base) {
   31.48 +    private IndexNode setBase(final Expression base) {
   31.49          if (this.base == base) {
   31.50              return this;
   31.51          }
   31.52 @@ -111,7 +111,7 @@
   31.53       * @param index new index expression
   31.54       * @return a node equivalent to this one except for the requested change.
   31.55       */
   31.56 -    public IndexNode setIndex(Node index) {
   31.57 +    public IndexNode setIndex(Expression index) {
   31.58          if(this.index == index) {
   31.59              return this;
   31.60          }
    32.1 --- a/src/jdk/nashorn/internal/ir/LabelNode.java	Thu Jul 11 18:23:13 2013 +0530
    32.2 +++ b/src/jdk/nashorn/internal/ir/LabelNode.java	Thu Jul 11 18:33:33 2013 +0200
    32.3 @@ -32,7 +32,7 @@
    32.4   * IR representation for a labeled statement.
    32.5   */
    32.6  @Immutable
    32.7 -public final class LabelNode extends LexicalContextNode {
    32.8 +public final class LabelNode extends LexicalContextStatement {
    32.9      /** Label ident. */
   32.10      private final IdentNode label;
   32.11  
    33.1 --- a/src/jdk/nashorn/internal/ir/LexicalContext.java	Thu Jul 11 18:23:13 2013 +0530
    33.2 +++ b/src/jdk/nashorn/internal/ir/LexicalContext.java	Thu Jul 11 18:33:33 2013 +0200
    33.3 @@ -576,19 +576,20 @@
    33.4          final StringBuffer sb = new StringBuffer();
    33.5          sb.append("[ ");
    33.6          for (int i = 0; i < sp; i++) {
    33.7 -            final Node node = stack[i];
    33.8 +            final Object node = stack[i];
    33.9              sb.append(node.getClass().getSimpleName());
   33.10              sb.append('@');
   33.11              sb.append(Debug.id(node));
   33.12              sb.append(':');
   33.13              if (node instanceof FunctionNode) {
   33.14 -                final Source source = ((FunctionNode)node).getSource();
   33.15 +                final FunctionNode fn = (FunctionNode)node;
   33.16 +                final Source source = fn.getSource();
   33.17                  String src = source.toString();
   33.18                  if (src.indexOf(File.pathSeparator) != -1) {
   33.19                      src = src.substring(src.lastIndexOf(File.pathSeparator));
   33.20                  }
   33.21                  src += ' ';
   33.22 -                src += source.getLine(node.getStart());
   33.23 +                src += source.getLine(fn.getStart());
   33.24                  sb.append(src);
   33.25              }
   33.26              sb.append(' ');
   33.27 @@ -631,7 +632,7 @@
   33.28  
   33.29          private T findNext() {
   33.30              for (int i = index; i >= 0; i--) {
   33.31 -                final Node node = stack[i];
   33.32 +                final Object node = stack[i];
   33.33                  if (node == until) {
   33.34                      return null;
   33.35                  }
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/src/jdk/nashorn/internal/ir/LexicalContextExpression.java	Thu Jul 11 18:33:33 2013 +0200
    34.3 @@ -0,0 +1,59 @@
    34.4 +/*
    34.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    34.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    34.7 + *
    34.8 + * This code is free software; you can redistribute it and/or modify it
    34.9 + * under the terms of the GNU General Public License version 2 only, as
   34.10 + * published by the Free Software Foundation.  Oracle designates this
   34.11 + * particular file as subject to the "Classpath" exception as provided
   34.12 + * by Oracle in the LICENSE file that accompanied this code.
   34.13 + *
   34.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   34.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   34.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   34.17 + * version 2 for more details (a copy is included in the LICENSE file that
   34.18 + * accompanied this code).
   34.19 + *
   34.20 + * You should have received a copy of the GNU General Public License version
   34.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   34.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   34.23 + *
   34.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   34.25 + * or visit www.oracle.com if you need additional information or have any
   34.26 + * questions.
   34.27 + */
   34.28 +
   34.29 +package jdk.nashorn.internal.ir;
   34.30 +
   34.31 +import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   34.32 +
   34.33 +abstract class LexicalContextExpression extends Expression implements LexicalContextNode {
   34.34 +
   34.35 +    LexicalContextExpression(LexicalContextExpression expr) {
   34.36 +        super(expr);
   34.37 +    }
   34.38 +
   34.39 +    LexicalContextExpression(long token, int start, int finish) {
   34.40 +        super(token, start, finish);
   34.41 +    }
   34.42 +
   34.43 +    LexicalContextExpression(long token, int finish) {
   34.44 +        super(token, finish);
   34.45 +    }
   34.46 +
   34.47 +    @Override
   34.48 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   34.49 +        return Acceptor.accept(this, visitor);
   34.50 +    }
   34.51 +
   34.52 +    /**
   34.53 +     * Set the symbol and replace in lexical context if applicable
   34.54 +     * @param lc     lexical context
   34.55 +     * @param symbol symbol
   34.56 +     * @return new node if symbol changed
   34.57 +     */
   34.58 +    @Override
   34.59 +    public Expression setSymbol(final LexicalContext lc, final Symbol symbol) {
   34.60 +        return Node.replaceInLexicalContext(lc, this, (LexicalContextExpression)super.setSymbol(null, symbol));
   34.61 +    }
   34.62 +}
    35.1 --- a/src/jdk/nashorn/internal/ir/LexicalContextNode.java	Thu Jul 11 18:23:13 2013 +0530
    35.2 +++ b/src/jdk/nashorn/internal/ir/LexicalContextNode.java	Thu Jul 11 18:33:33 2013 +0200
    35.3 @@ -26,31 +26,12 @@
    35.4  
    35.5  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    35.6  
    35.7 +
    35.8  /**
    35.9 - * Superclass for nodes that can be part of the lexical context
   35.10 + * Interface for nodes that can be part of the lexical context.
   35.11   * @see LexicalContext
   35.12   */
   35.13 -public abstract class LexicalContextNode extends Statement {
   35.14 -    /**
   35.15 -     * Constructor
   35.16 -     *
   35.17 -     * @param lineNumber line number
   35.18 -     * @param token      token
   35.19 -     * @param finish     finish
   35.20 -     */
   35.21 -    protected LexicalContextNode(final int lineNumber, final long token, final int finish) {
   35.22 -        super(lineNumber, token, finish);
   35.23 -    }
   35.24 -
   35.25 -    /**
   35.26 -     * Copy constructor
   35.27 -     *
   35.28 -     * @param node source node
   35.29 -     */
   35.30 -    protected LexicalContextNode(final LexicalContextNode node) {
   35.31 -        super(node);
   35.32 -    }
   35.33 -
   35.34 +public interface LexicalContextNode {
   35.35      /**
   35.36       * Accept function for the node given a lexical context. It must be prepared
   35.37       * to replace itself if present in the lexical context
   35.38 @@ -60,25 +41,15 @@
   35.39       *
   35.40       * @return new node or same node depending on state change
   35.41       */
   35.42 -    protected abstract Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor);
   35.43 +    Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor);
   35.44  
   35.45 -    @Override
   35.46 -    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   35.47 -        final LexicalContext lc = visitor.getLexicalContext();
   35.48 -        lc.push(this);
   35.49 -        final LexicalContextNode newNode = (LexicalContextNode)accept(lc, visitor);
   35.50 -        return lc.pop(newNode);
   35.51 +    // Would be a default method on Java 8
   35.52 +    static class Acceptor {
   35.53 +        static Node accept(LexicalContextNode node, final NodeVisitor<? extends LexicalContext> visitor) {
   35.54 +            final LexicalContext lc = visitor.getLexicalContext();
   35.55 +            lc.push(node);
   35.56 +            final LexicalContextNode newNode = (LexicalContextNode)node.accept(lc, visitor);
   35.57 +            return (Node)lc.pop(newNode);
   35.58 +        }
   35.59      }
   35.60 -
   35.61 -    /**
   35.62 -     * Set the symbol and replace in lexical context if applicable
   35.63 -     * @param lc     lexical context
   35.64 -     * @param symbol symbol
   35.65 -     * @return new node if symbol changed
   35.66 -     */
   35.67 -    @Override
   35.68 -    public Node setSymbol(final LexicalContext lc, final Symbol symbol) {
   35.69 -        return Node.replaceInLexicalContext(lc, this, (LexicalContextNode)super.setSymbol(null, symbol));
   35.70 -    }
   35.71 -
   35.72  }
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/src/jdk/nashorn/internal/ir/LexicalContextStatement.java	Thu Jul 11 18:33:33 2013 +0200
    36.3 @@ -0,0 +1,55 @@
    36.4 +/*
    36.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    36.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    36.7 + *
    36.8 + * This code is free software; you can redistribute it and/or modify it
    36.9 + * under the terms of the GNU General Public License version 2 only, as
   36.10 + * published by the Free Software Foundation.  Oracle designates this
   36.11 + * particular file as subject to the "Classpath" exception as provided
   36.12 + * by Oracle in the LICENSE file that accompanied this code.
   36.13 + *
   36.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   36.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   36.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   36.17 + * version 2 for more details (a copy is included in the LICENSE file that
   36.18 + * accompanied this code).
   36.19 + *
   36.20 + * You should have received a copy of the GNU General Public License version
   36.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   36.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   36.23 + *
   36.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   36.25 + * or visit www.oracle.com if you need additional information or have any
   36.26 + * questions.
   36.27 + */
   36.28 +
   36.29 +package jdk.nashorn.internal.ir;
   36.30 +
   36.31 +import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   36.32 +
   36.33 +abstract class LexicalContextStatement extends Statement implements LexicalContextNode {
   36.34 +    /**
   36.35 +     * Constructor
   36.36 +     *
   36.37 +     * @param lineNumber line number
   36.38 +     * @param token      token
   36.39 +     * @param finish     finish
   36.40 +     */
   36.41 +    protected LexicalContextStatement(final int lineNumber, final long token, final int finish) {
   36.42 +        super(lineNumber, token, finish);
   36.43 +    }
   36.44 +
   36.45 +    /**
   36.46 +     * Copy constructor
   36.47 +     *
   36.48 +     * @param node source node
   36.49 +     */
   36.50 +    protected LexicalContextStatement(final LexicalContextStatement node) {
   36.51 +        super(node);
   36.52 +    }
   36.53 +
   36.54 +    @Override
   36.55 +    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   36.56 +        return Acceptor.accept(this, visitor);
   36.57 +    }
   36.58 +}
    37.1 --- a/src/jdk/nashorn/internal/ir/LiteralNode.java	Thu Jul 11 18:23:13 2013 +0530
    37.2 +++ b/src/jdk/nashorn/internal/ir/LiteralNode.java	Thu Jul 11 18:33:33 2013 +0200
    37.3 @@ -45,7 +45,7 @@
    37.4   * @param <T> the literal type
    37.5   */
    37.6  @Immutable
    37.7 -public abstract class LiteralNode<T> extends Node implements PropertyKey {
    37.8 +public abstract class LiteralNode<T> extends Expression implements PropertyKey {
    37.9      /** Literal value */
   37.10      protected final T value;
   37.11  
   37.12 @@ -551,7 +551,7 @@
   37.13      /**
   37.14       * Array literal node class.
   37.15       */
   37.16 -    public static final class ArrayLiteralNode extends LiteralNode<Node[]> {
   37.17 +    public static final class ArrayLiteralNode extends LiteralNode<Expression[]> {
   37.18  
   37.19          /** Array element type. */
   37.20          private Type elementType;
   37.21 @@ -619,7 +619,7 @@
   37.22           * @param finish  finish
   37.23           * @param value   array literal value, a Node array
   37.24           */
   37.25 -        protected ArrayLiteralNode(final long token, final int finish, final Node[] value) {
   37.26 +        protected ArrayLiteralNode(final long token, final int finish, final Expression[] value) {
   37.27              super(Token.recast(token, TokenType.ARRAY), finish, value);
   37.28              this.elementType = Type.UNKNOWN;
   37.29          }
   37.30 @@ -628,7 +628,7 @@
   37.31           * Copy constructor
   37.32           * @param node source array literal node
   37.33           */
   37.34 -        private ArrayLiteralNode(final ArrayLiteralNode node, final Node[] value) {
   37.35 +        private ArrayLiteralNode(final ArrayLiteralNode node, final Expression[] value) {
   37.36              super(node, value);
   37.37              this.elementType = node.elementType;
   37.38              this.presets     = node.presets;
   37.39 @@ -737,7 +737,7 @@
   37.40          }
   37.41  
   37.42          private void analyzeElements() {
   37.43 -            for (final Node node : value) {
   37.44 +            for (final Expression node : value) {
   37.45                  if (node == null) {
   37.46                      elementType = elementType.widest(Type.OBJECT); //no way to represent undefined as number
   37.47                      break;
   37.48 @@ -826,15 +826,15 @@
   37.49          @Override
   37.50          public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   37.51              if (visitor.enterLiteralNode(this)) {
   37.52 -                final List<Node> oldValue = Arrays.asList(value);
   37.53 -                final List<Node> newValue = Node.accept(visitor, Node.class, oldValue);
   37.54 +                final List<Expression> oldValue = Arrays.asList(value);
   37.55 +                final List<Expression> newValue = Node.accept(visitor, Expression.class, oldValue);
   37.56                  return visitor.leaveLiteralNode(oldValue != newValue ? setValue(newValue) : this);
   37.57              }
   37.58              return this;
   37.59          }
   37.60  
   37.61 -        private ArrayLiteralNode setValue(final List<Node> value) {
   37.62 -            return new ArrayLiteralNode(this, value.toArray(new Node[value.size()]));
   37.63 +        private ArrayLiteralNode setValue(final List<Expression> value) {
   37.64 +            return new ArrayLiteralNode(this, value.toArray(new Expression[value.size()]));
   37.65          }
   37.66  
   37.67          @Override
   37.68 @@ -866,8 +866,8 @@
   37.69       *
   37.70       * @return the new literal node
   37.71       */
   37.72 -    public static LiteralNode<Node[]> newInstance(final long token, final int finish, final List<Node> value) {
   37.73 -        return new ArrayLiteralNode(token, finish, value.toArray(new Node[value.size()]));
   37.74 +    public static LiteralNode<Expression[]> newInstance(final long token, final int finish, final List<Expression> value) {
   37.75 +        return new ArrayLiteralNode(token, finish, value.toArray(new Expression[value.size()]));
   37.76      }
   37.77  
   37.78  
   37.79 @@ -879,8 +879,8 @@
   37.80       *
   37.81       * @return the new literal node
   37.82       */
   37.83 -    public static LiteralNode<?> newInstance(final Node parent, final List<Node> value) {
   37.84 -        return new ArrayLiteralNode(parent.getToken(), parent.getFinish(), value.toArray(new Node[value.size()]));
   37.85 +    public static LiteralNode<?> newInstance(final Node parent, final List<Expression> value) {
   37.86 +        return new ArrayLiteralNode(parent.getToken(), parent.getFinish(), value.toArray(new Expression[value.size()]));
   37.87      }
   37.88  
   37.89      /**
   37.90 @@ -892,7 +892,7 @@
   37.91       *
   37.92       * @return the new literal node
   37.93       */
   37.94 -    public static LiteralNode<Node[]> newInstance(final long token, final int finish, final Node[] value) {
   37.95 +    public static LiteralNode<Expression[]> newInstance(final long token, final int finish, final Expression[] value) {
   37.96          return new ArrayLiteralNode(token, finish, value);
   37.97      }
   37.98  }
    38.1 --- a/src/jdk/nashorn/internal/ir/LoopNode.java	Thu Jul 11 18:23:13 2013 +0530
    38.2 +++ b/src/jdk/nashorn/internal/ir/LoopNode.java	Thu Jul 11 18:33:33 2013 +0200
    38.3 @@ -27,18 +27,17 @@
    38.4  
    38.5  import java.util.Arrays;
    38.6  import java.util.List;
    38.7 -
    38.8  import jdk.nashorn.internal.codegen.Label;
    38.9  
   38.10  /**
   38.11   * A loop node, for example a while node, do while node or for node
   38.12   */
   38.13 -public abstract class LoopNode extends BreakableNode {
   38.14 +public abstract class LoopNode extends BreakableStatement {
   38.15      /** loop continue label. */
   38.16      protected final Label continueLabel;
   38.17  
   38.18      /** Loop test node, null if infinite */
   38.19 -    protected final Node test;
   38.20 +    protected final Expression test;
   38.21  
   38.22      /** Loop body */
   38.23      protected final Block body;
   38.24 @@ -56,7 +55,7 @@
   38.25       * @param body               loop body
   38.26       * @param controlFlowEscapes controlFlowEscapes
   38.27       */
   38.28 -    protected LoopNode(final int lineNumber, final long token, final int finish, final Node test, final Block body, final boolean controlFlowEscapes) {
   38.29 +    protected LoopNode(final int lineNumber, final long token, final int finish, final Expression test, final Block body, final boolean controlFlowEscapes) {
   38.30          super(lineNumber, token, finish, new Label("while_break"));
   38.31          this.continueLabel = new Label("while_continue");
   38.32          this.test = test;
   38.33 @@ -72,7 +71,7 @@
   38.34       * @param body     new body
   38.35       * @param controlFlowEscapes controlFlowEscapes
   38.36       */
   38.37 -    protected LoopNode(final LoopNode loopNode, final Node test, final Block body, final boolean controlFlowEscapes) {
   38.38 +    protected LoopNode(final LoopNode loopNode, final Expression test, final Block body, final boolean controlFlowEscapes) {
   38.39          super(loopNode);
   38.40          this.continueLabel = new Label(loopNode.continueLabel);
   38.41          this.test = test;
   38.42 @@ -151,7 +150,7 @@
   38.43       * Get the test for this for node
   38.44       * @return the test
   38.45       */
   38.46 -    public abstract Node getTest();
   38.47 +    public abstract Expression getTest();
   38.48  
   38.49      /**
   38.50       * Set the test for this for node
   38.51 @@ -160,7 +159,7 @@
   38.52       * @param test new test
   38.53       * @return same or new node depending on if test was changed
   38.54       */
   38.55 -    public abstract LoopNode setTest(final LexicalContext lc, final Node test);
   38.56 +    public abstract LoopNode setTest(final LexicalContext lc, final Expression test);
   38.57  
   38.58      /**
   38.59       * Set the control flow escapes flag for this node.
    39.1 --- a/src/jdk/nashorn/internal/ir/Node.java	Thu Jul 11 18:23:13 2013 +0530
    39.2 +++ b/src/jdk/nashorn/internal/ir/Node.java	Thu Jul 11 18:33:33 2013 +0200
    39.3 @@ -27,7 +27,6 @@
    39.4  
    39.5  import java.util.ArrayList;
    39.6  import java.util.List;
    39.7 -
    39.8  import jdk.nashorn.internal.codegen.types.Type;
    39.9  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   39.10  import jdk.nashorn.internal.parser.Token;
   39.11 @@ -37,9 +36,6 @@
   39.12   * Nodes are used to compose Abstract Syntax Trees.
   39.13   */
   39.14  public abstract class Node implements Cloneable {
   39.15 -    /** Node symbol. */
   39.16 -    private Symbol symbol;
   39.17 -
   39.18      /** Start of source range. */
   39.19      protected final int start;
   39.20  
   39.21 @@ -81,34 +77,11 @@
   39.22       */
   39.23      protected Node(final Node node) {
   39.24          this.token  = node.token;
   39.25 -        this.symbol = node.symbol;
   39.26          this.start  = node.start;
   39.27          this.finish = node.finish;
   39.28      }
   39.29  
   39.30      /**
   39.31 -     * Check if the node has a type. The default behavior is to go into the symbol
   39.32 -     * and check the symbol type, but there may be overrides, for example in
   39.33 -     * getters that require a different type than the internal representation
   39.34 -     *
   39.35 -     * @return true if a type exists
   39.36 -     */
   39.37 -    public boolean hasType() {
   39.38 -        return getSymbol() != null;
   39.39 -    }
   39.40 -
   39.41 -    /**
   39.42 -     * Returns the type of the node. Typically this is the symbol type. No types
   39.43 -     * are stored in the node itself, unless it implements TypeOverride
   39.44 -     *
   39.45 -     * @return the type of the node.
   39.46 -     */
   39.47 -    public Type getType() {
   39.48 -        assert hasType() : this + " has no type";
   39.49 -        return symbol.getSymbolType();
   39.50 -    }
   39.51 -
   39.52 -    /**
   39.53       * Is this an atom node - for example a literal or an identity
   39.54       *
   39.55       * @return true if atom
   39.56 @@ -235,16 +208,6 @@
   39.57          return start;
   39.58      }
   39.59  
   39.60 -    /**
   39.61 -     * Return the Symbol the compiler has assigned to this Node. The symbol
   39.62 -     * is the place where it's expression value is stored after evaluation
   39.63 -     *
   39.64 -     * @return the symbol
   39.65 -     */
   39.66 -    public Symbol getSymbol() {
   39.67 -        return symbol;
   39.68 -    }
   39.69 -
   39.70      @Override
   39.71      protected Object clone() {
   39.72          try {
   39.73 @@ -254,24 +217,6 @@
   39.74          }
   39.75      }
   39.76  
   39.77 -    /**
   39.78 -     * Assign a symbol to this node. See {@link Node#getSymbol()} for explanation
   39.79 -     * of what a symbol is
   39.80 -     *
   39.81 -     * @param lc lexical context
   39.82 -     * @param symbol the symbol
   39.83 -     * @return new node
   39.84 -     */
   39.85 -    public Node setSymbol(final LexicalContext lc, final Symbol symbol) {
   39.86 -        if (this.symbol == symbol) {
   39.87 -            return this;
   39.88 -        }
   39.89 -        final Node newNode = (Node)clone();
   39.90 -        newNode.symbol = symbol;
   39.91 -        return newNode;
   39.92 -    }
   39.93 -
   39.94 -
   39.95      @Override
   39.96      public final boolean equals(final Object other) {
   39.97          return super.equals(other);
    40.1 --- a/src/jdk/nashorn/internal/ir/ObjectNode.java	Thu Jul 11 18:23:13 2013 +0530
    40.2 +++ b/src/jdk/nashorn/internal/ir/ObjectNode.java	Thu Jul 11 18:33:33 2013 +0200
    40.3 @@ -34,7 +34,7 @@
    40.4   * IR representation of an object literal.
    40.5   */
    40.6  @Immutable
    40.7 -public final class ObjectNode extends Node {
    40.8 +public final class ObjectNode extends Expression {
    40.9  
   40.10      /** Literal elements. */
   40.11      private final List<PropertyNode> elements;
    41.1 --- a/src/jdk/nashorn/internal/ir/PropertyNode.java	Thu Jul 11 18:23:13 2013 +0530
    41.2 +++ b/src/jdk/nashorn/internal/ir/PropertyNode.java	Thu Jul 11 18:33:33 2013 +0200
    41.3 @@ -38,7 +38,7 @@
    41.4      private final PropertyKey key;
    41.5  
    41.6      /** Property value. */
    41.7 -    private final Node value;
    41.8 +    private final Expression value;
    41.9  
   41.10      /** Property getter. */
   41.11      private final FunctionNode getter;
   41.12 @@ -56,7 +56,7 @@
   41.13       * @param getter  getter function body
   41.14       * @param setter  setter function body
   41.15       */
   41.16 -    public PropertyNode(final long token, final int finish, final PropertyKey key, final Node value, final FunctionNode getter, final FunctionNode setter) {
   41.17 +    public PropertyNode(final long token, final int finish, final PropertyKey key, final Expression value, final FunctionNode getter, final FunctionNode setter) {
   41.18          super(token, finish);
   41.19          this.key    = key;
   41.20          this.value  = value;
   41.21 @@ -64,7 +64,7 @@
   41.22          this.setter = setter;
   41.23      }
   41.24  
   41.25 -    private PropertyNode(final PropertyNode propertyNode, final PropertyKey key, final Node value, final FunctionNode getter, final FunctionNode setter) {
   41.26 +    private PropertyNode(final PropertyNode propertyNode, final PropertyKey key, final Expression value, final FunctionNode getter, final FunctionNode setter) {
   41.27          super(propertyNode);
   41.28          this.key    = key;
   41.29          this.value  = value;
   41.30 @@ -85,7 +85,7 @@
   41.31          if (visitor.enterPropertyNode(this)) {
   41.32              return visitor.leavePropertyNode(
   41.33                  setKey((PropertyKey)((Node)key).accept(visitor)).
   41.34 -                setValue(value == null ? null : value.accept(visitor)).
   41.35 +                setValue(value == null ? null : (Expression)value.accept(visitor)).
   41.36                  setGetter(getter == null ? null : (FunctionNode)getter.accept(visitor)).
   41.37                  setSetter(setter == null ? null : (FunctionNode)setter.accept(visitor)));
   41.38          }
   41.39 @@ -140,8 +140,8 @@
   41.40       * Return the key for this property node
   41.41       * @return the key
   41.42       */
   41.43 -    public Node getKey() {
   41.44 -        return (Node)key;
   41.45 +    public Expression getKey() {
   41.46 +        return (Expression)key;
   41.47      }
   41.48  
   41.49      private PropertyNode setKey(final PropertyKey key) {
   41.50 @@ -175,7 +175,7 @@
   41.51       * Get the value of this property
   41.52       * @return property value
   41.53       */
   41.54 -    public Node getValue() {
   41.55 +    public Expression getValue() {
   41.56          return value;
   41.57      }
   41.58  
   41.59 @@ -184,7 +184,7 @@
   41.60       * @param value new value
   41.61       * @return same node or new node if state changed
   41.62       */
   41.63 -    public PropertyNode setValue(final Node value) {
   41.64 +    public PropertyNode setValue(final Expression value) {
   41.65          if (this.value == value) {
   41.66              return this;
   41.67          }
    42.1 --- a/src/jdk/nashorn/internal/ir/ReturnNode.java	Thu Jul 11 18:23:13 2013 +0530
    42.2 +++ b/src/jdk/nashorn/internal/ir/ReturnNode.java	Thu Jul 11 18:33:33 2013 +0200
    42.3 @@ -27,6 +27,7 @@
    42.4  
    42.5  import static jdk.nashorn.internal.parser.TokenType.RETURN;
    42.6  import static jdk.nashorn.internal.parser.TokenType.YIELD;
    42.7 +
    42.8  import jdk.nashorn.internal.ir.annotations.Immutable;
    42.9  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   42.10  
   42.11 @@ -36,7 +37,7 @@
   42.12  @Immutable
   42.13  public class ReturnNode extends Statement {
   42.14      /** Optional expression. */
   42.15 -    private final Node expression;
   42.16 +    private final Expression expression;
   42.17  
   42.18      /**
   42.19       * Constructor
   42.20 @@ -46,12 +47,12 @@
   42.21       * @param finish     finish
   42.22       * @param expression expression to return
   42.23       */
   42.24 -    public ReturnNode(final int lineNumber, final long token, final int finish, final Node expression) {
   42.25 +    public ReturnNode(final int lineNumber, final long token, final int finish, final Expression expression) {
   42.26          super(lineNumber, token, finish);
   42.27          this.expression = expression;
   42.28      }
   42.29  
   42.30 -    private ReturnNode(final ReturnNode returnNode, final Node expression) {
   42.31 +    private ReturnNode(final ReturnNode returnNode, final Expression expression) {
   42.32          super(returnNode);
   42.33          this.expression = expression;
   42.34      }
   42.35 @@ -89,7 +90,7 @@
   42.36      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   42.37          if (visitor.enterReturnNode(this)) {
   42.38              if (expression != null) {
   42.39 -                return visitor.leaveReturnNode(setExpression(expression.accept(visitor)));
   42.40 +                return visitor.leaveReturnNode(setExpression((Expression)expression.accept(visitor)));
   42.41              }
   42.42              return visitor.leaveReturnNode(this);
   42.43          }
   42.44 @@ -111,7 +112,7 @@
   42.45       * Get the expression this node returns
   42.46       * @return return expression, or null if void return
   42.47       */
   42.48 -    public Node getExpression() {
   42.49 +    public Expression getExpression() {
   42.50          return expression;
   42.51      }
   42.52  
   42.53 @@ -120,7 +121,7 @@
   42.54       * @param expression new expression, or null if void return
   42.55       * @return new or same return node
   42.56       */
   42.57 -    public ReturnNode setExpression(final Node expression) {
   42.58 +    public ReturnNode setExpression(final Expression expression) {
   42.59          if (this.expression == expression) {
   42.60              return this;
   42.61          }
    43.1 --- a/src/jdk/nashorn/internal/ir/RuntimeNode.java	Thu Jul 11 18:23:13 2013 +0530
    43.2 +++ b/src/jdk/nashorn/internal/ir/RuntimeNode.java	Thu Jul 11 18:33:33 2013 +0200
    43.3 @@ -29,7 +29,6 @@
    43.4  import java.util.Arrays;
    43.5  import java.util.Collections;
    43.6  import java.util.List;
    43.7 -
    43.8  import jdk.nashorn.internal.codegen.types.Type;
    43.9  import jdk.nashorn.internal.ir.annotations.Immutable;
   43.10  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   43.11 @@ -39,7 +38,7 @@
   43.12   * IR representation for a runtime call.
   43.13   */
   43.14  @Immutable
   43.15 -public class RuntimeNode extends Node implements TypeOverride<RuntimeNode> {
   43.16 +public class RuntimeNode extends Expression implements TypeOverride<RuntimeNode> {
   43.17  
   43.18      /**
   43.19       * Request enum used for meta-information about the runtime request
   43.20 @@ -267,7 +266,7 @@
   43.21      private final Request request;
   43.22  
   43.23      /** Call arguments. */
   43.24 -    private final List<Node> args;
   43.25 +    private final List<Expression> args;
   43.26  
   43.27      /** Call site override - e.g. we know that a ScriptRuntime.ADD will return an int */
   43.28      private final Type callSiteType;
   43.29 @@ -283,7 +282,7 @@
   43.30       * @param request the request
   43.31       * @param args    arguments to request
   43.32       */
   43.33 -    public RuntimeNode(final long token, final int finish, final Request request, final List<Node> args) {
   43.34 +    public RuntimeNode(final long token, final int finish, final Request request, final List<Expression> args) {
   43.35          super(token, finish);
   43.36  
   43.37          this.request      = request;
   43.38 @@ -292,7 +291,7 @@
   43.39          this.isFinal      = false;
   43.40      }
   43.41  
   43.42 -    private RuntimeNode(final RuntimeNode runtimeNode, final Request request, final Type callSiteType, final boolean isFinal, final List<Node> args) {
   43.43 +    private RuntimeNode(final RuntimeNode runtimeNode, final Request request, final Type callSiteType, final boolean isFinal, final List<Expression> args) {
   43.44          super(runtimeNode);
   43.45  
   43.46          this.request      = request;
   43.47 @@ -309,7 +308,7 @@
   43.48       * @param request the request
   43.49       * @param args    arguments to request
   43.50       */
   43.51 -    public RuntimeNode(final long token, final int finish, final Request request, final Node... args) {
   43.52 +    public RuntimeNode(final long token, final int finish, final Request request, final Expression... args) {
   43.53          this(token, finish, request, Arrays.asList(args));
   43.54      }
   43.55  
   43.56 @@ -320,7 +319,7 @@
   43.57       * @param request the request
   43.58       * @param args    arguments to request
   43.59       */
   43.60 -    public RuntimeNode(final Node parent, final Request request, final Node... args) {
   43.61 +    public RuntimeNode(final Expression parent, final Request request, final Expression... args) {
   43.62          this(parent, request, Arrays.asList(args));
   43.63      }
   43.64  
   43.65 @@ -331,7 +330,7 @@
   43.66       * @param request the request
   43.67       * @param args    arguments to request
   43.68       */
   43.69 -    public RuntimeNode(final Node parent, final Request request, final List<Node> args) {
   43.70 +    public RuntimeNode(final Expression parent, final Request request, final List<Expression> args) {
   43.71          super(parent);
   43.72  
   43.73          this.request      = request;
   43.74 @@ -408,9 +407,9 @@
   43.75      @Override
   43.76      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   43.77          if (visitor.enterRuntimeNode(this)) {
   43.78 -            final List<Node> newArgs = new ArrayList<>();
   43.79 +            final List<Expression> newArgs = new ArrayList<>();
   43.80              for (final Node arg : args) {
   43.81 -                newArgs.add(arg.accept(visitor));
   43.82 +                newArgs.add((Expression)arg.accept(visitor));
   43.83              }
   43.84              return visitor.leaveRuntimeNode(setArgs(newArgs));
   43.85          }
   43.86 @@ -443,11 +442,11 @@
   43.87       * Get the arguments for this runtime node
   43.88       * @return argument list
   43.89       */
   43.90 -    public List<Node> getArgs() {
   43.91 +    public List<Expression> getArgs() {
   43.92          return Collections.unmodifiableList(args);
   43.93      }
   43.94  
   43.95 -    private RuntimeNode setArgs(final List<Node> args) {
   43.96 +    private RuntimeNode setArgs(final List<Expression> args) {
   43.97          if (this.args == args) {
   43.98              return this;
   43.99          }
  43.100 @@ -470,7 +469,7 @@
  43.101       * @return true if all arguments now are primitive
  43.102       */
  43.103      public boolean isPrimitive() {
  43.104 -        for (final Node arg : args) {
  43.105 +        for (final Expression arg : args) {
  43.106              if (arg.getType().isObject()) {
  43.107                  return false;
  43.108              }
    44.1 --- a/src/jdk/nashorn/internal/ir/SplitNode.java	Thu Jul 11 18:23:13 2013 +0530
    44.2 +++ b/src/jdk/nashorn/internal/ir/SplitNode.java	Thu Jul 11 18:33:33 2013 +0200
    44.3 @@ -33,7 +33,7 @@
    44.4   * Node indicating code is split across classes.
    44.5   */
    44.6  @Immutable
    44.7 -public class SplitNode extends LexicalContextNode {
    44.8 +public class SplitNode extends LexicalContextStatement {
    44.9      /** Split node method name. */
   44.10      private final String name;
   44.11  
   44.12 @@ -46,13 +46,12 @@
   44.13      /**
   44.14       * Constructor
   44.15       *
   44.16 -     * @param lineNumber  lineNumber
   44.17       * @param name        name of split node
   44.18       * @param body        body of split code
   44.19       * @param compileUnit compile unit to use for the body
   44.20       */
   44.21 -    public SplitNode(final int lineNumber, final String name, final Node body, final CompileUnit compileUnit) {
   44.22 -        super(lineNumber, body.getToken(), body.getFinish());
   44.23 +    public SplitNode(final String name, final Node body, final CompileUnit compileUnit) {
   44.24 +        super(-1, body.getToken(), body.getFinish());
   44.25          this.name        = name;
   44.26          this.body        = body;
   44.27          this.compileUnit = compileUnit;
    45.1 --- a/src/jdk/nashorn/internal/ir/SwitchNode.java	Thu Jul 11 18:23:13 2013 +0530
    45.2 +++ b/src/jdk/nashorn/internal/ir/SwitchNode.java	Thu Jul 11 18:33:33 2013 +0200
    45.3 @@ -28,7 +28,6 @@
    45.4  import java.util.ArrayList;
    45.5  import java.util.Collections;
    45.6  import java.util.List;
    45.7 -
    45.8  import jdk.nashorn.internal.codegen.Label;
    45.9  import jdk.nashorn.internal.ir.annotations.Immutable;
   45.10  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   45.11 @@ -37,9 +36,9 @@
   45.12   * IR representation of a SWITCH statement.
   45.13   */
   45.14  @Immutable
   45.15 -public final class SwitchNode extends BreakableNode {
   45.16 +public final class SwitchNode extends BreakableStatement {
   45.17      /** Switch expression. */
   45.18 -    private final Node expression;
   45.19 +    private final Expression expression;
   45.20  
   45.21      /** Switch cases. */
   45.22      private final List<CaseNode> cases;
   45.23 @@ -60,14 +59,14 @@
   45.24       * @param cases       cases
   45.25       * @param defaultCase the default case node - null if none, otherwise has to be present in cases list
   45.26       */
   45.27 -    public SwitchNode(final int lineNumber, final long token, final int finish, final Node expression, final List<CaseNode> cases, final CaseNode defaultCase) {
   45.28 +    public SwitchNode(final int lineNumber, final long token, final int finish, final Expression expression, final List<CaseNode> cases, final CaseNode defaultCase) {
   45.29          super(lineNumber, token, finish, new Label("switch_break"));
   45.30          this.expression       = expression;
   45.31          this.cases            = cases;
   45.32          this.defaultCaseIndex = defaultCase == null ? -1 : cases.indexOf(defaultCase);
   45.33      }
   45.34  
   45.35 -    private SwitchNode(final SwitchNode switchNode, final Node expression, final List<CaseNode> cases, final int defaultCase) {
   45.36 +    private SwitchNode(final SwitchNode switchNode, final Expression expression, final List<CaseNode> cases, final int defaultCase) {
   45.37          super(switchNode);
   45.38          this.expression       = expression;
   45.39          this.cases            = cases;
   45.40 @@ -103,7 +102,7 @@
   45.41      public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
   45.42          if (visitor.enterSwitchNode(this)) {
   45.43              return visitor.leaveSwitchNode(
   45.44 -                setExpression(lc, expression.accept(visitor)).
   45.45 +                setExpression(lc, (Expression)expression.accept(visitor)).
   45.46                  setCases(lc, Node.accept(visitor, CaseNode.class, cases), defaultCaseIndex));
   45.47          }
   45.48  
   45.49 @@ -167,7 +166,7 @@
   45.50       * Return the expression to switch on
   45.51       * @return switch expression
   45.52       */
   45.53 -    public Node getExpression() {
   45.54 +    public Expression getExpression() {
   45.55          return expression;
   45.56      }
   45.57  
   45.58 @@ -177,7 +176,7 @@
   45.59       * @param expression switch expression
   45.60       * @return new switch node or same if no state was changed
   45.61       */
   45.62 -    public SwitchNode setExpression(final LexicalContext lc, final Node expression) {
   45.63 +    public SwitchNode setExpression(final LexicalContext lc, final Expression expression) {
   45.64          if (this.expression == expression) {
   45.65              return this;
   45.66          }
    46.1 --- a/src/jdk/nashorn/internal/ir/TemporarySymbols.java	Thu Jul 11 18:23:13 2013 +0530
    46.2 +++ b/src/jdk/nashorn/internal/ir/TemporarySymbols.java	Thu Jul 11 18:33:33 2013 +0200
    46.3 @@ -49,7 +49,7 @@
    46.4       * @param node the node
    46.5       * @return the node that is guaranteed to have a symbol.
    46.6       */
    46.7 -    public Node ensureSymbol(final LexicalContext lc, final Type type, final Node node) {
    46.8 +    public Expression ensureSymbol(final LexicalContext lc, final Type type, final Expression node) {
    46.9          final Symbol symbol = node.getSymbol();
   46.10          if (symbol != null) {
   46.11              return node;
    47.1 --- a/src/jdk/nashorn/internal/ir/TernaryNode.java	Thu Jul 11 18:23:13 2013 +0530
    47.2 +++ b/src/jdk/nashorn/internal/ir/TernaryNode.java	Thu Jul 11 18:33:33 2013 +0200
    47.3 @@ -32,43 +32,43 @@
    47.4   * TernaryNode nodes represent three operand operations (?:).
    47.5   */
    47.6  @Immutable
    47.7 -public final class TernaryNode extends Node {
    47.8 -    private final Node lhs;
    47.9 +public final class TernaryNode extends Expression {
   47.10 +    private final Expression test;
   47.11  
   47.12 -    private final Node rhs;
   47.13 +    private final Expression trueExpr;
   47.14  
   47.15      /** Third argument. */
   47.16 -    private final Node third;
   47.17 +    private final Expression falseExpr;
   47.18  
   47.19      /**
   47.20       * Constructor
   47.21       *
   47.22 -     * @param token  token
   47.23 -     * @param lhs    left hand side node
   47.24 -     * @param rhs    right hand side node
   47.25 -     * @param third  third node
   47.26 +     * @param token     token
   47.27 +     * @param test      test expression
   47.28 +     * @param trueExpr  expression evaluated when test evaluates to true
   47.29 +     * @param falseExpr expression evaluated when test evaluates to true
   47.30       */
   47.31 -    public TernaryNode(final long token, final Node lhs, final Node rhs, final Node third) {
   47.32 -        super(token, third.getFinish());
   47.33 -        this.lhs = lhs;
   47.34 -        this.rhs = rhs;
   47.35 -        this.third = third;
   47.36 +    public TernaryNode(final long token, final Expression test, final Expression trueExpr, final Expression falseExpr) {
   47.37 +        super(token, falseExpr.getFinish());
   47.38 +        this.test = test;
   47.39 +        this.trueExpr = trueExpr;
   47.40 +        this.falseExpr = falseExpr;
   47.41      }
   47.42  
   47.43 -    private TernaryNode(final TernaryNode ternaryNode, final Node lhs, final Node rhs, final Node third) {
   47.44 +    private TernaryNode(final TernaryNode ternaryNode, final Expression test, final Expression trueExpr, final Expression falseExpr) {
   47.45          super(ternaryNode);
   47.46 -        this.lhs = lhs;
   47.47 -        this.rhs = rhs;
   47.48 -        this.third = third;
   47.49 +        this.test = test;
   47.50 +        this.trueExpr = trueExpr;
   47.51 +        this.falseExpr = falseExpr;
   47.52      }
   47.53  
   47.54      @Override
   47.55      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   47.56          if (visitor.enterTernaryNode(this)) {
   47.57 -            final Node newLhs = lhs().accept(visitor);
   47.58 -            final Node newRhs = rhs().accept(visitor);
   47.59 -            final Node newThird = third.accept(visitor);
   47.60 -            return visitor.leaveTernaryNode(setThird(newThird).setLHS(newLhs).setRHS(newRhs));
   47.61 +            final Expression newTest = (Expression)getTest().accept(visitor);
   47.62 +            final Expression newTrueExpr = (Expression)getTrueExpression().accept(visitor);
   47.63 +            final Expression newFalseExpr = (Expression)falseExpr.accept(visitor);
   47.64 +            return visitor.leaveTernaryNode(setTest(newTest).setTrueExpression(newTrueExpr).setFalseExpression1(newFalseExpr));
   47.65          }
   47.66  
   47.67          return this;
   47.68 @@ -76,96 +76,96 @@
   47.69  
   47.70      @Override
   47.71      public void toString(final StringBuilder sb) {
   47.72 -        final boolean lhsParen   = tokenType().needsParens(lhs().tokenType(), true);
   47.73 -        final boolean rhsParen   = tokenType().needsParens(rhs().tokenType(), false);
   47.74 -        final boolean thirdParen = tokenType().needsParens(third().tokenType(), false);
   47.75 +        final boolean testParen  = tokenType().needsParens(getTest().tokenType(), true);
   47.76 +        final boolean trueParen  = tokenType().needsParens(getTrueExpression().tokenType(), false);
   47.77 +        final boolean falseParen = tokenType().needsParens(getFalseExpression().tokenType(), false);
   47.78  
   47.79 -        if (lhsParen) {
   47.80 +        if (testParen) {
   47.81              sb.append('(');
   47.82          }
   47.83 -        lhs().toString(sb);
   47.84 -        if (lhsParen) {
   47.85 +        getTest().toString(sb);
   47.86 +        if (testParen) {
   47.87              sb.append(')');
   47.88          }
   47.89  
   47.90          sb.append(" ? ");
   47.91  
   47.92 -        if (rhsParen) {
   47.93 +        if (trueParen) {
   47.94              sb.append('(');
   47.95          }
   47.96 -        rhs().toString(sb);
   47.97 -        if (rhsParen) {
   47.98 +        getTrueExpression().toString(sb);
   47.99 +        if (trueParen) {
  47.100              sb.append(')');
  47.101          }
  47.102  
  47.103          sb.append(" : ");
  47.104  
  47.105 -        if (thirdParen) {
  47.106 +        if (falseParen) {
  47.107              sb.append('(');
  47.108          }
  47.109 -        third().toString(sb);
  47.110 -        if (thirdParen) {
  47.111 +        getFalseExpression().toString(sb);
  47.112 +        if (falseParen) {
  47.113              sb.append(')');
  47.114          }
  47.115      }
  47.116  
  47.117      /**
  47.118 -     * Get the lhs node for this ternary expression, i.e. "x" in x ? y : z
  47.119 -     * @return a node
  47.120 +     * Get the test expression for this ternary expression, i.e. "x" in x ? y : z
  47.121 +     * @return the test expression
  47.122       */
  47.123 -    public Node lhs() {
  47.124 -        return lhs;
  47.125 +    public Expression getTest() {
  47.126 +        return test;
  47.127      }
  47.128  
  47.129      /**
  47.130 -     * Get the rhs node for this ternary expression, i.e. "y" in x ? y : z
  47.131 -     * @return a node
  47.132 +     * Get the true expression for this ternary expression, i.e. "y" in x ? y : z
  47.133 +     * @return the true expression
  47.134       */
  47.135 -    public Node rhs() {
  47.136 -        return rhs;
  47.137 +    public Expression getTrueExpression() {
  47.138 +        return trueExpr;
  47.139      }
  47.140  
  47.141      /**
  47.142 -     * Get the "third" node for this ternary expression, i.e. "z" in x ? y : z
  47.143 -     * @return a node
  47.144 +     * Get the false expression for this ternary expression, i.e. "z" in x ? y : z
  47.145 +     * @return the false expression
  47.146       */
  47.147 -    public Node third() {
  47.148 -        return third;
  47.149 +    public Expression getFalseExpression() {
  47.150 +        return falseExpr;
  47.151      }
  47.152  
  47.153      /**
  47.154 -     * Set the left hand side expression for this node
  47.155 -     * @param lhs new left hand side expression
  47.156 +     * Set the test expression for this node
  47.157 +     * @param test new test expression
  47.158       * @return a node equivalent to this one except for the requested change.
  47.159       */
  47.160 -    public TernaryNode setLHS(final Node lhs) {
  47.161 -        if (this.lhs == lhs) {
  47.162 +    public TernaryNode setTest(final Expression test) {
  47.163 +        if (this.test == test) {
  47.164              return this;
  47.165          }
  47.166 -        return new TernaryNode(this, lhs, rhs, third);
  47.167 +        return new TernaryNode(this, test, trueExpr, falseExpr);
  47.168      }
  47.169  
  47.170      /**
  47.171 -     * Set the right hand side expression for this node
  47.172 -     * @param rhs new left hand side expression
  47.173 +     * Set the true expression for this node
  47.174 +     * @param trueExpr new true expression
  47.175       * @return a node equivalent to this one except for the requested change.
  47.176       */
  47.177 -    public TernaryNode setRHS(final Node rhs) {
  47.178 -        if (this.rhs == rhs) {
  47.179 +    public TernaryNode setTrueExpression(final Expression trueExpr) {
  47.180 +        if (this.trueExpr == trueExpr) {
  47.181              return this;
  47.182          }
  47.183 -        return new TernaryNode(this, lhs, rhs, third);
  47.184 +        return new TernaryNode(this, test, trueExpr, falseExpr);
  47.185      }
  47.186  
  47.187      /**
  47.188 -     * Reset the "third" node for this ternary expression, i.e. "z" in x ? y : z
  47.189 -     * @param third a node
  47.190 +     * Set the false expression for this node
  47.191 +     * @param falseExpr new false expression
  47.192       * @return a node equivalent to this one except for the requested change.
  47.193       */
  47.194 -    public TernaryNode setThird(final Node third) {
  47.195 -        if (this.third == third) {
  47.196 +    public TernaryNode setFalseExpression1(final Expression falseExpr) {
  47.197 +        if (this.falseExpr == falseExpr) {
  47.198              return this;
  47.199          }
  47.200 -        return new TernaryNode(this, lhs, rhs, third);
  47.201 +        return new TernaryNode(this, test, trueExpr, falseExpr);
  47.202      }
  47.203  }
    48.1 --- a/src/jdk/nashorn/internal/ir/ThrowNode.java	Thu Jul 11 18:23:13 2013 +0530
    48.2 +++ b/src/jdk/nashorn/internal/ir/ThrowNode.java	Thu Jul 11 18:33:33 2013 +0200
    48.3 @@ -34,7 +34,7 @@
    48.4  @Immutable
    48.5  public final class ThrowNode extends Statement {
    48.6      /** Exception expression. */
    48.7 -    private final Node expression;
    48.8 +    private final Expression expression;
    48.9  
   48.10      private final int flags;
   48.11  
   48.12 @@ -50,13 +50,13 @@
   48.13       * @param expression expression to throw
   48.14       * @param flags      flags
   48.15       */
   48.16 -    public ThrowNode(final int lineNumber, final long token, final int finish, final Node expression, final int flags) {
   48.17 +    public ThrowNode(final int lineNumber, final long token, final int finish, final Expression expression, final int flags) {
   48.18          super(lineNumber, token, finish);
   48.19          this.expression = expression;
   48.20          this.flags = flags;
   48.21      }
   48.22  
   48.23 -    private ThrowNode(final ThrowNode node, final Node expression, final int flags) {
   48.24 +    private ThrowNode(final ThrowNode node, final Expression expression, final int flags) {
   48.25          super(node);
   48.26          this.expression = expression;
   48.27          this.flags = flags;
   48.28 @@ -74,7 +74,7 @@
   48.29      @Override
   48.30      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   48.31          if (visitor.enterThrowNode(this)) {
   48.32 -            return visitor.leaveThrowNode(setExpression(expression.accept(visitor)));
   48.33 +            return visitor.leaveThrowNode(setExpression((Expression)expression.accept(visitor)));
   48.34          }
   48.35  
   48.36          return this;
   48.37 @@ -93,7 +93,7 @@
   48.38       * Get the expression that is being thrown by this node
   48.39       * @return expression
   48.40       */
   48.41 -    public Node getExpression() {
   48.42 +    public Expression getExpression() {
   48.43          return expression;
   48.44      }
   48.45  
   48.46 @@ -102,7 +102,7 @@
   48.47       * @param expression new expression
   48.48       * @return new or same thrownode
   48.49       */
   48.50 -    public ThrowNode setExpression(final Node expression) {
   48.51 +    public ThrowNode setExpression(final Expression expression) {
   48.52          if (this.expression == expression) {
   48.53              return this;
   48.54          }
    49.1 --- a/src/jdk/nashorn/internal/ir/UnaryNode.java	Thu Jul 11 18:23:13 2013 +0530
    49.2 +++ b/src/jdk/nashorn/internal/ir/UnaryNode.java	Thu Jul 11 18:33:33 2013 +0200
    49.3 @@ -29,6 +29,7 @@
    49.4  import static jdk.nashorn.internal.parser.TokenType.CONVERT;
    49.5  import static jdk.nashorn.internal.parser.TokenType.DECPOSTFIX;
    49.6  import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
    49.7 +
    49.8  import jdk.nashorn.internal.codegen.types.Type;
    49.9  import jdk.nashorn.internal.ir.annotations.Immutable;
   49.10  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   49.11 @@ -39,9 +40,9 @@
   49.12   * UnaryNode nodes represent single operand operations.
   49.13   */
   49.14  @Immutable
   49.15 -public final class UnaryNode extends Node implements Assignment<Node> {
   49.16 +public final class UnaryNode extends Expression implements Assignment<Expression> {
   49.17      /** Right hand side argument. */
   49.18 -    private final Node rhs;
   49.19 +    private final Expression rhs;
   49.20  
   49.21      /**
   49.22       * Constructor
   49.23 @@ -49,7 +50,7 @@
   49.24       * @param token  token
   49.25       * @param rhs    expression
   49.26       */
   49.27 -    public UnaryNode(final long token, final Node rhs) {
   49.28 +    public UnaryNode(final long token, final Expression rhs) {
   49.29          this(token, Math.min(rhs.getStart(), Token.descPosition(token)), Math.max(Token.descPosition(token) + Token.descLength(token), rhs.getFinish()), rhs);
   49.30      }
   49.31  
   49.32 @@ -61,13 +62,13 @@
   49.33       * @param finish finish
   49.34       * @param rhs    expression
   49.35       */
   49.36 -    public UnaryNode(final long token, final int start, final int finish, final Node rhs) {
   49.37 +    public UnaryNode(final long token, final int start, final int finish, final Expression rhs) {
   49.38          super(token, start, finish);
   49.39          this.rhs = rhs;
   49.40      }
   49.41  
   49.42  
   49.43 -    private UnaryNode(final UnaryNode unaryNode, final Node rhs) {
   49.44 +    private UnaryNode(final UnaryNode unaryNode, final Expression rhs) {
   49.45          super(unaryNode);
   49.46          this.rhs = rhs;
   49.47      }
   49.48 @@ -101,17 +102,17 @@
   49.49      }
   49.50  
   49.51      @Override
   49.52 -    public Node getAssignmentDest() {
   49.53 +    public Expression getAssignmentDest() {
   49.54          return isAssignment() ? rhs() : null;
   49.55      }
   49.56  
   49.57      @Override
   49.58 -    public Node setAssignmentDest(Node n) {
   49.59 +    public UnaryNode setAssignmentDest(Expression n) {
   49.60          return setRHS(n);
   49.61      }
   49.62  
   49.63      @Override
   49.64 -    public Node getAssignmentSource() {
   49.65 +    public Expression getAssignmentSource() {
   49.66          return getAssignmentDest();
   49.67      }
   49.68  
   49.69 @@ -122,7 +123,7 @@
   49.70      @Override
   49.71      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   49.72          if (visitor.enterUnaryNode(this)) {
   49.73 -            return visitor.leaveUnaryNode(setRHS(rhs.accept(visitor)));
   49.74 +            return visitor.leaveUnaryNode(setRHS((Expression)rhs.accept(visitor)));
   49.75          }
   49.76  
   49.77          return this;
   49.78 @@ -189,7 +190,7 @@
   49.79       *
   49.80       * @return right hand side or expression node
   49.81       */
   49.82 -    public Node rhs() {
   49.83 +    public Expression rhs() {
   49.84          return rhs;
   49.85      }
   49.86  
   49.87 @@ -202,7 +203,7 @@
   49.88       * @param rhs right hand side or expression node
   49.89       * @return a node equivalent to this one except for the requested change.
   49.90       */
   49.91 -    public UnaryNode setRHS(final Node rhs) {
   49.92 +    public UnaryNode setRHS(final Expression rhs) {
   49.93          if (this.rhs == rhs) {
   49.94              return this;
   49.95          }
    50.1 --- a/src/jdk/nashorn/internal/ir/VarNode.java	Thu Jul 11 18:23:13 2013 +0530
    50.2 +++ b/src/jdk/nashorn/internal/ir/VarNode.java	Thu Jul 11 18:33:33 2013 +0200
    50.3 @@ -37,7 +37,7 @@
    50.4      private final IdentNode name;
    50.5  
    50.6      /** Initialization expression. */
    50.7 -    private final Node init;
    50.8 +    private final Expression init;
    50.9  
   50.10      /** Is this a var statement (as opposed to a "var" in a for loop statement) */
   50.11      private final int flags;
   50.12 @@ -59,11 +59,11 @@
   50.13       * @param name       name of variable
   50.14       * @param init       init node or null if just a declaration
   50.15       */
   50.16 -    public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Node init) {
   50.17 +    public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Expression init) {
   50.18          this(lineNumber, token, finish, name, init, IS_STATEMENT);
   50.19      }
   50.20  
   50.21 -    private VarNode(final VarNode varNode, final IdentNode name, final Node init, final int flags) {
   50.22 +    private VarNode(final VarNode varNode, final IdentNode name, final Expression init, final int flags) {
   50.23          super(varNode);
   50.24          this.name = init == null ? name : name.setIsInitializedHere();
   50.25          this.init = init;
   50.26 @@ -80,7 +80,7 @@
   50.27       * @param init       init node or null if just a declaration
   50.28       * @param flags      flags
   50.29       */
   50.30 -    public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Node init, final int flags) {
   50.31 +    public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Expression init, final int flags) {
   50.32          super(lineNumber, token, finish);
   50.33  
   50.34          this.name  = init == null ? name : name.setIsInitializedHere();
   50.35 @@ -99,12 +99,12 @@
   50.36      }
   50.37  
   50.38      @Override
   50.39 -    public Node setAssignmentDest(IdentNode n) {
   50.40 +    public VarNode setAssignmentDest(IdentNode n) {
   50.41          return setName(n);
   50.42      }
   50.43  
   50.44      @Override
   50.45 -    public Node getAssignmentSource() {
   50.46 +    public Expression getAssignmentSource() {
   50.47          return isAssignment() ? getInit() : null;
   50.48      }
   50.49  
   50.50 @@ -123,9 +123,9 @@
   50.51      @Override
   50.52      public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
   50.53          if (visitor.enterVarNode(this)) {
   50.54 -            final IdentNode newName = (IdentNode)name.accept(visitor);
   50.55 -            final Node      newInit = init == null ? null : init.accept(visitor);
   50.56 -            final VarNode   newThis;
   50.57 +            final IdentNode  newName = (IdentNode)name.accept(visitor);
   50.58 +            final Expression newInit = init == null ? null : (Expression)init.accept(visitor);
   50.59 +            final VarNode    newThis;
   50.60              if (name != newName || init != newInit) {
   50.61                  newThis = new VarNode(this, newName, newInit, flags);
   50.62              } else {
   50.63 @@ -151,7 +151,7 @@
   50.64       * If this is an assignment of the form {@code var x = init;}, get the init part.
   50.65       * @return the expression to initialize the variable to, null if just a declaration
   50.66       */
   50.67 -    public Node getInit() {
   50.68 +    public Expression getInit() {
   50.69          return init;
   50.70      }
   50.71  
   50.72 @@ -160,7 +160,7 @@
   50.73       * @param init new initialization expression
   50.74       * @return a node equivalent to this one except for the requested change.
   50.75       */
   50.76 -    public VarNode setInit(final Node init) {
   50.77 +    public VarNode setInit(final Expression init) {
   50.78          if (this.init == init) {
   50.79              return this;
   50.80          }
    51.1 --- a/src/jdk/nashorn/internal/ir/WhileNode.java	Thu Jul 11 18:23:13 2013 +0530
    51.2 +++ b/src/jdk/nashorn/internal/ir/WhileNode.java	Thu Jul 11 18:33:33 2013 +0200
    51.3 @@ -59,7 +59,7 @@
    51.4       * @param body      body
    51.5       * @param controlFlowEscapes control flow escapes?
    51.6       */
    51.7 -    protected WhileNode(final WhileNode whileNode, final Node test, final Block body, final boolean controlFlowEscapes) {
    51.8 +    protected WhileNode(final WhileNode whileNode, final Expression test, final Block body, final boolean controlFlowEscapes) {
    51.9          super(whileNode, test, body, controlFlowEscapes);
   51.10          this.isDoWhile = whileNode.isDoWhile;
   51.11      }
   51.12 @@ -75,28 +75,28 @@
   51.13      }
   51.14  
   51.15      @Override
   51.16 -    protected Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
   51.17 +    public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
   51.18          if (visitor.enterWhileNode(this)) {
   51.19              if (isDoWhile()) {
   51.20                  return visitor.leaveWhileNode(
   51.21 -                        setTest(lc, test.accept(visitor)).
   51.22 +                        setTest(lc, (Expression)test.accept(visitor)).
   51.23                          setBody(lc, (Block)body.accept(visitor)));
   51.24              }
   51.25              return visitor.leaveWhileNode(
   51.26                      setBody(lc, (Block)body.accept(visitor)).
   51.27 -                    setTest(lc, test.accept(visitor)));
   51.28 +                    setTest(lc, (Expression)test.accept(visitor)));
   51.29  
   51.30          }
   51.31          return this;
   51.32      }
   51.33  
   51.34      @Override
   51.35 -    public Node getTest() {
   51.36 +    public Expression getTest() {
   51.37          return test;
   51.38      }
   51.39  
   51.40      @Override
   51.41 -    public WhileNode setTest(final LexicalContext lc, final Node test) {
   51.42 +    public WhileNode setTest(final LexicalContext lc, final Expression test) {
   51.43          if (this.test == test) {
   51.44              return this;
   51.45          }
    52.1 --- a/src/jdk/nashorn/internal/ir/WithNode.java	Thu Jul 11 18:23:13 2013 +0530
    52.2 +++ b/src/jdk/nashorn/internal/ir/WithNode.java	Thu Jul 11 18:33:33 2013 +0200
    52.3 @@ -32,9 +32,9 @@
    52.4   * IR representation for {@code with} statements.
    52.5   */
    52.6  @Immutable
    52.7 -public final class WithNode extends LexicalContextNode {
    52.8 +public final class WithNode extends LexicalContextStatement {
    52.9     /** This expression. */
   52.10 -    private final Node expression;
   52.11 +    private final Expression expression;
   52.12  
   52.13      /** Statements. */
   52.14      private final Block body;
   52.15 @@ -52,7 +52,7 @@
   52.16          this.body       = null;
   52.17      }
   52.18  
   52.19 -    private WithNode(final WithNode node, final Node expression, final Block body) {
   52.20 +    private WithNode(final WithNode node, final Expression expression, final Block body) {
   52.21          super(node);
   52.22          this.expression = expression;
   52.23          this.body       = body;
   52.24 @@ -67,7 +67,7 @@
   52.25      public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
   52.26          if (visitor.enterWithNode(this)) {
   52.27               return visitor.leaveWithNode(
   52.28 -                setExpression(lc, expression.accept(visitor)).
   52.29 +                setExpression(lc, (Expression)expression.accept(visitor)).
   52.30                  setBody(lc, (Block)body.accept(visitor)));
   52.31          }
   52.32          return this;
   52.33 @@ -110,7 +110,7 @@
   52.34       * Get the expression of this WithNode
   52.35       * @return the expression
   52.36       */
   52.37 -    public Node getExpression() {
   52.38 +    public Expression getExpression() {
   52.39          return expression;
   52.40      }
   52.41  
   52.42 @@ -120,7 +120,7 @@
   52.43       * @param expression new expression
   52.44       * @return new or same withnode
   52.45       */
   52.46 -    public WithNode setExpression(final LexicalContext lc, final Node expression) {
   52.47 +    public WithNode setExpression(final LexicalContext lc, final Expression expression) {
   52.48          if (this.expression == expression) {
   52.49              return this;
   52.50          }
    53.1 --- a/src/jdk/nashorn/internal/ir/debug/ASTWriter.java	Thu Jul 11 18:23:13 2013 +0530
    53.2 +++ b/src/jdk/nashorn/internal/ir/debug/ASTWriter.java	Thu Jul 11 18:33:33 2013 +0200
    53.3 @@ -33,10 +33,11 @@
    53.4  import java.util.Iterator;
    53.5  import java.util.LinkedList;
    53.6  import java.util.List;
    53.7 -
    53.8  import jdk.nashorn.internal.ir.BinaryNode;
    53.9  import jdk.nashorn.internal.ir.Block;
   53.10 +import jdk.nashorn.internal.ir.Expression;
   53.11  import jdk.nashorn.internal.ir.Node;
   53.12 +import jdk.nashorn.internal.ir.Symbol;
   53.13  import jdk.nashorn.internal.ir.TernaryNode;
   53.14  import jdk.nashorn.internal.ir.annotations.Ignore;
   53.15  import jdk.nashorn.internal.ir.annotations.Reference;
   53.16 @@ -111,8 +112,15 @@
   53.17              type = "ref: " + type;
   53.18          }
   53.19          type += "@" + Debug.id(node);
   53.20 -        if (node.getSymbol() != null) {
   53.21 -            type += "#" + node.getSymbol();
   53.22 +        final Symbol symbol;
   53.23 +        if(node instanceof Expression) {
   53.24 +            symbol = ((Expression)node).getSymbol();
   53.25 +        } else {
   53.26 +            symbol = null;
   53.27 +        }
   53.28 +
   53.29 +        if (symbol != null) {
   53.30 +            type += "#" + symbol;
   53.31          }
   53.32  
   53.33          if (node instanceof Block && ((Block)node).needsScope()) {
   53.34 @@ -135,8 +143,8 @@
   53.35              status += " Goto ";
   53.36          }
   53.37  
   53.38 -        if (node.getSymbol() != null) {
   53.39 -            status += node.getSymbol();
   53.40 +        if (symbol != null) {
   53.41 +            status += symbol;
   53.42          }
   53.43  
   53.44          status = status.trim();
   53.45 @@ -144,8 +152,8 @@
   53.46              status = " [" + status + "]";
   53.47          }
   53.48  
   53.49 -        if (node.getSymbol() != null) {
   53.50 -            String tname = node.getType().toString();
   53.51 +        if (symbol != null) {
   53.52 +            String tname = ((Expression)node).getType().toString();
   53.53              if (tname.indexOf('.') != -1) {
   53.54                  tname = tname.substring(tname.lastIndexOf('.') + 1, tname.length());
   53.55              }
    54.1 --- a/src/jdk/nashorn/internal/ir/debug/JSONWriter.java	Thu Jul 11 18:23:13 2013 +0530
    54.2 +++ b/src/jdk/nashorn/internal/ir/debug/JSONWriter.java	Thu Jul 11 18:33:33 2013 +0200
    54.3 @@ -27,18 +27,18 @@
    54.4  
    54.5  import java.util.Arrays;
    54.6  import java.util.List;
    54.7 -
    54.8  import jdk.nashorn.internal.codegen.CompilerConstants;
    54.9  import jdk.nashorn.internal.ir.AccessNode;
   54.10  import jdk.nashorn.internal.ir.BinaryNode;
   54.11  import jdk.nashorn.internal.ir.Block;
   54.12 +import jdk.nashorn.internal.ir.BlockStatement;
   54.13  import jdk.nashorn.internal.ir.BreakNode;
   54.14  import jdk.nashorn.internal.ir.CallNode;
   54.15  import jdk.nashorn.internal.ir.CaseNode;
   54.16  import jdk.nashorn.internal.ir.CatchNode;
   54.17  import jdk.nashorn.internal.ir.ContinueNode;
   54.18  import jdk.nashorn.internal.ir.EmptyNode;
   54.19 -import jdk.nashorn.internal.ir.ExecuteNode;
   54.20 +import jdk.nashorn.internal.ir.ExpressionStatement;
   54.21  import jdk.nashorn.internal.ir.ForNode;
   54.22  import jdk.nashorn.internal.ir.FunctionNode;
   54.23  import jdk.nashorn.internal.ir.IdentNode;
   54.24 @@ -298,14 +298,27 @@
   54.25      }
   54.26  
   54.27      @Override
   54.28 -    public boolean enterExecuteNode(final ExecuteNode executeNode) {
   54.29 -        enterDefault(executeNode);
   54.30 +    public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
   54.31 +        enterDefault(expressionStatement);
   54.32  
   54.33          type("ExpressionStatement");
   54.34          comma();
   54.35  
   54.36          property("expression");
   54.37 -        executeNode.getExpression().accept(this);
   54.38 +        expressionStatement.getExpression().accept(this);
   54.39 +
   54.40 +        return leave();
   54.41 +    }
   54.42 +
   54.43 +    @Override
   54.44 +    public boolean enterBlockStatement(BlockStatement blockStatement) {
   54.45 +        enterDefault(blockStatement);
   54.46 +
   54.47 +        type("BlockStatement");
   54.48 +        comma();
   54.49 +
   54.50 +        property("block");
   54.51 +        blockStatement.getBlock().accept(this);
   54.52  
   54.53          return leave();
   54.54      }
   54.55 @@ -680,15 +693,15 @@
   54.56          comma();
   54.57  
   54.58          property("test");
   54.59 -        ternaryNode.lhs().accept(this);
   54.60 +        ternaryNode.getTest().accept(this);
   54.61          comma();
   54.62  
   54.63          property("consequent");
   54.64 -        ternaryNode.rhs().accept(this);
   54.65 +        ternaryNode.getTrueExpression().accept(this);
   54.66          comma();
   54.67  
   54.68          property("alternate");
   54.69 -        ternaryNode.third().accept(this);
   54.70 +        ternaryNode.getFalseExpression().accept(this);
   54.71  
   54.72          return leave();
   54.73      }
    55.1 --- a/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java	Thu Jul 11 18:23:13 2013 +0530
    55.2 +++ b/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java	Thu Jul 11 18:33:33 2013 +0200
    55.3 @@ -26,12 +26,11 @@
    55.4  package jdk.nashorn.internal.ir.debug;
    55.5  
    55.6  import java.util.List;
    55.7 -
    55.8  import jdk.nashorn.internal.ir.BinaryNode;
    55.9  import jdk.nashorn.internal.ir.Block;
   55.10  import jdk.nashorn.internal.ir.CaseNode;
   55.11  import jdk.nashorn.internal.ir.CatchNode;
   55.12 -import jdk.nashorn.internal.ir.ExecuteNode;
   55.13 +import jdk.nashorn.internal.ir.ExpressionStatement;
   55.14  import jdk.nashorn.internal.ir.ForNode;
   55.15  import jdk.nashorn.internal.ir.FunctionNode;
   55.16  import jdk.nashorn.internal.ir.IfNode;
   55.17 @@ -41,7 +40,6 @@
   55.18  import jdk.nashorn.internal.ir.SplitNode;
   55.19  import jdk.nashorn.internal.ir.Statement;
   55.20  import jdk.nashorn.internal.ir.SwitchNode;
   55.21 -import jdk.nashorn.internal.ir.Symbol;
   55.22  import jdk.nashorn.internal.ir.TryNode;
   55.23  import jdk.nashorn.internal.ir.VarNode;
   55.24  import jdk.nashorn.internal.ir.WhileNode;
   55.25 @@ -167,14 +165,6 @@
   55.26                  continue;
   55.27              }
   55.28  
   55.29 -            final Symbol symbol = statement.getSymbol();
   55.30 -
   55.31 -            if (symbol != null) {
   55.32 -                sb.append("  [");
   55.33 -                sb.append(symbol.toString());
   55.34 -                sb.append(']');
   55.35 -            }
   55.36 -
   55.37              int  lastIndex = sb.length() - 1;
   55.38              char lastChar  = sb.charAt(lastIndex);
   55.39              while (Character.isWhitespace(lastChar) && lastIndex >= 0) {
   55.40 @@ -215,8 +205,8 @@
   55.41      }
   55.42  
   55.43      @Override
   55.44 -    public boolean enterExecuteNode(final ExecuteNode executeNode) {
   55.45 -        executeNode.getExpression().accept(this);
   55.46 +    public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
   55.47 +        expressionStatement.getExpression().accept(this);
   55.48          return false;
   55.49      }
   55.50  
    56.1 --- a/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java	Thu Jul 11 18:23:13 2013 +0530
    56.2 +++ b/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java	Thu Jul 11 18:33:33 2013 +0200
    56.3 @@ -1263,6 +1263,4 @@
    56.4      public Node leaveSUB(final BinaryNode binaryNode) {
    56.5          return leaveDefault(binaryNode);
    56.6      }
    56.7 -
    56.8 -
    56.9  }
    57.1 --- a/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java	Thu Jul 11 18:23:13 2013 +0530
    57.2 +++ b/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java	Thu Jul 11 18:33:33 2013 +0200
    57.3 @@ -28,13 +28,14 @@
    57.4  import jdk.nashorn.internal.ir.AccessNode;
    57.5  import jdk.nashorn.internal.ir.BinaryNode;
    57.6  import jdk.nashorn.internal.ir.Block;
    57.7 +import jdk.nashorn.internal.ir.BlockStatement;
    57.8  import jdk.nashorn.internal.ir.BreakNode;
    57.9  import jdk.nashorn.internal.ir.CallNode;
   57.10  import jdk.nashorn.internal.ir.CaseNode;
   57.11  import jdk.nashorn.internal.ir.CatchNode;
   57.12  import jdk.nashorn.internal.ir.ContinueNode;
   57.13  import jdk.nashorn.internal.ir.EmptyNode;
   57.14 -import jdk.nashorn.internal.ir.ExecuteNode;
   57.15 +import jdk.nashorn.internal.ir.ExpressionStatement;
   57.16  import jdk.nashorn.internal.ir.ForNode;
   57.17  import jdk.nashorn.internal.ir.FunctionNode;
   57.18  import jdk.nashorn.internal.ir.IdentNode;
   57.19 @@ -308,23 +309,43 @@
   57.20      }
   57.21  
   57.22      /**
   57.23 -     * Callback for entering an ExecuteNode
   57.24 +     * Callback for entering an ExpressionStatement
   57.25       *
   57.26 -     * @param  executeNode the node
   57.27 +     * @param  expressionStatement the node
   57.28       * @return true if traversal should continue and node children be traversed, false otherwise
   57.29       */
   57.30 -    public boolean enterExecuteNode(final ExecuteNode executeNode) {
   57.31 -        return enterDefault(executeNode);
   57.32 +    public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) {
   57.33 +        return enterDefault(expressionStatement);
   57.34      }
   57.35  
   57.36      /**
   57.37 -     * Callback for leaving an ExecuteNode
   57.38 +     * Callback for leaving an ExpressionStatement
   57.39       *
   57.40 -     * @param  executeNode the node
   57.41 +     * @param  expressionStatement the node
   57.42       * @return processed node, which will replace the original one, or the original node
   57.43       */
   57.44 -    public Node leaveExecuteNode(final ExecuteNode executeNode) {
   57.45 -        return leaveDefault(executeNode);
   57.46 +    public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) {
   57.47 +        return leaveDefault(expressionStatement);
   57.48 +    }
   57.49 +
   57.50 +    /**
   57.51 +     * Callback for entering a BlockStatement
   57.52 +     *
   57.53 +     * @param  blockStatement the node
   57.54 +     * @return true if traversal should continue and node children be traversed, false otherwise
   57.55 +     */
   57.56 +    public boolean enterBlockStatement(final BlockStatement blockStatement) {
   57.57 +        return enterDefault(blockStatement);
   57.58 +    }
   57.59 +
   57.60 +    /**
   57.61 +     * Callback for leaving a BlockStatement
   57.62 +     *
   57.63 +     * @param  blockStatement the node
   57.64 +     * @return processed node, which will replace the original one, or the original node
   57.65 +     */
   57.66 +    public Node leaveBlockStatement(final BlockStatement blockStatement) {
   57.67 +        return leaveDefault(blockStatement);
   57.68      }
   57.69  
   57.70      /**
    58.1 --- a/src/jdk/nashorn/internal/parser/JSONParser.java	Thu Jul 11 18:23:13 2013 +0530
    58.2 +++ b/src/jdk/nashorn/internal/parser/JSONParser.java	Thu Jul 11 18:33:33 2013 +0200
    58.3 @@ -35,6 +35,7 @@
    58.4  
    58.5  import java.util.ArrayList;
    58.6  import java.util.List;
    58.7 +import jdk.nashorn.internal.ir.Expression;
    58.8  import jdk.nashorn.internal.ir.LiteralNode;
    58.9  import jdk.nashorn.internal.ir.Node;
   58.10  import jdk.nashorn.internal.ir.ObjectNode;
   58.11 @@ -274,7 +275,7 @@
   58.12       * Parse a JSON literal from the token stream
   58.13       * @return the JSON literal as a Node
   58.14       */
   58.15 -    private Node jsonLiteral() {
   58.16 +    private Expression jsonLiteral() {
   58.17          final long literalToken = token;
   58.18  
   58.19          switch (type) {
   58.20 @@ -326,7 +327,7 @@
   58.21       * Parse an array literal from the token stream
   58.22       * @return the array literal as a Node
   58.23       */
   58.24 -    private Node arrayLiteral() {
   58.25 +    private LiteralNode<Expression[]> arrayLiteral() {
   58.26          // Unlike JavaScript array literals, elison is not permitted in JSON.
   58.27  
   58.28          // Capture LBRACKET token.
   58.29 @@ -334,9 +335,9 @@
   58.30          // LBRACKET tested in caller.
   58.31          next();
   58.32  
   58.33 -        Node result = null;
   58.34 +        LiteralNode<Expression[]> result = null;
   58.35          // Prepare to accummulating elements.
   58.36 -        final List<Node> elements = new ArrayList<>();
   58.37 +        final List<Expression> elements = new ArrayList<>();
   58.38  
   58.39  loop:
   58.40          while (true) {
   58.41 @@ -368,7 +369,7 @@
   58.42       * Parse an object literal from the token stream
   58.43       * @return the object literal as a Node
   58.44       */
   58.45 -    private Node objectLiteral() {
   58.46 +    private ObjectNode objectLiteral() {
   58.47          // Capture LBRACE token.
   58.48          final long objectToken = token;
   58.49          // LBRACE tested in caller.
   58.50 @@ -423,7 +424,7 @@
   58.51  
   58.52          if (name != null) {
   58.53              expect(COLON);
   58.54 -            final Node value = jsonLiteral();
   58.55 +            final Expression value = jsonLiteral();
   58.56              return new PropertyNode(propertyToken, value.getFinish(), name, value, null, null);
   58.57          }
   58.58  
    59.1 --- a/src/jdk/nashorn/internal/parser/Parser.java	Thu Jul 11 18:23:13 2013 +0530
    59.2 +++ b/src/jdk/nashorn/internal/parser/Parser.java	Thu Jul 11 18:33:33 2013 +0200
    59.3 @@ -54,6 +54,7 @@
    59.4  import static jdk.nashorn.internal.parser.TokenType.WHILE;
    59.5  
    59.6  import java.util.ArrayList;
    59.7 +import java.util.Collections;
    59.8  import java.util.HashSet;
    59.9  import java.util.Iterator;
   59.10  import java.util.LinkedHashMap;
   59.11 @@ -66,6 +67,7 @@
   59.12  import jdk.nashorn.internal.ir.BinaryNode;
   59.13  import jdk.nashorn.internal.ir.Block;
   59.14  import jdk.nashorn.internal.ir.BlockLexicalContext;
   59.15 +import jdk.nashorn.internal.ir.BlockStatement;
   59.16  import jdk.nashorn.internal.ir.BreakNode;
   59.17  import jdk.nashorn.internal.ir.BreakableNode;
   59.18  import jdk.nashorn.internal.ir.CallNode;
   59.19 @@ -73,7 +75,8 @@
   59.20  import jdk.nashorn.internal.ir.CatchNode;
   59.21  import jdk.nashorn.internal.ir.ContinueNode;
   59.22  import jdk.nashorn.internal.ir.EmptyNode;
   59.23 -import jdk.nashorn.internal.ir.ExecuteNode;
   59.24 +import jdk.nashorn.internal.ir.Expression;
   59.25 +import jdk.nashorn.internal.ir.ExpressionStatement;
   59.26  import jdk.nashorn.internal.ir.ForNode;
   59.27  import jdk.nashorn.internal.ir.FunctionNode;
   59.28  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
   59.29 @@ -350,7 +353,7 @@
   59.30       * @return New block.
   59.31       */
   59.32      private Block newBlock() {
   59.33 -        return lc.push(new Block(line, token, Token.descPosition(token)));
   59.34 +        return lc.push(new Block(token, Token.descPosition(token)));
   59.35      }
   59.36  
   59.37      /**
   59.38 @@ -516,7 +519,7 @@
   59.39       * @param rhs Right hand side expression.
   59.40       * @return Verified expression.
   59.41       */
   59.42 -    private Node verifyAssignment(final long op, final Node lhs, final Node rhs) {
   59.43 +    private Expression verifyAssignment(final long op, final Expression lhs, final Expression rhs) {
   59.44          final TokenType opType = Token.descType(op);
   59.45  
   59.46          switch (opType) {
   59.47 @@ -562,7 +565,7 @@
   59.48       * @param isPostfix  Prefix or postfix.
   59.49       * @return           Reduced expression.
   59.50       */
   59.51 -    private static Node incDecExpression(final long firstToken, final TokenType tokenType, final Node expression, final boolean isPostfix) {
   59.52 +    private static UnaryNode incDecExpression(final long firstToken, final TokenType tokenType, final Expression expression, final boolean isPostfix) {
   59.53          if (isPostfix) {
   59.54              return new UnaryNode(Token.recast(firstToken, tokenType == DECPREFIX ? DECPOSTFIX : INCPOSTFIX), expression.getStart(), Token.descPosition(firstToken) + Token.descLength(firstToken), expression);
   59.55          }
   59.56 @@ -622,8 +625,8 @@
   59.57       * @return Directive value if the given statement is a directive
   59.58       */
   59.59      private String getDirective(final Node stmt) {
   59.60 -        if (stmt instanceof ExecuteNode) {
   59.61 -            final Node expr = ((ExecuteNode)stmt).getExpression();
   59.62 +        if (stmt instanceof ExpressionStatement) {
   59.63 +            final Node expr = ((ExpressionStatement)stmt).getExpression();
   59.64              if (expr instanceof LiteralNode) {
   59.65                  final LiteralNode<?> lit = (LiteralNode<?>)expr;
   59.66                  final long litToken = lit.getToken();
   59.67 @@ -836,9 +839,7 @@
   59.68       * Parse a statement block.
   59.69       */
   59.70      private void block() {
   59.71 -        final Block newBlock = getBlock(true);
   59.72 -        // Force block execution.
   59.73 -        appendStatement(new ExecuteNode(newBlock.getLineNumber(), newBlock.getToken(), finish, newBlock));
   59.74 +        appendStatement(new BlockStatement(line, getBlock(true)));
   59.75      }
   59.76  
   59.77      /**
   59.78 @@ -921,7 +922,7 @@
   59.79              verifyStrictIdent(name, "variable name");
   59.80  
   59.81              // Assume no init.
   59.82 -            Node init = null;
   59.83 +            Expression init = null;
   59.84  
   59.85              // Look for initializer assignment.
   59.86              if (type == ASSIGN) {
   59.87 @@ -985,20 +986,20 @@
   59.88          final long expressionToken = token;
   59.89  
   59.90          // Get expression and add as statement.
   59.91 -        final Node expression = expression();
   59.92 -
   59.93 -        ExecuteNode executeNode = null;
   59.94 +        final Expression expression = expression();
   59.95 +
   59.96 +        ExpressionStatement expressionStatement = null;
   59.97          if (expression != null) {
   59.98 -            executeNode = new ExecuteNode(expressionLine, expressionToken, finish, expression);
   59.99 -            appendStatement(executeNode);
  59.100 +            expressionStatement = new ExpressionStatement(expressionLine, expressionToken, finish, expression);
  59.101 +            appendStatement(expressionStatement);
  59.102          } else {
  59.103              expect(null);
  59.104          }
  59.105  
  59.106          endOfLine();
  59.107  
  59.108 -        if (executeNode != null) {
  59.109 -            executeNode.setFinish(finish);
  59.110 +        if (expressionStatement != null) {
  59.111 +            expressionStatement.setFinish(finish);
  59.112              lc.getCurrentBlock().setFinish(finish);
  59.113          }
  59.114      }
  59.115 @@ -1020,7 +1021,7 @@
  59.116          next();
  59.117  
  59.118          expect(LPAREN);
  59.119 -        final Node test = expression();
  59.120 +        final Expression test = expression();
  59.121          expect(RPAREN);
  59.122          final Block pass = getStatement();
  59.123  
  59.124 @@ -1049,8 +1050,6 @@
  59.125          // Create FOR node, capturing FOR token.
  59.126          ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, null, null, null, ForNode.IS_FOR);
  59.127  
  59.128 -        // Set up new block for scope of vars. Captures first token.
  59.129 -        Block outer = newBlock();
  59.130          lc.push(forNode);
  59.131  
  59.132          try {
  59.133 @@ -1076,7 +1075,7 @@
  59.134              case SEMICOLON:
  59.135                  break;
  59.136              default:
  59.137 -                final Node expression = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
  59.138 +                final Expression expression = expression(unaryExpression(), COMMARIGHT.getPrecedence(), true);
  59.139                  forNode = forNode.setInit(lc, expression);
  59.140                  break;
  59.141              }
  59.142 @@ -1148,15 +1147,11 @@
  59.143              final Block body = getStatement();
  59.144              forNode = forNode.setBody(lc, body);
  59.145              forNode.setFinish(body.getFinish());
  59.146 -            outer.setFinish(body.getFinish());
  59.147  
  59.148              appendStatement(forNode);
  59.149          } finally {
  59.150              lc.pop(forNode);
  59.151 -            outer = restoreBlock(outer);
  59.152          }
  59.153 -
  59.154 -        appendStatement(new ExecuteNode(outer.getLineNumber(), outer.getToken(), outer.getFinish(), outer));
  59.155       }
  59.156  
  59.157      /**
  59.158 @@ -1364,7 +1359,7 @@
  59.159          // RETURN tested in caller.
  59.160          nextOrEOL();
  59.161  
  59.162 -        Node expression = null;
  59.163 +        Expression expression = null;
  59.164  
  59.165          // SEMICOLON or expression.
  59.166          switch (type) {
  59.167 @@ -1400,7 +1395,7 @@
  59.168          // YIELD tested in caller.
  59.169          nextOrEOL();
  59.170  
  59.171 -        Node expression = null;
  59.172 +        Expression expression = null;
  59.173  
  59.174          // SEMICOLON or expression.
  59.175          switch (type) {
  59.176 @@ -1502,7 +1497,7 @@
  59.177  
  59.178              while (type != RBRACE) {
  59.179                  // Prepare for next case.
  59.180 -                Node caseExpression = null;
  59.181 +                Expression caseExpression = null;
  59.182                  final long caseToken = token;
  59.183  
  59.184                  switch (type) {
  59.185 @@ -1595,7 +1590,7 @@
  59.186          // THROW tested in caller.
  59.187          nextOrEOL();
  59.188  
  59.189 -        Node expression = null;
  59.190 +        Expression expression = null;
  59.191  
  59.192          // SEMICOLON or expression.
  59.193          switch (type) {
  59.194 @@ -1643,6 +1638,7 @@
  59.195          next();
  59.196  
  59.197          // Container block needed to act as target for labeled break statements
  59.198 +        final int startLine = line;
  59.199          Block outer = newBlock();
  59.200  
  59.201          // Create try.
  59.202 @@ -1662,11 +1658,13 @@
  59.203                  verifyStrictIdent(exception, "catch argument");
  59.204  
  59.205                  // Check for conditional catch.
  59.206 -                Node ifExpression = null;
  59.207 +                final Expression ifExpression;
  59.208                  if (type == IF) {
  59.209                      next();
  59.210                      // Get the exception condition.
  59.211                      ifExpression = expression();
  59.212 +                } else {
  59.213 +                    ifExpression = null;
  59.214                  }
  59.215  
  59.216                  expect(RPAREN);
  59.217 @@ -1713,7 +1711,7 @@
  59.218              outer = restoreBlock(outer);
  59.219          }
  59.220  
  59.221 -        appendStatement(new ExecuteNode(outer.getLineNumber(), outer.getToken(), outer.getFinish(), outer));
  59.222 +        appendStatement(new BlockStatement(startLine, outer));
  59.223      }
  59.224  
  59.225      /**
  59.226 @@ -1731,7 +1729,7 @@
  59.227          // DEBUGGER tested in caller.
  59.228          next();
  59.229          endOfLine();
  59.230 -        appendStatement(new ExecuteNode(debuggerLine, debuggerToken, finish, new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList<Node>())));
  59.231 +        appendStatement(new ExpressionStatement(debuggerLine, debuggerToken, finish, new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList<Expression>())));
  59.232      }
  59.233  
  59.234      /**
  59.235 @@ -1749,7 +1747,7 @@
  59.236       * @return Expression node.
  59.237       */
  59.238      @SuppressWarnings("fallthrough")
  59.239 -    private Node primaryExpression() {
  59.240 +    private Expression primaryExpression() {
  59.241          // Capture first token.
  59.242          final int  primaryLine  = line;
  59.243          final long primaryToken = token;
  59.244 @@ -1796,7 +1794,7 @@
  59.245          case LPAREN:
  59.246              next();
  59.247  
  59.248 -            final Node expression = expression();
  59.249 +            final Expression expression = expression();
  59.250  
  59.251              expect(RPAREN);
  59.252  
  59.253 @@ -1823,17 +1821,16 @@
  59.254       * @param primaryToken Original string token.
  59.255       * @return callNode to $EXEC.
  59.256       */
  59.257 -    Node execString(final int primaryLine, final long primaryToken) {
  59.258 +    CallNode execString(final int primaryLine, final long primaryToken) {
  59.259          // Synthesize an ident to call $EXEC.
  59.260          final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME);
  59.261          // Skip over EXECSTRING.
  59.262          next();
  59.263          // Set up argument list for call.
  59.264 -        final List<Node> arguments = new ArrayList<>();
  59.265          // Skip beginning of edit string expression.
  59.266          expect(LBRACE);
  59.267          // Add the following expression to arguments.
  59.268 -        arguments.add(expression());
  59.269 +        final List<Expression> arguments = Collections.singletonList(expression());
  59.270          // Skip ending of edit string expression.
  59.271          expect(RBRACE);
  59.272  
  59.273 @@ -1860,14 +1857,14 @@
  59.274       * Parse array literal.
  59.275       * @return Expression node.
  59.276       */
  59.277 -    private Node arrayLiteral() {
  59.278 +    private LiteralNode<Expression[]> arrayLiteral() {
  59.279          // Capture LBRACKET token.
  59.280          final long arrayToken = token;
  59.281          // LBRACKET tested in caller.
  59.282          next();
  59.283  
  59.284          // Prepare to accummulating elements.
  59.285 -        final List<Node> elements = new ArrayList<>();
  59.286 +        final List<Expression> elements = new ArrayList<>();
  59.287          // Track elisions.
  59.288          boolean elision = true;
  59.289  loop:
  59.290 @@ -1895,7 +1892,7 @@
  59.291                      throw error(AbstractParser.message("expected.comma", type.getNameOrType()));
  59.292                  }
  59.293                  // Add expression element.
  59.294 -                final Node expression = assignmentExpression(false);
  59.295 +                final Expression expression = assignmentExpression(false);
  59.296  
  59.297                  if (expression != null) {
  59.298                      elements.add(expression);
  59.299 @@ -1925,7 +1922,7 @@
  59.300       * Parse an object literal.
  59.301       * @return Expression node.
  59.302       */
  59.303 -    private Node objectLiteral() {
  59.304 +    private ObjectNode objectLiteral() {
  59.305          // Capture LBRACE token.
  59.306          final long objectToken = token;
  59.307          // LBRACE tested in caller.
  59.308 @@ -1972,11 +1969,11 @@
  59.309  
  59.310                      // ECMA section 11.1.5 Object Initialiser
  59.311                      // point # 4 on property assignment production
  59.312 -                    final Node         value  = property.getValue();
  59.313 +                    final Expression   value  = property.getValue();
  59.314                      final FunctionNode getter = property.getGetter();
  59.315                      final FunctionNode setter = property.getSetter();
  59.316  
  59.317 -                    final Node         prevValue  = existingProperty.getValue();
  59.318 +                    final Expression   prevValue  = existingProperty.getValue();
  59.319                      final FunctionNode prevGetter = existingProperty.getGetter();
  59.320                      final FunctionNode prevSetter = existingProperty.getSetter();
  59.321  
  59.322 @@ -2052,7 +2049,7 @@
  59.323      private PropertyKey propertyName() {
  59.324          switch (type) {
  59.325          case IDENT:
  59.326 -            return getIdent();
  59.327 +            return getIdent().setIsPropertyName();
  59.328          case OCTAL:
  59.329              if (isStrictMode) {
  59.330                  throw error(AbstractParser.message("strict.no.octal"), token);
  59.331 @@ -2129,7 +2126,7 @@
  59.332                  }
  59.333              }
  59.334  
  59.335 -            propertyName =  new IdentNode(propertyToken, finish, ident);
  59.336 +            propertyName =  new IdentNode(propertyToken, finish, ident).setIsPropertyName();
  59.337          } else {
  59.338              propertyName = propertyName();
  59.339          }
  59.340 @@ -2155,14 +2152,14 @@
  59.341       * Parse left hand side expression.
  59.342       * @return Expression node.
  59.343       */
  59.344 -    private Node leftHandSideExpression() {
  59.345 +    private Expression leftHandSideExpression() {
  59.346          int  callLine  = line;
  59.347          long callToken = token;
  59.348  
  59.349 -        Node lhs = memberExpression();
  59.350 +        Expression lhs = memberExpression();
  59.351  
  59.352          if (type == LPAREN) {
  59.353 -            final List<Node> arguments = argumentList();
  59.354 +            final List<Expression> arguments = optimizeList(argumentList());
  59.355  
  59.356              // Catch special functions.
  59.357              if (lhs instanceof IdentNode) {
  59.358 @@ -2181,7 +2178,7 @@
  59.359              switch (type) {
  59.360              case LPAREN:
  59.361                  // Get NEW or FUNCTION arguments.
  59.362 -                final List<Node> arguments = argumentList();
  59.363 +                final List<Expression> arguments = optimizeList(argumentList());
  59.364  
  59.365                  // Create call node.
  59.366                  lhs = new CallNode(callLine, callToken, finish, lhs, arguments);
  59.367 @@ -2192,7 +2189,7 @@
  59.368                  next();
  59.369  
  59.370                  // Get array index.
  59.371 -                final Node rhs = expression();
  59.372 +                final Expression rhs = expression();
  59.373  
  59.374                  expect(RBRACKET);
  59.375  
  59.376 @@ -2229,19 +2226,19 @@
  59.377       * Parse new expression.
  59.378       * @return Expression node.
  59.379       */
  59.380 -    private Node newExpression() {
  59.381 +    private Expression newExpression() {
  59.382          final long newToken = token;
  59.383          // NEW is tested in caller.
  59.384          next();
  59.385  
  59.386          // Get function base.
  59.387          final int  callLine    = line;
  59.388 -        final Node constructor = memberExpression();
  59.389 +        final Expression constructor = memberExpression();
  59.390          if (constructor == null) {
  59.391              return null;
  59.392          }
  59.393          // Get arguments.
  59.394 -        List<Node> arguments;
  59.395 +        ArrayList<Expression> arguments;
  59.396  
  59.397          // Allow for missing arguments.
  59.398          if (type == LPAREN) {
  59.399 @@ -2259,12 +2256,11 @@
  59.400          //
  59.401          // The object literal following the "new Constructor()" expresssion
  59.402          // is passed as an additional (last) argument to the constructor.
  59.403 -
  59.404          if (!env._no_syntax_extensions && type == LBRACE) {
  59.405              arguments.add(objectLiteral());
  59.406          }
  59.407  
  59.408 -        final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, arguments);
  59.409 +        final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, optimizeList(arguments));
  59.410  
  59.411          return new UnaryNode(newToken, callNode);
  59.412      }
  59.413 @@ -2282,9 +2278,9 @@
  59.414       * Parse member expression.
  59.415       * @return Expression node.
  59.416       */
  59.417 -    private Node memberExpression() {
  59.418 +    private Expression memberExpression() {
  59.419          // Prepare to build operation.
  59.420 -        Node lhs;
  59.421 +        Expression lhs;
  59.422  
  59.423          switch (type) {
  59.424          case NEW:
  59.425 @@ -2313,7 +2309,7 @@
  59.426                  next();
  59.427  
  59.428                  // Get array index.
  59.429 -                final Node index = expression();
  59.430 +                final Expression index = expression();
  59.431  
  59.432                  expect(RBRACKET);
  59.433  
  59.434 @@ -2358,9 +2354,9 @@
  59.435       * Parse function call arguments.
  59.436       * @return Argument list.
  59.437       */
  59.438 -    private List<Node> argumentList() {
  59.439 +    private ArrayList<Expression> argumentList() {
  59.440          // Prepare to accumulate list of arguments.
  59.441 -        final List<Node> nodeList = new ArrayList<>();
  59.442 +        final ArrayList<Expression> nodeList = new ArrayList<>();
  59.443          // LPAREN tested in caller.
  59.444          next();
  59.445  
  59.446 @@ -2380,9 +2376,23 @@
  59.447          }
  59.448  
  59.449          expect(RPAREN);
  59.450 -
  59.451          return nodeList;
  59.452 -   }
  59.453 +    }
  59.454 +
  59.455 +    private static <T> List<T> optimizeList(ArrayList<T> list) {
  59.456 +        switch(list.size()) {
  59.457 +            case 0: {
  59.458 +                return Collections.emptyList();
  59.459 +            }
  59.460 +            case 1: {
  59.461 +                return Collections.singletonList(list.get(0));
  59.462 +            }
  59.463 +            default: {
  59.464 +                list.trimToSize();
  59.465 +                return list;
  59.466 +            }
  59.467 +        }
  59.468 +    }
  59.469  
  59.470      /**
  59.471       * FunctionDeclaration :
  59.472 @@ -2398,7 +2408,7 @@
  59.473       *
  59.474       * @return Expression node.
  59.475       */
  59.476 -    private Node functionExpression(final boolean isStatement, final boolean topLevel) {
  59.477 +    private Expression functionExpression(final boolean isStatement, final boolean topLevel) {
  59.478          final long functionToken = token;
  59.479          final int  functionLine  = line;
  59.480          // FUNCTION is tested in caller.
  59.481 @@ -2574,10 +2584,8 @@
  59.482                   */
  59.483  
  59.484                  // just expression as function body
  59.485 -                final Node expr = assignmentExpression(true);
  59.486 +                final Expression expr = assignmentExpression(true);
  59.487                  assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
  59.488 -                // create a return statement - this creates code in itself and does not need to be
  59.489 -                // wrapped into an ExecuteNode
  59.490                  final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), finish, expr);
  59.491                  appendStatement(returnNode);
  59.492                  lastToken = token;
  59.493 @@ -2620,11 +2628,11 @@
  59.494          }
  59.495      }
  59.496  
  59.497 -    private RuntimeNode referenceError(final Node lhs, final Node rhs, final boolean earlyError) {
  59.498 +    private RuntimeNode referenceError(final Expression lhs, final Expression rhs, final boolean earlyError) {
  59.499          if (earlyError) {
  59.500              throw error(JSErrorType.REFERENCE_ERROR, AbstractParser.message("invalid.lvalue"), lhs.getToken());
  59.501          }
  59.502 -        final ArrayList<Node> args = new ArrayList<>();
  59.503 +        final ArrayList<Expression> args = new ArrayList<>();
  59.504          args.add(lhs);
  59.505          if (rhs == null) {
  59.506              args.add(LiteralNode.newInstance(lhs.getToken(), lhs.getFinish()));
  59.507 @@ -2669,18 +2677,18 @@
  59.508       * Parse unary expression.
  59.509       * @return Expression node.
  59.510       */
  59.511 -    private Node unaryExpression() {
  59.512 +    private Expression unaryExpression() {
  59.513          final int  unaryLine  = line;
  59.514          final long unaryToken = token;
  59.515  
  59.516          switch (type) {
  59.517          case DELETE: {
  59.518              next();
  59.519 -            final Node expr = unaryExpression();
  59.520 +            final Expression expr = unaryExpression();
  59.521              if (expr instanceof BaseNode || expr instanceof IdentNode) {
  59.522                  return new UnaryNode(unaryToken, expr);
  59.523              }
  59.524 -            appendStatement(new ExecuteNode(unaryLine, unaryToken, finish, expr));
  59.525 +            appendStatement(new ExpressionStatement(unaryLine, unaryToken, finish, expr));
  59.526              return LiteralNode.newInstance(unaryToken, finish, true);
  59.527          }
  59.528          case VOID:
  59.529 @@ -2690,7 +2698,7 @@
  59.530          case BIT_NOT:
  59.531          case NOT:
  59.532              next();
  59.533 -            final Node expr = unaryExpression();
  59.534 +            final Expression expr = unaryExpression();
  59.535              return new UnaryNode(unaryToken, expr);
  59.536  
  59.537          case INCPREFIX:
  59.538 @@ -2698,7 +2706,7 @@
  59.539              final TokenType opType = type;
  59.540              next();
  59.541  
  59.542 -            final Node lhs = leftHandSideExpression();
  59.543 +            final Expression lhs = leftHandSideExpression();
  59.544              // ++, -- without operand..
  59.545              if (lhs == null) {
  59.546                  throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
  59.547 @@ -2723,14 +2731,14 @@
  59.548              break;
  59.549          }
  59.550  
  59.551 -        Node expression = leftHandSideExpression();
  59.552 +        Expression expression = leftHandSideExpression();
  59.553  
  59.554          if (last != EOL) {
  59.555              switch (type) {
  59.556              case INCPREFIX:
  59.557              case DECPREFIX:
  59.558                  final TokenType opType = type;
  59.559 -                final Node lhs = expression;
  59.560 +                final Expression lhs = expression;
  59.561                  // ++, -- without operand..
  59.562                  if (lhs == null) {
  59.563                      throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
  59.564 @@ -2855,16 +2863,16 @@
  59.565       * Parse expression.
  59.566       * @return Expression node.
  59.567       */
  59.568 -    private Node expression() {
  59.569 +    private Expression expression() {
  59.570          // TODO - Destructuring array.
  59.571          // Include commas in expression parsing.
  59.572          return expression(unaryExpression(), COMMARIGHT.getPrecedence(), false);
  59.573      }
  59.574  
  59.575 -    private Node expression(final Node exprLhs, final int minPrecedence, final boolean noIn) {
  59.576 +    private Expression expression(final Expression exprLhs, final int minPrecedence, final boolean noIn) {
  59.577          // Get the precedence of the next operator.
  59.578          int precedence = type.getPrecedence();
  59.579 -        Node lhs = exprLhs;
  59.580 +        Expression lhs = exprLhs;
  59.581  
  59.582          // While greater precedence.
  59.583          while (type.isOperator(noIn) && precedence >= minPrecedence) {
  59.584 @@ -2877,12 +2885,12 @@
  59.585  
  59.586                  // Pass expression. Middle expression of a conditional expression can be a "in"
  59.587                  // expression - even in the contexts where "in" is not permitted.
  59.588 -                final Node rhs = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
  59.589 +                final Expression rhs = expression(unaryExpression(), ASSIGN.getPrecedence(), false);
  59.590  
  59.591                  expect(COLON);
  59.592  
  59.593                  // Fail expression.
  59.594 -                final Node third = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
  59.595 +                final Expression third = expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
  59.596  
  59.597                  // Build up node.
  59.598                  lhs = new TernaryNode(op, lhs, rhs, third);
  59.599 @@ -2891,7 +2899,7 @@
  59.600                  next();
  59.601  
  59.602                   // Get the next primary expression.
  59.603 -                Node rhs = unaryExpression();
  59.604 +                Expression rhs = unaryExpression();
  59.605  
  59.606                  // Get precedence of next operator.
  59.607                  int nextPrecedence = type.getPrecedence();
  59.608 @@ -2913,7 +2921,7 @@
  59.609          return lhs;
  59.610      }
  59.611  
  59.612 -    private Node assignmentExpression(final boolean noIn) {
  59.613 +    private Expression assignmentExpression(final boolean noIn) {
  59.614          // TODO - Handle decompose.
  59.615          // Exclude commas in expression parsing.
  59.616          return expression(unaryExpression(), ASSIGN.getPrecedence(), noIn);
    60.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Thu Jul 11 18:23:13 2013 +0530
    60.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Thu Jul 11 18:33:33 2013 +0200
    60.3 @@ -28,7 +28,6 @@
    60.4  import java.lang.invoke.MethodHandles;
    60.5  import java.lang.invoke.MethodHandles.Lookup;
    60.6  import java.lang.invoke.MethodType;
    60.7 -import java.util.Map;
    60.8  import java.util.concurrent.ConcurrentHashMap;
    60.9  import java.util.concurrent.ConcurrentMap;
   60.10  import jdk.internal.dynalink.CallSiteDescriptor;
   60.11 @@ -111,7 +110,7 @@
   60.12          final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(lookup, operator, operand, methodType, flags);
   60.13          // Many of these call site descriptors are identical (e.g. every getter for a property color will be
   60.14          // "dyn:getProp:color(Object)Object", so it makes sense canonicalizing them.
   60.15 -        final Map<NashornCallSiteDescriptor, NashornCallSiteDescriptor> classCanonicals = canonicals.get(lookup.lookupClass());
   60.16 +        final ConcurrentMap<NashornCallSiteDescriptor, NashornCallSiteDescriptor> classCanonicals = canonicals.get(lookup.lookupClass());
   60.17          final NashornCallSiteDescriptor canonical = classCanonicals.putIfAbsent(csd, csd);
   60.18          return canonical != null ? canonical : csd;
   60.19      }
    61.1 --- a/test/script/trusted/JDK-8006529.js	Thu Jul 11 18:23:13 2013 +0530
    61.2 +++ b/test/script/trusted/JDK-8006529.js	Thu Jul 11 18:33:33 2013 +0200
    61.3 @@ -39,26 +39,26 @@
    61.4   * and FunctionNode because of package-access check and so reflective calls.
    61.5   */
    61.6  
    61.7 -var Parser            = Java.type("jdk.nashorn.internal.parser.Parser")
    61.8 -var Compiler          = Java.type("jdk.nashorn.internal.codegen.Compiler")
    61.9 -var Context           = Java.type("jdk.nashorn.internal.runtime.Context")
   61.10 -var ScriptEnvironment = Java.type("jdk.nashorn.internal.runtime.ScriptEnvironment")
   61.11 -var Source            = Java.type("jdk.nashorn.internal.runtime.Source")
   61.12 -var FunctionNode      = Java.type("jdk.nashorn.internal.ir.FunctionNode")
   61.13 -var Block             = Java.type("jdk.nashorn.internal.ir.Block")
   61.14 -var VarNode           = Java.type("jdk.nashorn.internal.ir.VarNode")
   61.15 -var ExecuteNode       = Java.type("jdk.nashorn.internal.ir.ExecuteNode")
   61.16 -var UnaryNode         = Java.type("jdk.nashorn.internal.ir.UnaryNode")
   61.17 -var BinaryNode        = Java.type("jdk.nashorn.internal.ir.BinaryNode")
   61.18 -var ThrowErrorManager = Java.type("jdk.nashorn.internal.runtime.Context$ThrowErrorManager")
   61.19 -var Debug             = Java.type("jdk.nashorn.internal.runtime.Debug")
   61.20 +var Parser              = Java.type("jdk.nashorn.internal.parser.Parser")
   61.21 +var Compiler            = Java.type("jdk.nashorn.internal.codegen.Compiler")
   61.22 +var Context             = Java.type("jdk.nashorn.internal.runtime.Context")
   61.23 +var ScriptEnvironment   = Java.type("jdk.nashorn.internal.runtime.ScriptEnvironment")
   61.24 +var Source              = Java.type("jdk.nashorn.internal.runtime.Source")
   61.25 +var FunctionNode        = Java.type("jdk.nashorn.internal.ir.FunctionNode")
   61.26 +var Block               = Java.type("jdk.nashorn.internal.ir.Block")
   61.27 +var VarNode             = Java.type("jdk.nashorn.internal.ir.VarNode")
   61.28 +var ExpressionStatement = Java.type("jdk.nashorn.internal.ir.ExpressionStatement")
   61.29 +var UnaryNode           = Java.type("jdk.nashorn.internal.ir.UnaryNode")
   61.30 +var BinaryNode          = Java.type("jdk.nashorn.internal.ir.BinaryNode")
   61.31 +var ThrowErrorManager   = Java.type("jdk.nashorn.internal.runtime.Context$ThrowErrorManager")
   61.32 +var Debug               = Java.type("jdk.nashorn.internal.runtime.Debug")
   61.33  
   61.34  var parseMethod = Parser.class.getMethod("parse");
   61.35  var compileMethod = Compiler.class.getMethod("compile", FunctionNode.class);
   61.36  var getBodyMethod = FunctionNode.class.getMethod("getBody");
   61.37  var getStatementsMethod = Block.class.getMethod("getStatements");
   61.38  var getInitMethod = VarNode.class.getMethod("getInit");
   61.39 -var getExpressionMethod = ExecuteNode.class.getMethod("getExpression")
   61.40 +var getExpressionMethod = ExpressionStatement.class.getMethod("getExpression")
   61.41  var rhsMethod = UnaryNode.class.getMethod("rhs")
   61.42  var lhsMethod = BinaryNode.class.getMethod("lhs")
   61.43  var binaryRhsMethod = BinaryNode.class.getMethod("rhs")
   61.44 @@ -101,7 +101,7 @@
   61.45          return findFunction(rhsMethod.invoke(node))
   61.46      } else if(node instanceof BinaryNode) {
   61.47          return findFunction(lhsMethod.invoke(node)) || findFunction(binaryRhsMethod.invoke(node))
   61.48 -	} else if(node instanceof ExecuteNode) {
   61.49 +	} else if(node instanceof ExpressionStatement) {
   61.50  		return findFunction(getExpressionMethod.invoke(node))
   61.51      } else if(node instanceof FunctionNode) {
   61.52          return node

mercurial