668
669 private MethodEmitter sharedScopeCall(final IdentNode identNode, final int flags) {
670 final Symbol symbol = identNode.getSymbol();
671 int scopeCallFlags = flags;
672 method.loadCompilerConstant(SCOPE);
673 if (isFastScope(symbol)) {
674 method.load(getScopeProtoDepth(currentBlock, symbol));
675 scopeCallFlags |= CALLSITE_FAST_SCOPE;
676 } else {
677 method.load(-1); // Bypass fast-scope code in shared callsite
678 }
679 loadArgs(args);
680 final Type[] paramTypes = method.getTypesFromStack(args.size());
681 final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol, identNode.getType(), callNodeType, paramTypes, scopeCallFlags);
682 return scopeCall.generateInvoke(method);
683 }
684
685 private void scopeCall(final IdentNode node, final int flags) {
686 load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
687 // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
688 method.loadNull(); //the 'this'
689 method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
690 }
691
692 private void evalCall(final IdentNode node, final int flags) {
693 load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
694
695 final Label not_eval = new Label("not_eval");
696 final Label eval_done = new Label("eval_done");
697
698 // check if this is the real built-in eval
699 method.dup();
700 globalIsEval();
701
702 method.ifeq(not_eval);
703 // We don't need ScriptFunction object for 'eval'
704 method.pop();
705
706 method.loadCompilerConstant(SCOPE); // Load up self (scope).
707
708 final CallNode.EvalArgs evalArgs = callNode.getEvalArgs();
801 public boolean enterIndexNode(final IndexNode node) {
802 load(node.getBase(), Type.OBJECT);
803 method.dup();
804 final Type indexType = node.getIndex().getType();
805 if (indexType.isObject() || indexType.isBoolean()) {
806 load(node.getIndex(), Type.OBJECT); //TODO
807 } else {
808 load(node.getIndex());
809 }
810 method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true);
811 method.swap();
812 method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags());
813
814 return false;
815 }
816
817 @Override
818 protected boolean enterDefault(final Node node) {
819 // Load up function.
820 load(function, Type.OBJECT); //TODO, e.g. booleans can be used as functions
821 method.loadNull(); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
822 method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
823
824 return false;
825 }
826 });
827
828 method.store(callNode.getSymbol());
829
830 return false;
831 }
832
833 @Override
834 public boolean enterContinueNode(final ContinueNode continueNode) {
835 lineNumber(continueNode);
836
837 final LoopNode continueTo = lc.getContinueTo(continueNode.getLabel());
838 for (int i = 0; i < lc.getScopeNestingLevelTo(continueTo); i++) {
839 closeWith();
840 }
841 method.splitAwareGoto(lc, continueTo.getContinueLabel());
|
668
669 private MethodEmitter sharedScopeCall(final IdentNode identNode, final int flags) {
670 final Symbol symbol = identNode.getSymbol();
671 int scopeCallFlags = flags;
672 method.loadCompilerConstant(SCOPE);
673 if (isFastScope(symbol)) {
674 method.load(getScopeProtoDepth(currentBlock, symbol));
675 scopeCallFlags |= CALLSITE_FAST_SCOPE;
676 } else {
677 method.load(-1); // Bypass fast-scope code in shared callsite
678 }
679 loadArgs(args);
680 final Type[] paramTypes = method.getTypesFromStack(args.size());
681 final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol, identNode.getType(), callNodeType, paramTypes, scopeCallFlags);
682 return scopeCall.generateInvoke(method);
683 }
684
685 private void scopeCall(final IdentNode node, final int flags) {
686 load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
687 // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
688 method.loadUndefined(Type.OBJECT); //the 'this' object
689 method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
690 }
691
692 private void evalCall(final IdentNode node, final int flags) {
693 load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
694
695 final Label not_eval = new Label("not_eval");
696 final Label eval_done = new Label("eval_done");
697
698 // check if this is the real built-in eval
699 method.dup();
700 globalIsEval();
701
702 method.ifeq(not_eval);
703 // We don't need ScriptFunction object for 'eval'
704 method.pop();
705
706 method.loadCompilerConstant(SCOPE); // Load up self (scope).
707
708 final CallNode.EvalArgs evalArgs = callNode.getEvalArgs();
801 public boolean enterIndexNode(final IndexNode node) {
802 load(node.getBase(), Type.OBJECT);
803 method.dup();
804 final Type indexType = node.getIndex().getType();
805 if (indexType.isObject() || indexType.isBoolean()) {
806 load(node.getIndex(), Type.OBJECT); //TODO
807 } else {
808 load(node.getIndex());
809 }
810 method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true);
811 method.swap();
812 method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags());
813
814 return false;
815 }
816
817 @Override
818 protected boolean enterDefault(final Node node) {
819 // Load up function.
820 load(function, Type.OBJECT); //TODO, e.g. booleans can be used as functions
821 method.loadUndefined(Type.OBJECT); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
822 method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
823
824 return false;
825 }
826 });
827
828 method.store(callNode.getSymbol());
829
830 return false;
831 }
832
833 @Override
834 public boolean enterContinueNode(final ContinueNode continueNode) {
835 lineNumber(continueNode);
836
837 final LoopNode continueTo = lc.getContinueTo(continueNode.getLabel());
838 for (int i = 0; i < lc.getScopeNestingLevelTo(continueTo); i++) {
839 closeWith();
840 }
841 method.splitAwareGoto(lc, continueTo.getContinueLabel());
|