internal Node initFunction(FunctionNode fnNode, int functionIndex, Node statements, int functionType) { fnNode.itsFunctionType = functionType; fnNode.addChildToBack (statements); int functionCount = fnNode.FunctionCount; if (functionCount != 0) { // Functions containing other functions require activation objects fnNode.itsNeedsActivation = true; for (int i = 0; i != functionCount; ++i) { FunctionNode fn = fnNode.getFunctionNode (i); // nested function expression statements overrides var if (fn.FunctionType == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) { string name = fn.FunctionName; if (name != null && name.Length != 0) { fnNode.removeParamOrVar (name); } } } } if (functionType == FunctionNode.FUNCTION_EXPRESSION) { string name = fnNode.FunctionName; if (name != null && name.Length != 0 && !fnNode.hasParamOrVar (name)) { // A function expression needs to have its name as a // variable (if it isn't already allocated as a variable). // See ECMA Ch. 13. We add code to the beginning of the // function to initialize a local variable of the // function's name to the function value. fnNode.addVar (name); Node setFn = new Node (Token.EXPR_VOID, new Node (Token.SETNAME, Node.newString (Token.BINDNAME, name), new Node (Token.THISFN))); statements.addChildrenToFront (setFn); } } // Add return to end if needed. Node lastStmt = statements.LastChild; if (lastStmt == null || lastStmt.Type != Token.RETURN) { statements.addChildToBack (new Node (Token.RETURN)); } Node result = Node.newString (Token.FUNCTION, fnNode.FunctionName); result.putIntProp (Node.FUNCTION_PROP, functionIndex); return result; }