< prev index next >

src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java

Print this page




  80 import jdk.nashorn.internal.runtime.Context;
  81 import jdk.nashorn.internal.runtime.JSType;
  82 import jdk.nashorn.internal.runtime.Source;
  83 import jdk.nashorn.internal.runtime.logging.DebugLogger;
  84 import jdk.nashorn.internal.runtime.logging.Loggable;
  85 import jdk.nashorn.internal.runtime.logging.Logger;
  86 
  87 /**
  88  * Lower to more primitive operations. After lowering, an AST still has no symbols
  89  * and types, but several nodes have been turned into more low level constructs
  90  * and control flow termination criteria have been computed.
  91  *
  92  * We do things like code copying/inlining of finallies here, as it is much
  93  * harder and context dependent to do any code copying after symbols have been
  94  * finalized.
  95  */
  96 @Logger(name="lower")
  97 final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Loggable {
  98 
  99     private final DebugLogger log;

 100 
 101     // Conservative pattern to test if element names consist of characters valid for identifiers.
 102     // This matches any non-zero length alphanumeric string including _ and $ and not starting with a digit.
 103     private static final Pattern SAFE_PROPERTY_NAME = Pattern.compile("[a-zA-Z_$][\\w$]*");
 104 
 105     /**
 106      * Constructor.
 107      */
 108     Lower(final Compiler compiler) {
 109         super(new BlockLexicalContext() {
 110 
 111             @Override
 112             public List<Statement> popStatements() {
 113                 final List<Statement> newStatements = new ArrayList<>();
 114                 boolean terminated = false;
 115 
 116                 final List<Statement> statements = super.popStatements();
 117                 for (final Statement statement : statements) {
 118                     if (!terminated) {
 119                         newStatements.add(statement);


 127                 return newStatements;
 128             }
 129 
 130             @Override
 131             protected Block afterSetStatements(final Block block) {
 132                 final List<Statement> stmts = block.getStatements();
 133                 for(final ListIterator<Statement> li = stmts.listIterator(stmts.size()); li.hasPrevious();) {
 134                     final Statement stmt = li.previous();
 135                     // popStatements() guarantees that the only thing after a terminal statement are uninitialized
 136                     // VarNodes. We skip past those, and set the terminal state of the block to the value of the
 137                     // terminal state of the first statement that is not an uninitialized VarNode.
 138                     if(!(stmt instanceof VarNode && ((VarNode)stmt).getInit() == null)) {
 139                         return block.setIsTerminal(this, stmt.isTerminal());
 140                     }
 141                 }
 142                 return block.setIsTerminal(this, false);
 143             }
 144         });
 145 
 146         this.log = initLogger(compiler.getContext());

 147     }
 148 
 149     @Override
 150     public DebugLogger getLogger() {
 151         return log;
 152     }
 153 
 154     @Override
 155     public DebugLogger initLogger(final Context context) {
 156         return context.getLogger(this.getClass());
 157     }
 158 
 159     @Override
 160     public boolean enterBreakNode(final BreakNode breakNode) {
 161         addStatement(breakNode);
 162         return false;
 163     }
 164 
 165     @Override
 166     public Node leaveCallNode(final CallNode callNode) {


 240         }
 241 
 242         return addStatement(node);
 243     }
 244 
 245     @Override
 246     public Node leaveBlockStatement(final BlockStatement blockStatement) {
 247         return addStatement(blockStatement);
 248     }
 249 
 250     @Override
 251     public Node leaveForNode(final ForNode forNode) {
 252         ForNode newForNode = forNode;
 253 
 254         final Expression test = forNode.getTest();
 255         if (!forNode.isForIn() && isAlwaysTrue(test)) {
 256             newForNode = forNode.setTest(lc, null);
 257         }
 258 
 259         newForNode = checkEscape(newForNode);
 260         if(newForNode.isForIn()) {
 261             // Wrap it in a block so its internally created iterator is restricted in scope

 262             addStatementEnclosedInBlock(newForNode);
 263         } else {
 264             addStatement(newForNode);
 265         }
 266         return newForNode;
 267     }
 268 
 269     @Override
 270     public Node leaveFunctionNode(final FunctionNode functionNode) {
 271         log.info("END FunctionNode: ", functionNode.getName());
 272         return functionNode;
 273     }
 274 
 275     @Override
 276     public Node leaveIfNode(final IfNode ifNode) {
 277         return addStatement(ifNode);
 278     }
 279 
 280     @Override
 281     public Node leaveIN(final BinaryNode binaryNode) {




  80 import jdk.nashorn.internal.runtime.Context;
  81 import jdk.nashorn.internal.runtime.JSType;
  82 import jdk.nashorn.internal.runtime.Source;
  83 import jdk.nashorn.internal.runtime.logging.DebugLogger;
  84 import jdk.nashorn.internal.runtime.logging.Loggable;
  85 import jdk.nashorn.internal.runtime.logging.Logger;
  86 
  87 /**
  88  * Lower to more primitive operations. After lowering, an AST still has no symbols
  89  * and types, but several nodes have been turned into more low level constructs
  90  * and control flow termination criteria have been computed.
  91  *
  92  * We do things like code copying/inlining of finallies here, as it is much
  93  * harder and context dependent to do any code copying after symbols have been
  94  * finalized.
  95  */
  96 @Logger(name="lower")
  97 final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Loggable {
  98 
  99     private final DebugLogger log;
 100     private final boolean es6;
 101 
 102     // Conservative pattern to test if element names consist of characters valid for identifiers.
 103     // This matches any non-zero length alphanumeric string including _ and $ and not starting with a digit.
 104     private static final Pattern SAFE_PROPERTY_NAME = Pattern.compile("[a-zA-Z_$][\\w$]*");
 105 
 106     /**
 107      * Constructor.
 108      */
 109     Lower(final Compiler compiler) {
 110         super(new BlockLexicalContext() {
 111 
 112             @Override
 113             public List<Statement> popStatements() {
 114                 final List<Statement> newStatements = new ArrayList<>();
 115                 boolean terminated = false;
 116 
 117                 final List<Statement> statements = super.popStatements();
 118                 for (final Statement statement : statements) {
 119                     if (!terminated) {
 120                         newStatements.add(statement);


 128                 return newStatements;
 129             }
 130 
 131             @Override
 132             protected Block afterSetStatements(final Block block) {
 133                 final List<Statement> stmts = block.getStatements();
 134                 for(final ListIterator<Statement> li = stmts.listIterator(stmts.size()); li.hasPrevious();) {
 135                     final Statement stmt = li.previous();
 136                     // popStatements() guarantees that the only thing after a terminal statement are uninitialized
 137                     // VarNodes. We skip past those, and set the terminal state of the block to the value of the
 138                     // terminal state of the first statement that is not an uninitialized VarNode.
 139                     if(!(stmt instanceof VarNode && ((VarNode)stmt).getInit() == null)) {
 140                         return block.setIsTerminal(this, stmt.isTerminal());
 141                     }
 142                 }
 143                 return block.setIsTerminal(this, false);
 144             }
 145         });
 146 
 147         this.log = initLogger(compiler.getContext());
 148         this.es6 = compiler.getScriptEnvironment()._es6;
 149     }
 150 
 151     @Override
 152     public DebugLogger getLogger() {
 153         return log;
 154     }
 155 
 156     @Override
 157     public DebugLogger initLogger(final Context context) {
 158         return context.getLogger(this.getClass());
 159     }
 160 
 161     @Override
 162     public boolean enterBreakNode(final BreakNode breakNode) {
 163         addStatement(breakNode);
 164         return false;
 165     }
 166 
 167     @Override
 168     public Node leaveCallNode(final CallNode callNode) {


 242         }
 243 
 244         return addStatement(node);
 245     }
 246 
 247     @Override
 248     public Node leaveBlockStatement(final BlockStatement blockStatement) {
 249         return addStatement(blockStatement);
 250     }
 251 
 252     @Override
 253     public Node leaveForNode(final ForNode forNode) {
 254         ForNode newForNode = forNode;
 255 
 256         final Expression test = forNode.getTest();
 257         if (!forNode.isForIn() && isAlwaysTrue(test)) {
 258             newForNode = forNode.setTest(lc, null);
 259         }
 260 
 261         newForNode = checkEscape(newForNode);
 262         if(!es6 && newForNode.isForIn()) {
 263             // Wrap it in a block so its internally created iterator is restricted in scope, unless we are running
 264             // in ES6 mode, in which case the parser already created a block to capture let/const declarations.
 265             addStatementEnclosedInBlock(newForNode);
 266         } else {
 267             addStatement(newForNode);
 268         }
 269         return newForNode;
 270     }
 271 
 272     @Override
 273     public Node leaveFunctionNode(final FunctionNode functionNode) {
 274         log.info("END FunctionNode: ", functionNode.getName());
 275         return functionNode;
 276     }
 277 
 278     @Override
 279     public Node leaveIfNode(final IfNode ifNode) {
 280         return addStatement(ifNode);
 281     }
 282 
 283     @Override
 284     public Node leaveIN(final BinaryNode binaryNode) {


< prev index next >