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)));
}
Exemplo n.º 2
0
// 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;
}