void JSHTMLElement::pushEventHandlerScope(ExecState* exec, ScopeChain& scope) const { HTMLElement* element = impl(); // The document is put on first, fall back to searching it only after the element and form. scope.push(static_cast<JSObject*>(toJS(exec, element->ownerDocument()))); // The form is next, searched before the document, but after the element itself. if (HTMLFormElement* form = element->form()) scope.push(static_cast<JSObject*>(toJS(exec, form))); // The element is on top, searched first. scope.push(static_cast<JSObject*>(toJS(exec, element))); }
// ECMA 15.3.2 The Function Constructor JSObject *FunctionObjectImp::construct(ExecState *exec, const List &args, const Identifier &functionName, const UString &sourceURL, int lineNumber) { UString p(""); UString body; int argsSize = args.size(); if (argsSize == 0) { body = ""; } else if (argsSize == 1) { body = args[0]->toString(exec); } else { p = args[0]->toString(exec); for (int k = 1; k < argsSize - 1; k++) { p += "," + args[k]->toString(exec); } body = args[argsSize - 1]->toString(exec); } // parse the source code int sourceId; int errLine; UString errMsg; RefPtr<FunctionBodyNode> functionBody = parser().parseFunctionBody(sourceURL, lineNumber, body.data(), body.size(), &sourceId, &errLine, &errMsg); // notify debugger that source has been parsed Debugger *dbg = exec->dynamicInterpreter()->debugger(); if (dbg) { // make sure to pass in sourceURL, since it's useful for lazy event listeners, and empty for actual function ctor dbg->reportSourceParsed(exec, functionBody.get(), sourceId, sourceURL, body, lineNumber, errLine, errMsg); } // no program node == syntax error - throw a syntax error if (!functionBody) // we can't return a Completion(Throw) here, so just set the exception // and return it { return throwError(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL); } ScopeChain scopeChain; scopeChain.push(exec->lexicalInterpreter()->globalObject()); FunctionImp *fimp = new FunctionImp(exec, functionName, functionBody.get(), scopeChain); // parse parameter list. throw syntax error on illegal identifiers int len = p.size(); const UChar *c = p.data(); int i = 0, params = 0; UString param; while (i < len) { while (*c == ' ' && i < len) { c++, i++; } if (Lexer::isIdentStart(c->uc)) { // else error param = UString(c, 1); c++, i++; while (i < len && (Lexer::isIdentPart(c->uc))) { param += UString(c, 1); c++, i++; } while (i < len && *c == ' ') { c++, i++; } if (i == len) { functionBody->addParam(Identifier(param)); params++; break; } else if (*c == ',') { functionBody->addParam(Identifier(param)); params++; c++, i++; continue; } // else error } return throwError(exec, SyntaxError, "Syntax error in parameter list"); } List consArgs; JSObject *objCons = exec->lexicalInterpreter()->builtinObject(); JSObject *prototype = objCons->construct(exec, List::empty()); prototype->put(exec, exec->propertyNames().constructor, fimp, DontEnum | DontDelete | ReadOnly); // ECMA Edition 5.1r6 - 15.3.5.2 - [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false fimp->put(exec, exec->propertyNames().prototype, prototype, Internal | DontDelete | DontEnum); return fimp; }