< prev index next >

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

Print this page




1593 
1594                 //call nodes have program points.
1595 
1596                 final int flags = getCallSiteFlags() | (callNode.isApplyToCall() ? CALLSITE_APPLY_TO_CALL : 0);
1597 
1598                 new OptimisticOperation(callNode, resultBounds) {
1599                     int argCount;
1600                     @Override
1601                     void loadStack() {
1602                         loadExpressionAsObject(node.getBase());
1603                         method.dup();
1604                         // NOTE: not using a nested OptimisticOperation on this dynamicGet, as we expect to get back
1605                         // a callable object. Nobody in their right mind would optimistically type this call site.
1606                         assert !node.isOptimistic();
1607                         method.dynamicGet(node.getType(), node.getProperty(), flags, true, node.isIndex());
1608                         method.swap();
1609                         argCount = loadArgs(args);
1610                     }
1611                     @Override
1612                     void consumeStack() {
1613                         dynamicCall(2 + argCount, flags, node.getProperty());
1614                     }
1615                 }.emit();
1616 
1617                 return false;
1618             }
1619 
1620             @Override
1621             public boolean enterFunctionNode(final FunctionNode origCallee) {
1622                 new OptimisticOperation(callNode, resultBounds) {
1623                     FunctionNode callee;
1624                     int argsCount;
1625                     @Override
1626                     void loadStack() {
1627                         callee = (FunctionNode)origCallee.accept(CodeGenerator.this);
1628                         if (callee.isStrict()) { // "this" is undefined
1629                             method.loadUndefined(Type.OBJECT);
1630                         } else { // get global from scope (which is the self)
1631                             globalInstance();
1632                         }
1633                         argsCount = loadArgs(args);
1634                     }
1635 
1636                     @Override
1637                     void consumeStack() {
1638                         final int flags = getCallSiteFlags();
1639                         //assert callNodeType.equals(callee.getReturnType()) : callNodeType + " != " + callee.getReturnType();
1640                         dynamicCall(2 + argsCount, flags, origCallee.getName());
1641                     }
1642                 }.emit();
1643                 return false;
1644             }
1645 
1646             @Override
1647             public boolean enterIndexNode(final IndexNode node) {
1648                 new OptimisticOperation(callNode, resultBounds) {
1649                     int argsCount;
1650                     @Override
1651                     void loadStack() {
1652                         loadExpressionAsObject(node.getBase());
1653                         method.dup();
1654                         final Type indexType = node.getIndex().getType();
1655                         if (indexType.isObject() || indexType.isBoolean()) {
1656                             loadExpressionAsObject(node.getIndex()); //TODO boolean
1657                         } else {
1658                             loadExpressionUnbounded(node.getIndex());
1659                         }
1660                         // NOTE: not using a nested OptimisticOperation on this dynamicGetIndex, as we expect to get
1661                         // back a callable object. Nobody in their right mind would optimistically type this call site.
1662                         assert !node.isOptimistic();
1663                         method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true);
1664                         method.swap();
1665                         argsCount = loadArgs(args);
1666                     }
1667                     @Override
1668                     void consumeStack() {
1669                         final int flags = getCallSiteFlags();
1670                         dynamicCall(2 + argsCount, flags, null);
1671                     }
1672                 }.emit();
1673                 return false;
1674             }
1675 
1676             @Override
1677             protected boolean enterDefault(final Node node) {
1678                 new OptimisticOperation(callNode, resultBounds) {
1679                     int argsCount;
1680                     @Override
1681                     void loadStack() {
1682                         // Load up function.
1683                         loadExpressionAsObject(function); //TODO, e.g. booleans can be used as functions
1684                         method.loadUndefined(Type.OBJECT); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
1685                         argsCount = loadArgs(args);
1686                         }
1687                         @Override
1688                         void consumeStack() {
1689                             final int flags = getCallSiteFlags() | CALLSITE_SCOPE;
1690                             dynamicCall(2 + argsCount, flags, null);
1691                         }
1692                 }.emit();
1693                 return false;
1694             }
1695         });
1696 
1697         return false;
1698     }
1699 
1700     /**
1701      * Returns the flags with optimistic flag and program point removed.
1702      * @param flags the flags that need optimism stripped from them.
1703      * @return flags without optimism
1704      */
1705     static int nonOptimisticFlags(final int flags) {
1706         return flags & ~(CALLSITE_OPTIMISTIC | -1 << CALLSITE_PROGRAM_POINT_SHIFT);
1707     }
1708 
1709     @Override
1710     public boolean enterContinueNode(final ContinueNode continueNode) {


3694      * @param discard if true, the expression is loaded and discarded
3695      * @param expr the expression that's either normally loaded or discard-loaded
3696      * @param resultBounds result bounds for when loading the expression normally
3697      */
3698     private void loadMaybeDiscard(final boolean discard, final Expression expr, final TypeBounds resultBounds) {
3699         if (discard) {
3700             loadAndDiscard(expr);
3701         } else {
3702             loadExpression(expr, resultBounds);
3703         }
3704     }
3705 
3706     private void loadNEW(final UnaryNode unaryNode) {
3707         final CallNode callNode = (CallNode)unaryNode.getExpression();
3708         final List<Expression> args   = callNode.getArgs();
3709 
3710         final Expression func = callNode.getFunction();
3711         // Load function reference.
3712         loadExpressionAsObject(func); // must detect type error
3713 
3714         method.dynamicNew(1 + loadArgs(args), getCallSiteFlags(),
3715             func instanceof IdentNode? ((IdentNode)func).getName() : null);
3716     }
3717 
3718     private void loadNOT(final UnaryNode unaryNode) {
3719         final Expression expr = unaryNode.getExpression();
3720         if(expr instanceof UnaryNode && expr.isTokenType(TokenType.NOT)) {
3721             // !!x is idiomatic boolean cast in JavaScript
3722             loadExpressionAsBoolean(((UnaryNode)expr).getExpression());
3723         } else {
3724             final Label trueLabel  = new Label("true");
3725             final Label afterLabel = new Label("after");
3726 
3727             emitBranch(expr, trueLabel, true);
3728             method.load(true);
3729             method._goto(afterLabel);
3730             method.label(trueLabel);
3731             method.load(false);
3732             method.label(afterLabel);
3733         }
3734     }
3735 




1593 
1594                 //call nodes have program points.
1595 
1596                 final int flags = getCallSiteFlags() | (callNode.isApplyToCall() ? CALLSITE_APPLY_TO_CALL : 0);
1597 
1598                 new OptimisticOperation(callNode, resultBounds) {
1599                     int argCount;
1600                     @Override
1601                     void loadStack() {
1602                         loadExpressionAsObject(node.getBase());
1603                         method.dup();
1604                         // NOTE: not using a nested OptimisticOperation on this dynamicGet, as we expect to get back
1605                         // a callable object. Nobody in their right mind would optimistically type this call site.
1606                         assert !node.isOptimistic();
1607                         method.dynamicGet(node.getType(), node.getProperty(), flags, true, node.isIndex());
1608                         method.swap();
1609                         argCount = loadArgs(args);
1610                     }
1611                     @Override
1612                     void consumeStack() {
1613                         dynamicCall(2 + argCount, flags, node.toString(false));
1614                     }
1615                 }.emit();
1616 
1617                 return false;
1618             }
1619 
1620             @Override
1621             public boolean enterFunctionNode(final FunctionNode origCallee) {
1622                 new OptimisticOperation(callNode, resultBounds) {
1623                     FunctionNode callee;
1624                     int argsCount;
1625                     @Override
1626                     void loadStack() {
1627                         callee = (FunctionNode)origCallee.accept(CodeGenerator.this);
1628                         if (callee.isStrict()) { // "this" is undefined
1629                             method.loadUndefined(Type.OBJECT);
1630                         } else { // get global from scope (which is the self)
1631                             globalInstance();
1632                         }
1633                         argsCount = loadArgs(args);
1634                     }
1635 
1636                     @Override
1637                     void consumeStack() {
1638                         dynamicCall(2 + argsCount, getCallSiteFlags(), origCallee.getName());


1639                     }
1640                 }.emit();
1641                 return false;
1642             }
1643 
1644             @Override
1645             public boolean enterIndexNode(final IndexNode node) {
1646                 new OptimisticOperation(callNode, resultBounds) {
1647                     int argsCount;
1648                     @Override
1649                     void loadStack() {
1650                         loadExpressionAsObject(node.getBase());
1651                         method.dup();
1652                         final Type indexType = node.getIndex().getType();
1653                         if (indexType.isObject() || indexType.isBoolean()) {
1654                             loadExpressionAsObject(node.getIndex()); //TODO boolean
1655                         } else {
1656                             loadExpressionUnbounded(node.getIndex());
1657                         }
1658                         // NOTE: not using a nested OptimisticOperation on this dynamicGetIndex, as we expect to get
1659                         // back a callable object. Nobody in their right mind would optimistically type this call site.
1660                         assert !node.isOptimistic();
1661                         method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true);
1662                         method.swap();
1663                         argsCount = loadArgs(args);
1664                     }
1665                     @Override
1666                     void consumeStack() {
1667                         dynamicCall(2 + argsCount, getCallSiteFlags(), node.toString(false));

1668                     }
1669                 }.emit();
1670                 return false;
1671             }
1672 
1673             @Override
1674             protected boolean enterDefault(final Node node) {
1675                 new OptimisticOperation(callNode, resultBounds) {
1676                     int argsCount;
1677                     @Override
1678                     void loadStack() {
1679                         // Load up function.
1680                         loadExpressionAsObject(function); //TODO, e.g. booleans can be used as functions
1681                         method.loadUndefined(Type.OBJECT); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
1682                         argsCount = loadArgs(args);
1683                         }
1684                         @Override
1685                         void consumeStack() {
1686                             final int flags = getCallSiteFlags() | CALLSITE_SCOPE;
1687                             dynamicCall(2 + argsCount, flags, node.toString(false));
1688                         }
1689                 }.emit();
1690                 return false;
1691             }
1692         });
1693 
1694         return false;
1695     }
1696 
1697     /**
1698      * Returns the flags with optimistic flag and program point removed.
1699      * @param flags the flags that need optimism stripped from them.
1700      * @return flags without optimism
1701      */
1702     static int nonOptimisticFlags(final int flags) {
1703         return flags & ~(CALLSITE_OPTIMISTIC | -1 << CALLSITE_PROGRAM_POINT_SHIFT);
1704     }
1705 
1706     @Override
1707     public boolean enterContinueNode(final ContinueNode continueNode) {


3691      * @param discard if true, the expression is loaded and discarded
3692      * @param expr the expression that's either normally loaded or discard-loaded
3693      * @param resultBounds result bounds for when loading the expression normally
3694      */
3695     private void loadMaybeDiscard(final boolean discard, final Expression expr, final TypeBounds resultBounds) {
3696         if (discard) {
3697             loadAndDiscard(expr);
3698         } else {
3699             loadExpression(expr, resultBounds);
3700         }
3701     }
3702 
3703     private void loadNEW(final UnaryNode unaryNode) {
3704         final CallNode callNode = (CallNode)unaryNode.getExpression();
3705         final List<Expression> args   = callNode.getArgs();
3706 
3707         final Expression func = callNode.getFunction();
3708         // Load function reference.
3709         loadExpressionAsObject(func); // must detect type error
3710 
3711         method.dynamicNew(1 + loadArgs(args), getCallSiteFlags(), func.toString(false));

3712     }
3713 
3714     private void loadNOT(final UnaryNode unaryNode) {
3715         final Expression expr = unaryNode.getExpression();
3716         if(expr instanceof UnaryNode && expr.isTokenType(TokenType.NOT)) {
3717             // !!x is idiomatic boolean cast in JavaScript
3718             loadExpressionAsBoolean(((UnaryNode)expr).getExpression());
3719         } else {
3720             final Label trueLabel  = new Label("true");
3721             final Label afterLabel = new Label("after");
3722 
3723             emitBranch(expr, trueLabel, true);
3724             method.load(true);
3725             method._goto(afterLabel);
3726             method.label(trueLabel);
3727             method.load(false);
3728             method.label(afterLabel);
3729         }
3730     }
3731 


< prev index next >