src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java
changeset 48411 4ff5c5206427
parent 48334 fdefa410d655
equal deleted inserted replaced
48410:8aab0cea56bf 48411:4ff5c5206427
    57 import java.util.List;
    57 import java.util.List;
    58 import java.util.ListIterator;
    58 import java.util.ListIterator;
    59 import java.util.Map;
    59 import java.util.Map;
    60 import java.util.Set;
    60 import java.util.Set;
    61 import jdk.nashorn.internal.ir.AccessNode;
    61 import jdk.nashorn.internal.ir.AccessNode;
       
    62 import jdk.nashorn.internal.ir.BaseNode;
    62 import jdk.nashorn.internal.ir.BinaryNode;
    63 import jdk.nashorn.internal.ir.BinaryNode;
    63 import jdk.nashorn.internal.ir.Block;
    64 import jdk.nashorn.internal.ir.Block;
    64 import jdk.nashorn.internal.ir.CatchNode;
    65 import jdk.nashorn.internal.ir.CatchNode;
    65 import jdk.nashorn.internal.ir.Expression;
    66 import jdk.nashorn.internal.ir.Expression;
    66 import jdk.nashorn.internal.ir.ForNode;
    67 import jdk.nashorn.internal.ir.ForNode;
   733         return binaryNode;
   734         return binaryNode;
   734     }
   735     }
   735 
   736 
   736     @Override
   737     @Override
   737     public Node leaveUnaryNode(final UnaryNode unaryNode) {
   738     public Node leaveUnaryNode(final UnaryNode unaryNode) {
   738         switch (unaryNode.tokenType()) {
   739         if (unaryNode.tokenType() == TokenType.TYPEOF) {
   739         case DELETE:
       
   740             return leaveDELETE(unaryNode);
       
   741         case TYPEOF:
       
   742             return leaveTYPEOF(unaryNode);
   740             return leaveTYPEOF(unaryNode);
   743         default:
   741         } else {
   744             return super.leaveUnaryNode(unaryNode);
   742             return super.leaveUnaryNode(unaryNode);
   745         }
   743         }
   746     }
       
   747 
       
   748     private Node leaveDELETE(final UnaryNode unaryNode) {
       
   749         final FunctionNode currentFunctionNode = lc.getCurrentFunction();
       
   750         final boolean      strictMode          = currentFunctionNode.isStrict();
       
   751         final Expression   rhs                 = unaryNode.getExpression();
       
   752         final Expression   strictFlagNode      = (Expression)LiteralNode.newInstance(unaryNode, strictMode).accept(this);
       
   753 
       
   754         Request request = Request.DELETE;
       
   755         final List<Expression> args = new ArrayList<>();
       
   756 
       
   757         if (rhs instanceof IdentNode) {
       
   758             final IdentNode ident = (IdentNode)rhs;
       
   759             // If this is a declared variable or a function parameter, delete always fails (except for globals).
       
   760             final String name = ident.getName();
       
   761             final Symbol symbol = ident.getSymbol();
       
   762 
       
   763             if (symbol.isThis()) {
       
   764                 // Can't delete "this", ignore and return true
       
   765                 return LiteralNode.newInstance(unaryNode, true);
       
   766             }
       
   767             final Expression literalNode = LiteralNode.newInstance(unaryNode, name);
       
   768             final boolean failDelete = strictMode || (!symbol.isScope() && (symbol.isParam() || (symbol.isVar() && !symbol.isProgramLevel())));
       
   769 
       
   770             if (!failDelete) {
       
   771                 args.add(compilerConstantIdentifier(SCOPE));
       
   772             }
       
   773             args.add(literalNode);
       
   774             args.add(strictFlagNode);
       
   775 
       
   776             if (failDelete) {
       
   777                 request = Request.FAIL_DELETE;
       
   778             } else if ((symbol.isGlobal() && !symbol.isFunctionDeclaration()) || symbol.isProgramLevel()) {
       
   779                 request = Request.SLOW_DELETE;
       
   780             }
       
   781         } else if (rhs instanceof AccessNode) {
       
   782             final Expression base     = ((AccessNode)rhs).getBase();
       
   783             final String     property = ((AccessNode)rhs).getProperty();
       
   784 
       
   785             args.add(base);
       
   786             args.add(LiteralNode.newInstance(unaryNode, property));
       
   787             args.add(strictFlagNode);
       
   788 
       
   789         } else if (rhs instanceof IndexNode) {
       
   790             final IndexNode indexNode = (IndexNode)rhs;
       
   791             final Expression base  = indexNode.getBase();
       
   792             final Expression index = indexNode.getIndex();
       
   793 
       
   794             args.add(base);
       
   795             args.add(index);
       
   796             args.add(strictFlagNode);
       
   797 
       
   798         } else {
       
   799             throw new AssertionError("Unexpected delete with " + rhs.getClass().getName() + " expression");
       
   800         }
       
   801         return new RuntimeNode(unaryNode, request, args);
       
   802     }
   744     }
   803 
   745 
   804     @Override
   746     @Override
   805     public Node leaveForNode(final ForNode forNode) {
   747     public Node leaveForNode(final ForNode forNode) {
   806         if (forNode.isForInOrOf()) {
   748         if (forNode.isForInOrOf()) {