< prev index next >

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

Print this page




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








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) | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
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 {




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


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


< prev index next >