648 final boolean isVarArg = callee.isVarArg(); |
648 final boolean isVarArg = callee.isVarArg(); |
649 final int argCount = isVarArg ? -1 : callee.getParameters().size(); |
649 final int argCount = isVarArg ? -1 : callee.getParameters().size(); |
650 |
650 |
651 final String signature = new FunctionSignature(true, callee.needsCallee(), callee.getReturnType(), isVarArg ? null : callee.getParameters()).toString(); |
651 final String signature = new FunctionSignature(true, callee.needsCallee(), callee.getReturnType(), isVarArg ? null : callee.getParameters()).toString(); |
652 |
652 |
|
653 if (callee.needsCallee()) { |
|
654 new FunctionObjectCreator(CodeGenerator.this, callee).makeObject(method); |
|
655 } |
|
656 |
653 if (callee.isStrictMode()) { // self is undefined |
657 if (callee.isStrictMode()) { // self is undefined |
654 method.loadUndefined(Type.OBJECT); |
658 method.loadUndefined(Type.OBJECT); |
655 } else { // get global from scope (which is the self) |
659 } else { // get global from scope (which is the self) |
656 globalInstance(); |
660 globalInstance(); |
657 } |
|
658 |
|
659 if (callee.needsCallee()) { // TODO: always true |
|
660 new FunctionObjectCreator(CodeGenerator.this, callee).makeObject(method); // TODO: if callee not needed, function object is used only to pass scope (could be optimized). if neither the scope nor the function object is needed by the callee, we can pass null instead. |
|
661 } |
661 } |
662 |
662 |
663 loadArgs(args, signature, isVarArg, argCount); |
663 loadArgs(args, signature, isVarArg, argCount); |
664 method.invokeStatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature); |
664 method.invokeStatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature); |
665 assert method.peekType().equals(callee.getReturnType()) : method.peekType() + " != " + callee.getReturnType(); |
665 assert method.peekType().equals(callee.getReturnType()) : method.peekType() + " != " + callee.getReturnType(); |
1644 final String name = splitNode.getName(); |
1644 final String name = splitNode.getName(); |
1645 |
1645 |
1646 final Class<?> rtype = fn.getReturnType().getTypeClass(); |
1646 final Class<?> rtype = fn.getReturnType().getTypeClass(); |
1647 final boolean needsArguments = fn.needsArguments(); |
1647 final boolean needsArguments = fn.needsArguments(); |
1648 final Class<?>[] ptypes = needsArguments ? |
1648 final Class<?>[] ptypes = needsArguments ? |
1649 new Class<?>[] {Object.class, ScriptFunction.class, ScriptObject.class, Object.class} : |
1649 new Class<?>[] {ScriptFunction.class, Object.class, ScriptObject.class, Object.class} : |
1650 new Class<?>[] {Object.class, ScriptFunction.class, ScriptObject.class}; |
1650 new Class<?>[] {ScriptFunction.class, Object.class, ScriptObject.class}; |
1651 |
1651 |
1652 setCurrentCompileUnit(splitCompileUnit); |
1652 setCurrentCompileUnit(splitCompileUnit); |
1653 splitNode.setCompileUnit(splitCompileUnit); |
1653 splitNode.setCompileUnit(splitCompileUnit); |
1654 |
1654 |
1655 final Call splitCall = staticCallNoLookup( |
1655 final Call splitCall = staticCallNoLookup( |
1667 method.setFunctionNode(fn); |
1667 method.setFunctionNode(fn); |
1668 method.setSplitNode(splitNode); |
1668 method.setSplitNode(splitNode); |
1669 splitNode.setMethodEmitter(method); |
1669 splitNode.setMethodEmitter(method); |
1670 |
1670 |
1671 final MethodEmitter caller = splitNode.getCaller(); |
1671 final MethodEmitter caller = splitNode.getCaller(); |
1672 caller.loadThis(); |
|
1673 if(fn.needsCallee()) { |
1672 if(fn.needsCallee()) { |
1674 caller.loadCallee(); |
1673 caller.loadCallee(); |
1675 } else { |
1674 } else { |
1676 caller.loadNull(); |
1675 caller.loadNull(); |
1677 } |
1676 } |
|
1677 caller.loadThis(); |
1678 caller.loadScope(); |
1678 caller.loadScope(); |
1679 if (needsArguments) { |
1679 if (needsArguments) { |
1680 caller.loadArguments(); |
1680 caller.loadArguments(); |
1681 } |
1681 } |
1682 caller.invoke(splitCall); |
1682 caller.invoke(splitCall); |