< prev index next >

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

Print this page




1736     }
1737 
1738     @Override
1739     public boolean enterBlockStatement(final BlockStatement blockStatement) {
1740         if(!method.isReachable()) {
1741             return false;
1742         }
1743         enterStatement(blockStatement);
1744 
1745         blockStatement.getBlock().accept(this);
1746 
1747         return false;
1748     }
1749 
1750     @Override
1751     public boolean enterForNode(final ForNode forNode) {
1752         if(!method.isReachable()) {
1753             return false;
1754         }
1755         enterStatement(forNode);
1756         if (forNode.isForIn()) {
1757             enterForIn(forNode);
1758         } else {
1759             final Expression init = forNode.getInit();
1760             if (init != null) {
1761                 loadAndDiscard(init);
1762             }
1763             enterForOrWhile(forNode, forNode.getModify());
1764         }
1765 
1766         return false;
1767     }
1768 
1769     private void enterForIn(final ForNode forNode) {
1770         loadExpression(forNode.getModify(), TypeBounds.OBJECT);
1771         method.invoke(forNode.isForEach() ? ScriptRuntime.TO_VALUE_ITERATOR : ScriptRuntime.TO_PROPERTY_ITERATOR);








1772         final Symbol iterSymbol = forNode.getIterator();
1773         final int iterSlot = iterSymbol.getSlot(Type.OBJECT);
1774         method.store(iterSymbol, ITERATOR_TYPE);
1775 
1776         method.beforeJoinPoint(forNode);
1777 
1778         final Label continueLabel = forNode.getContinueLabel();
1779         final Label breakLabel    = forNode.getBreakLabel();
1780 
1781         method.label(continueLabel);
1782         method.load(ITERATOR_TYPE, iterSlot);
1783         method.invoke(interfaceCallNoLookup(ITERATOR_CLASS, "hasNext", boolean.class));
1784         final JoinPredecessorExpression test = forNode.getTest();
1785         final Block body = forNode.getBody();
1786         if(LocalVariableConversion.hasLiveConversion(test)) {
1787             final Label afterConversion = new Label("for_in_after_test_conv");
1788             method.ifne(afterConversion);
1789             method.beforeJoinPoint(test);
1790             method._goto(breakLabel);
1791             method.label(afterConversion);


3301     }
3302 
3303     @Override
3304     public boolean enterVarNode(final VarNode varNode) {
3305         if(!method.isReachable()) {
3306             return false;
3307         }
3308         final Expression init = varNode.getInit();
3309         final IdentNode identNode = varNode.getName();
3310         final Symbol identSymbol = identNode.getSymbol();
3311         assert identSymbol != null : "variable node " + varNode + " requires a name with a symbol";
3312         final boolean needsScope = identSymbol.isScope();
3313 
3314         if (init == null) {
3315             // Block-scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ).
3316             // However, don't do this for CONST which always has an initializer except in the special case of
3317             // for-in/of loops, in which it is initialized in the loop header and should be left untouched here.
3318             if (needsScope && varNode.isLet()) {
3319                 method.loadCompilerConstant(SCOPE);
3320                 method.loadUndefined(Type.OBJECT);
3321                 final int flags = getScopeCallSiteFlags(identSymbol) | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
3322                 assert isFastScope(identSymbol);
3323                 storeFastScopeVar(identSymbol, flags);
3324             }
3325             return false;
3326         }
3327 
3328         enterStatement(varNode);
3329         assert method != null;
3330 
3331         if (needsScope) {
3332             method.loadCompilerConstant(SCOPE);
3333             loadExpressionUnbounded(init);
3334             // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
3335             final int flags = getScopeCallSiteFlags(identSymbol) | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
3336             if (isFastScope(identSymbol)) {
3337                 storeFastScopeVar(identSymbol, flags);
3338             } else {
3339                 method.dynamicSet(identNode.getName(), flags, false);
3340             }
3341         } else {




1736     }
1737 
1738     @Override
1739     public boolean enterBlockStatement(final BlockStatement blockStatement) {
1740         if(!method.isReachable()) {
1741             return false;
1742         }
1743         enterStatement(blockStatement);
1744 
1745         blockStatement.getBlock().accept(this);
1746 
1747         return false;
1748     }
1749 
1750     @Override
1751     public boolean enterForNode(final ForNode forNode) {
1752         if(!method.isReachable()) {
1753             return false;
1754         }
1755         enterStatement(forNode);
1756         if (forNode.isForInOrOf()) {
1757             enterForIn(forNode);
1758         } else {
1759             final Expression init = forNode.getInit();
1760             if (init != null) {
1761                 loadAndDiscard(init);
1762             }
1763             enterForOrWhile(forNode, forNode.getModify());
1764         }
1765 
1766         return false;
1767     }
1768 
1769     private void enterForIn(final ForNode forNode) {
1770         loadExpression(forNode.getModify(), TypeBounds.OBJECT);
1771         if (forNode.isForEach()) {
1772             method.invoke(ScriptRuntime.TO_VALUE_ITERATOR);
1773         } else if (forNode.isForIn()) {
1774             method.invoke(ScriptRuntime.TO_PROPERTY_ITERATOR);
1775         } else if (forNode.isForOf()) {
1776             method.invoke(ScriptRuntime.TO_ES6_ITERATOR);
1777         } else {
1778             throw new IllegalArgumentException("Unexpected for node");
1779         }
1780         final Symbol iterSymbol = forNode.getIterator();
1781         final int iterSlot = iterSymbol.getSlot(Type.OBJECT);
1782         method.store(iterSymbol, ITERATOR_TYPE);
1783 
1784         method.beforeJoinPoint(forNode);
1785 
1786         final Label continueLabel = forNode.getContinueLabel();
1787         final Label breakLabel    = forNode.getBreakLabel();
1788 
1789         method.label(continueLabel);
1790         method.load(ITERATOR_TYPE, iterSlot);
1791         method.invoke(interfaceCallNoLookup(ITERATOR_CLASS, "hasNext", boolean.class));
1792         final JoinPredecessorExpression test = forNode.getTest();
1793         final Block body = forNode.getBody();
1794         if(LocalVariableConversion.hasLiveConversion(test)) {
1795             final Label afterConversion = new Label("for_in_after_test_conv");
1796             method.ifne(afterConversion);
1797             method.beforeJoinPoint(test);
1798             method._goto(breakLabel);
1799             method.label(afterConversion);


3309     }
3310 
3311     @Override
3312     public boolean enterVarNode(final VarNode varNode) {
3313         if(!method.isReachable()) {
3314             return false;
3315         }
3316         final Expression init = varNode.getInit();
3317         final IdentNode identNode = varNode.getName();
3318         final Symbol identSymbol = identNode.getSymbol();
3319         assert identSymbol != null : "variable node " + varNode + " requires a name with a symbol";
3320         final boolean needsScope = identSymbol.isScope();
3321 
3322         if (init == null) {
3323             // Block-scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ).
3324             // However, don't do this for CONST which always has an initializer except in the special case of
3325             // for-in/of loops, in which it is initialized in the loop header and should be left untouched here.
3326             if (needsScope && varNode.isLet()) {
3327                 method.loadCompilerConstant(SCOPE);
3328                 method.loadUndefined(Type.OBJECT);
3329                 final int flags = getScopeCallSiteFlags(identSymbol) | CALLSITE_DECLARE;
3330                 assert isFastScope(identSymbol);
3331                 storeFastScopeVar(identSymbol, flags);
3332             }
3333             return false;
3334         }
3335 
3336         enterStatement(varNode);
3337         assert method != null;
3338 
3339         if (needsScope) {
3340             method.loadCompilerConstant(SCOPE);
3341             loadExpressionUnbounded(init);
3342             // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
3343             final int flags = getScopeCallSiteFlags(identSymbol) | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
3344             if (isFastScope(identSymbol)) {
3345                 storeFastScopeVar(identSymbol, flags);
3346             } else {
3347                 method.dynamicSet(identNode.getName(), flags, false);
3348             }
3349         } else {


< prev index next >