bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error)
{
    ASSERT(m_callback);
    ASSERT(m_frame);
        
    if (!m_frame->script()->isEnabled())
        return true;
        
    JSGlobalObject* globalObject = m_frame->script()->globalObject();
    ExecState* exec = globalObject->globalExec();
        
    KJS::JSLock lock;
        
    JSValue* handleEventFunction = m_callback->get(exec, Identifier(exec, "handleEvent"));
    CallData handleEventCallData;
    CallType handleEventCallType = handleEventFunction->getCallData(handleEventCallData);
    CallData callbackCallData;
    CallType callbackCallType = CallTypeNone;

    if (handleEventCallType == CallTypeNone) {
        callbackCallType = m_callback->getCallData(callbackCallData);
        if (callbackCallType == CallTypeNone) {
            // FIXME: Should an exception be thrown here?
            return true;
        }
    }
        
    RefPtr<JSCustomSQLStatementErrorCallback> protect(this);
        
    ArgList args;
    args.append(toJS(exec, transaction));
    args.append(toJS(exec, error));
        
    JSValue* result;
    globalObject->startTimeoutCheck();
    if (handleEventCallType != CallTypeNone)
        result = call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_callback, args);
    else
        result = call(exec, m_callback, callbackCallType, callbackCallData, m_callback, args);
    globalObject->stopTimeoutCheck();
        
    if (exec->hadException()) {
        JSObject* exception = exec->exception()->toObject(exec);
        String message = exception->get(exec, exec->propertyNames().message)->toString(exec);
        int lineNumber = exception->get(exec, Identifier(exec, "line"))->toInt32(exec);
        String sourceURL = exception->get(exec, Identifier(exec, "sourceURL"))->toString(exec);
        m_frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL);
        exec->clearException();
            
        // The spec says:
        // "If the error callback returns false, then move on to the next statement..."
        // "Otherwise, the error callback did not return false, or there was no error callback"
        // Therefore an exception and returning true are the same thing - so, return true on an exception
        return true;
    }
        
    Document::updateDocumentsRendering();

    return result->toBoolean(exec);
}
bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error)
{
    ASSERT(m_callback);
    ASSERT(m_frame);
        
    if (!m_frame->script()->isEnabled())
        return true;
        
    JSGlobalObject* globalObject = m_frame->script()->globalObject();
    ExecState* exec = globalObject->globalExec();
        
    JSC::JSLock lock(false);
        
    JSValue* handleEventFunction = m_callback->get(exec, Identifier(exec, "handleEvent"));
    CallData handleEventCallData;
    CallType handleEventCallType = handleEventFunction->getCallData(handleEventCallData);
    CallData callbackCallData;
    CallType callbackCallType = CallTypeNone;

    if (handleEventCallType == CallTypeNone) {
        callbackCallType = m_callback->getCallData(callbackCallData);
        if (callbackCallType == CallTypeNone) {
            // FIXME: Should an exception be thrown here?
            return true;
        }
    }
        
    RefPtr<JSCustomSQLStatementErrorCallback> protect(this);
        
    ArgList args;
    args.append(toJS(exec, transaction));
    args.append(toJS(exec, error));
        
    JSValue* result;
    globalObject->startTimeoutCheck();
    if (handleEventCallType != CallTypeNone)
        result = call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_callback, args);
    else
        result = call(exec, m_callback, callbackCallType, callbackCallData, m_callback, args);
    globalObject->stopTimeoutCheck();
        
    if (exec->hadException()) {
        reportCurrentException(exec);
            
        // The spec says:
        // "If the error callback returns false, then move on to the next statement..."
        // "Otherwise, the error callback did not return false, or there was no error callback"
        // Therefore an exception and returning true are the same thing - so, return true on an exception
        return true;
    }
        
    Document::updateDocumentsRendering();

    return result->toBoolean(exec);
}
Example #3
0
JSObject* Error::create(ExecState* exec, ErrorType type, const UString& message, int lineNumber, int sourceId, const UString& sourceURL)
{
    JSObject* constructor;
    const char* name;
    switch (type) {
        case EvalError:
            constructor = exec->lexicalGlobalObject()->evalErrorConstructor();
            name = "Evaluation error";
            break;
        case RangeError:
            constructor = exec->lexicalGlobalObject()->rangeErrorConstructor();
            name = "Range error";
            break;
        case ReferenceError:
            constructor = exec->lexicalGlobalObject()->referenceErrorConstructor();
            name = "Reference error";
            break;
        case SyntaxError:
            constructor = exec->lexicalGlobalObject()->syntaxErrorConstructor();
            name = "Syntax error";
            break;
        case TypeError:
            constructor = exec->lexicalGlobalObject()->typeErrorConstructor();
            name = "Type error";
            break;
        case URIError:
            constructor = exec->lexicalGlobalObject()->URIErrorConstructor();
            name = "URI error";
            break;
        default:
            constructor = exec->lexicalGlobalObject()->errorConstructor();
            name = "Error";
            break;
    }

    ArgList args;
    if (message.isEmpty())
        args.append(jsString(exec, name));
    else
        args.append(jsString(exec, message));
    ConstructData constructData;
    ConstructType constructType = constructor->getConstructData(constructData);
    JSObject* error = construct(exec, constructor, constructType, constructData, args);

    if (lineNumber != -1)
        error->putWithAttributes(exec, Identifier(exec, "line"), jsNumber(exec, lineNumber), ReadOnly | DontDelete);
    if (sourceId != -1)
        error->putWithAttributes(exec, Identifier(exec, "sourceId"), jsNumber(exec, sourceId), ReadOnly | DontDelete);
    if (!sourceURL.isNull())
        error->putWithAttributes(exec, Identifier(exec, "sourceURL"), jsString(exec, sourceURL), ReadOnly | DontDelete);

    return error;
}
Example #4
0
void JSLazyEventListener::parseCode() const
{
    if (m_parsed)
        return;
    m_parsed = true;

    Frame* frame = window()->impl()->frame();
    if (frame && frame->script()->isEnabled()) {
        ExecState* exec = window()->globalExec();

        JSLock lock(false);
        ArgList args;

        UString sourceURL(frame->loader()->url().string());
        args.append(eventParameterName());
        args.append(jsString(exec, m_code));

        // FIXME: Passing the document's URL to construct is not always correct, since this event listener might
        // have been added with setAttribute from a script, and we should pass String() in that case.
        m_listener = constructFunction(exec, args, Identifier(exec, m_functionName), sourceURL, m_lineNumber); // FIXME: is globalExec ok?

        JSFunction* listenerAsFunction = static_cast<JSFunction*>(m_listener.get());

        if (exec->hadException()) {
            exec->clearException();

            // failed to parse, so let's just make this listener a no-op
            m_listener = 0;
        } else if (m_originalNode) {
            // Add the event's home element to the scope
            // (and the document, and the form - see JSHTMLElement::eventHandlerScope)
            ScopeChain scope = listenerAsFunction->scope();

            JSValue* thisObj = toJS(exec, m_originalNode);
            if (thisObj->isObject()) {
                static_cast<JSEventTargetNode*>(thisObj)->pushEventHandlerScope(exec, scope);
                listenerAsFunction->setScope(scope);
            }
        }
    }

    // no more need to keep the unparsed code around
    m_functionName = String();
    m_code = String();

    if (m_listener) {
        JSDOMWindow::ListenersMap& listeners = isHTMLEventListener()
            ? window()->jsHTMLEventListeners() : window()->jsEventListeners();
        listeners.set(m_listener, const_cast<JSLazyEventListener*>(this));
    }
}
Example #5
0
JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    JSLock lock;
    ExecState* exec = toJS(ctx);
    JSObject* jsObject = toJS(object);
    JSObject* jsThisObject = toJS(thisObject);

    if (!jsThisObject)
        jsThisObject = exec->globalThisValue();

    ArgList argList;
    for (size_t i = 0; i < argumentCount; i++)
        argList.append(toJS(arguments[i]));

    CallData callData;
    CallType callType = jsObject->getCallData(callData);
    if (callType == CallTypeNone)
        return 0;

    JSValueRef result = toRef(call(exec, jsObject, callType, callData, jsThisObject, argList));
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec->exception());
        exec->clearException();
        result = 0;
    }
    return result;
}
Example #6
0
JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[],  JSValueRef* exception)
{
    ExecState* exec = toJS(ctx);
    exec->globalData().heap.registerThread();
    JSLock lock(exec);

    JSObject* result;
    if (argumentCount) {
        ArgList argList;
        for (size_t i = 0; i < argumentCount; ++i)
            argList.append(toJS(arguments[i]));

        result = constructArray(exec, argList);
    } else
        result = constructEmptyArray(exec);

    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec->exception());
        exec->clearException();
        result = 0;
    }

    return toRef(result);
}
Example #7
0
JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
    ExecState* exec = toJS(ctx);
    exec->globalData().heap->registerThread();
    JSLock lock(exec);

    JSObject* jsObject = toJS(object);

    ConstructData constructData;
    ConstructType constructType = jsObject->getConstructData(constructData);
    if (constructType == ConstructTypeNone)
        return 0;

    ArgList argList;
    for (size_t i = 0; i < argumentCount; i++)
        argList.append(toJS(arguments[i]));
    JSObjectRef result = toRef(construct(exec, jsObject, constructType, constructData, argList));
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec->exception());
        exec->clearException();
        result = 0;
    }
    return result;
}
short JSNodeFilterCondition::acceptNode(Node* filterNode, JSValue*& exception) const
{
    // FIXME: It makes no sense for this to depend on the document being in a frame!
    Frame* frame = filterNode->document()->frame();
    if (!frame)
        return NodeFilter::FILTER_REJECT;

    JSLock lock;

    CallData callData;
    CallType callType = m_filter->getCallData(callData);
    if (callType == CallTypeNone)
        return NodeFilter::FILTER_ACCEPT;

    ExecState* exec = frame->script()->globalObject()->globalExec();
    ArgList args;
    args.append(toJS(exec, filterNode));
    if (exec->hadException()) {
        exception = takeException(exec);
        return NodeFilter::FILTER_REJECT;
    }
    JSValue* result = call(exec, m_filter, callType, callData, m_filter, args);
    if (exec->hadException()) {
        exception = takeException(exec);
        return NodeFilter::FILTER_REJECT;
    }
    int intResult = result->toInt32(exec);
    if (exec->hadException()) {
        exception = takeException(exec);
        return NodeFilter::FILTER_REJECT;
    }
    return intResult;
}
void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
{
    ASSERT(m_callback);
    ASSERT(m_frame);
        
    if (!m_frame->script()->isEnabled())
        return;

    JSGlobalObject* globalObject = m_frame->script()->globalObject();
    ExecState* exec = globalObject->globalExec();
        
    JSC::JSLock lock(false);

    JSValuePtr function = m_callback->get(exec, Identifier(exec, "handleEvent"));
    CallData callData;
    CallType callType = function.getCallData(callData);
    if (callType == CallTypeNone) {
        callType = m_callback->getCallData(callData);
        if (callType == CallTypeNone) {
            // FIXME: Should an exception be thrown here?
            return;
        }
        function = m_callback;
    }

    RefPtr<JSCustomSQLStatementCallback> protect(this);

    ArgList args;
    args.append(toJS(exec, transaction));
    args.append(toJS(exec, resultSet));
        
    globalObject->startTimeoutCheck();
    call(exec, function, callType, callData, m_callback, args);
    globalObject->stopTimeoutCheck();

    if (exec->hadException()) {
        reportCurrentException(exec);

        raisedException = true;
    }

    Document::updateDocumentsRendering();
}
Example #10
0
JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
    ExecState* exec = toJS(ctx);
    exec->globalData().heap->registerThread();
    JSLock lock(exec);

    Identifier nameID = name ? name->identifier(exec) : Identifier(exec, "anonymous");
    
    ArgList args;
    for (unsigned i = 0; i < parameterCount; i++)
        args.append(jsString(exec, parameterNames[i]->ustring()));
    args.append(jsString(exec, body->ustring()));

    JSObject* result = constructFunction(exec, args, nameID, sourceURL->ustring(), startingLineNumber);
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec->exception());
        exec->clearException();
        result = 0;
    }
    return toRef(result);
}
Example #11
0
JSValue* stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    UString s = thisValue->toThisString(exec);

    JSValue* a0 = args.at(exec, 0);

    UString u = s;
    RefPtr<RegExp> reg;
    RegExpObject* imp = 0;
    if (a0->isObject() && static_cast<JSObject *>(a0)->inherits(&RegExpObject::info))
        reg = static_cast<RegExpObject *>(a0)->regExp();
    else {
        /*
         *  ECMA 15.5.4.12 String.prototype.search (regexp)
         *  If regexp is not an object whose [[Class]] property is "RegExp", it is
         *  replaced with the result of the expression new RegExp(regexp).
         */
        reg = RegExp::create(exec, a0->toString(exec));
    }
    RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();
    int pos;
    int matchLength;
    regExpObj->performMatch(reg.get(), u, 0, pos, matchLength);
    if (!(reg->global())) {
        // case without 'g' flag is handled like RegExp.prototype.exec
        if (pos < 0)
            return jsNull();
        return regExpObj->arrayOfMatches(exec);
    }

    // return array of matches
    ArgList list;
    int lastIndex = 0;
    while (pos >= 0) {
        list.append(jsSubstring(exec, u, pos, matchLength));
        lastIndex = pos;
        pos += matchLength == 0 ? 1 : matchLength;
        regExpObj->performMatch(reg.get(), u, pos, pos, matchLength);
    }
    if (imp)
        imp->setLastIndex(lastIndex);
    if (list.isEmpty()) {
        // if there are no matches at all, it's important to return
        // Null instead of an empty array, because this matches
        // other browsers and because Null is a false value.
        return jsNull();
    }

    return constructArray(exec, list);
}
Example #12
0
    int compare_key_key(key va, key vb)
    {
        ASSERT(!va->isUndefined());
        ASSERT(!vb->isUndefined());

        if (m_exec->hadException())
            return 1;

        ArgList arguments;
        arguments.append(va);
        arguments.append(vb);
        double compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments)->toNumber(m_exec);
        return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent.
    }
JSValuePtr JSClipboard::types(ExecState* exec) const
{
    Clipboard* clipboard = impl();

    HashSet<String> types = clipboard->types();
    if (types.isEmpty())
        return jsNull();

    ArgList list;
    HashSet<String>::const_iterator end = types.end();
    for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it)
        list.append(jsString(exec, UString(*it)));
    return constructArray(exec, list);
}
Example #14
0
JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
    JSLock lock;
    
    ExecState* exec = toJS(ctx);
    UString::Rep* bodyRep = toJS(body);
    UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
    
    Identifier nameID = name ? Identifier(exec, toJS(name)) : Identifier(exec, "anonymous");
    
    ArgList args;
    for (unsigned i = 0; i < parameterCount; i++)
        args.append(jsString(exec, UString(toJS(parameterNames[i]))));
    args.append(jsString(exec, UString(bodyRep)));

    JSObject* result = constructFunction(exec, args, nameID, UString(sourceURLRep), startingLineNumber);
    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec->exception());
        exec->clearException();
        result = 0;
    }
    return toRef(result);
}
void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bool& raisedException)
{
    ASSERT(m_data);
    ASSERT(m_data->callback());
    ASSERT(m_data->frame());

    if (!m_data->frame()->script()->isEnabled())
        return;

    JSGlobalObject* globalObject = m_data->frame()->script()->globalObject();
    ExecState* exec = globalObject->globalExec();

    JSC::JSLock lock(false);

    JSValue* handleEventFunction = m_data->callback()->get(exec, Identifier(exec, "handleEvent"));
    CallData handleEventCallData;
    CallType handleEventCallType = handleEventFunction->getCallData(handleEventCallData);
    CallData callbackCallData;
    CallType callbackCallType = CallTypeNone;

    if (handleEventCallType == CallTypeNone) {
        callbackCallType = m_data->callback()->getCallData(callbackCallData);
        if (callbackCallType == CallTypeNone) {
            // FIXME: Should an exception be thrown here?
            return;
        }
    }

    RefPtr<JSCustomSQLTransactionCallback> protect(this);

    ArgList args;
    args.append(toJS(exec, transaction));

    globalObject->startTimeoutCheck();
    if (handleEventCallType != CallTypeNone)
        call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_data->callback(), args);
    else
        call(exec, m_data->callback(), callbackCallType, callbackCallData, m_data->callback(), args);
    globalObject->stopTimeoutCheck();

    if (exec->hadException()) {
        m_data->frame()->domWindow()->console()->reportCurrentException(exec);

        raisedException = true;
    }

    Document::updateDocumentsRendering();
}
String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
{
    ASSERT(m_customResolver);

    if (!m_frame)
        return String();
    if (!m_frame->script()->isEnabled())
        return String();

    JSLock lock(false);

    JSGlobalObject* globalObject = m_frame->script()->globalObject();
    ExecState* exec = globalObject->globalExec();
        
    JSValue* function = m_customResolver->get(exec, Identifier(exec, "lookupNamespaceURI"));
    CallData callData;
    CallType callType = function->getCallData(callData);
    if (callType == CallTypeNone) {
        callType = m_customResolver->getCallData(callData);
        if (callType == CallTypeNone) {
            // FIXME: Pass actual line number and source URL.
            m_frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method.", 0, String());
            return String();
        }
        function = m_customResolver;
    }

    RefPtr<JSCustomXPathNSResolver> selfProtector(this);

    ArgList args;
    args.append(jsString(exec, prefix));

    globalObject->startTimeoutCheck();
    JSValue* retval = call(exec, function, callType, callData, m_customResolver, args);
    globalObject->stopTimeoutCheck();

    String result;
    if (exec->hadException())
        reportCurrentException(exec);
    else {
        if (!retval->isUndefinedOrNull())
            result = retval->toString(exec);
    }

    Document::updateDocumentsRendering();

    return result;
}
bool JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
{
    ASSERT(m_callback);
    ASSERT(m_frame);
        
    if (!m_frame->script()->isEnabled())
        return true;
        
    JSGlobalObject* globalObject = m_frame->script()->globalObject();
    ExecState* exec = globalObject->globalExec();
        
    JSC::JSLock lock(false);
        
    JSValue* function = m_callback->get(exec, Identifier(exec, "handleEvent"));
    CallData callData;
    CallType callType = function->getCallData(callData);
    if (callType == CallTypeNone) {
        callType = m_callback->getCallData(callData);
        if (callType == CallTypeNone) {
            // FIXME: Should an exception be thrown here?
            return true;
        }
        function = m_callback;
    }

    RefPtr<JSCustomSQLTransactionErrorCallback> protect(this);
        
    ArgList args;
    args.append(toJS(exec, error));

    JSValue *result;
    globalObject->startTimeoutCheck();
    result = call(exec, function, callType, callData, m_callback, args);
    globalObject->stopTimeoutCheck();
        
    if (exec->hadException())
        m_frame->domWindow()->console()->reportCurrentException(exec);
        
    Document::updateDocumentsRendering();
    
    return result->toBoolean(exec);
}
JSValue* JSJavaScriptCallFrame::scopeChain(ExecState* exec) const
{
    if (!impl()->scopeChain())
        return jsNull();

    const ScopeChainNode* scopeChain = impl()->scopeChain();
    ScopeChainIterator iter = scopeChain->begin();
    ScopeChainIterator end = scopeChain->end();

    // we must always have something in the scope chain
    ASSERT(iter != end);

    ArgList list;
    do {
        list.append(*iter);
        ++iter;
    } while (iter != end);

    return constructArray(exec, list);
}
Example #19
0
void Console::trace(ExecState* exec)
{
    Page* page = this->page();
    if (!page)
        return;

    int signedLineNumber;
    intptr_t sourceID;
    UString urlString;
    JSValue* func;

    exec->machine()->retrieveLastCaller(exec, signedLineNumber, sourceID, urlString, func);

    ArgList args;
    while (!func->isNull()) {
        args.append(func);
        func = exec->machine()->retrieveCaller(exec, asInternalFunction(func));
    }
    
    page->inspectorController()->addMessageToConsole(JSMessageSource, TraceMessageLevel, exec, args, 0, String());
}
JSValue* JSQuarantinedObjectWrapper::call(ExecState* exec, JSObject* function, JSValue* thisValue, const ArgList& args)
{
    JSQuarantinedObjectWrapper* wrapper = static_cast<JSQuarantinedObjectWrapper*>(function);

    JSValue* preparedThisValue = wrapper->prepareIncomingValue(exec, thisValue);

    ArgList preparedArgs;
    for (size_t i = 0; i < args.size(); ++i)
        preparedArgs.append(wrapper->prepareIncomingValue(exec, args.at(exec, i)));

    // FIXME: Would be nice to find a way to reuse the result of m_unwrappedObject->getCallData
    // from when we called it in JSQuarantinedObjectWrapper::getCallData.
    CallData unwrappedCallData;
    CallType unwrappedCallType = wrapper->m_unwrappedObject->getCallData(unwrappedCallData);
    ASSERT(unwrappedCallType != CallTypeNone);

    JSValue* unwrappedResult = KJS::call(wrapper->unwrappedExecState(), wrapper->m_unwrappedObject, unwrappedCallType, unwrappedCallData, preparedThisValue, preparedArgs);

    JSValue* result = wrapper->wrapOutgoingValue(wrapper->unwrappedExecState(), unwrappedResult);

    wrapper->transferExceptionToExecState(exec);

    return result;
}
Example #21
0
void Arguments::fillArgList(ExecState* exec, ArgList& args)
{
    if (LIKELY(!d->deletedArguments)) {
        if (LIKELY(!d->numParameters)) {
            args.initialize(d->extraArguments, d->numArguments);
            return;
        }

        if (d->numParameters == d->numArguments) {
            args.initialize(&d->registers[d->firstParameterIndex], d->numArguments);
            return;
        }

        unsigned parametersLength = min(d->numParameters, d->numArguments);
        unsigned i = 0;
        for (; i < parametersLength; ++i)
            args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
        for (; i < d->numArguments; ++i)
            args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
        return;
    }

    unsigned parametersLength = min(d->numParameters, d->numArguments);
    unsigned i = 0;
    for (; i < parametersLength; ++i) {
        if (!d->deletedArguments[i])
            args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
        else
            args.append(get(exec, i));
    }
    for (; i < d->numArguments; ++i) {
        if (!d->deletedArguments[i])
            args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
        else
            args.append(get(exec, i));
    }
}
Example #22
0
void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
{
    JSObject* listener = listenerObj();
    if (!listener)
        return;

    JSDOMWindow* window = this->window();
    // Null check as clearWindow() can clear this and we still get called back by
    // xmlhttprequest objects. See http://bugs.webkit.org/show_bug.cgi?id=13275
    if (!window)
        return;
    Frame* frame = window->impl()->frame();
    if (!frame)
        return;
    ScriptController* script = frame->script();
    if (!script->isEnabled() || script->isPaused())
        return;

    JSLock lock(false);

    ExecState* exec = window->globalExec();

    JSValue* handleEventFunction = listener->get(exec, Identifier(exec, "handleEvent"));
    CallData callData;
    CallType callType = handleEventFunction->getCallData(callData);
    if (callType == CallTypeNone) {
        handleEventFunction = 0;
        callType = listener->getCallData(callData);
    }

    if (callType != CallTypeNone) {
        ref();

        ArgList args;
        args.append(toJS(exec, event));

        Event* savedEvent = window->currentEvent();
        window->setCurrentEvent(event);

        JSValue* retval;
        if (handleEventFunction) {
            window->startTimeoutCheck();
            retval = call(exec, handleEventFunction, callType, callData, listener, args);
        } else {
            JSValue* thisValue;
            if (isWindowEvent)
                thisValue = window->shell();
            else
                thisValue = toJS(exec, event->currentTarget());
            window->startTimeoutCheck();
            retval = call(exec, listener, callType, callData, thisValue, args);
        }
        window->stopTimeoutCheck();

        window->setCurrentEvent(savedEvent);

        if (exec->hadException())
            frame->domWindow()->console()->reportCurrentException(exec);
        else {
            if (!retval->isUndefinedOrNull() && event->storesResultAsString())
                event->storeResult(retval->toString(exec));
            if (m_isHTML) {
                bool retvalbool;
                if (retval->getBoolean(retvalbool) && !retvalbool)
                    event->preventDefault();
            }
        }

        Document::updateDocumentsRendering();
        deref();
    }
}
Example #23
0
static void getListFromVariantArgs(ExecState* exec, const NPVariant* args, unsigned argCount, RootObject* rootObject, ArgList& aList)
{
    for (unsigned i = 0; i < argCount; ++i)
        aList.append(convertNPVariantToValue(exec, &args[i], rootObject));
}
// ECMA 8.6.2.2
void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
{
    ASSERT(value);
    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));

    if (propertyName == exec->propertyNames().underscoreProto) {
        JSObject* proto = value->getObject();

        // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
        if (!proto && !value->isNull())
            return;
        
        while (proto) {
            if (proto == this) {
                throwError(exec, GeneralError, "cyclic __proto__ value");
                return;
            }
            proto = proto->prototype() ? proto->prototype()->getObject() : 0;
        }
        
        setPrototype(value);
        return;
    }
    
    // Check if there are any setters or getters in the prototype chain
    JSValue* prototype;
    for (JSObject* obj = this; !obj->structureID()->hasGetterSetterProperties(); obj = asObject(prototype)) {
        prototype = obj->prototype();
        if (prototype->isNull()) {
            putDirect(propertyName, value, 0, true, slot);
            return;
        }
    }
    
    unsigned attributes;
    if ((m_structureID->get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
        return;

    for (JSObject* obj = this; ; obj = asObject(prototype)) {
        if (JSValue* gs = obj->getDirect(propertyName)) {
            if (gs->isGetterSetter()) {
                JSObject* setterFunc = asGetterSetter(gs)->setter();        
                if (!setterFunc) {
                    throwSetterError(exec);
                    return;
                }
                
                CallData callData;
                CallType callType = setterFunc->getCallData(callData);
                ArgList args;
                args.append(value);
                call(exec, setterFunc, callType, callData, this, args);
                return;
            }

            // If there's an existing property on the object or one of its 
            // prototypes it should be replaced, so break here.
            break;
        }

        prototype = obj->prototype();
        if (prototype->isNull())
            break;
    }

    putDirect(propertyName, value, 0, true, slot);
    return;
}
Example #25
0
JSValue* stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    JSString* sourceVal = thisValue->toThisJSString(exec);
    const UString& source = sourceVal->value();

    JSValue* pattern = args.at(exec, 0);

    JSValue* replacement = args.at(exec, 1);
    UString replacementString;
    CallData callData;
    CallType callType = replacement->getCallData(callData);
    if (callType == CallTypeNone)
        replacementString = replacement->toString(exec);

    if (pattern->isObject(&RegExpObject::info)) {
        RegExp* reg = static_cast<RegExpObject*>(pattern)->regExp();
        bool global = reg->global();

        RegExpConstructor* regExpObj = exec->lexicalGlobalObject()->regExpConstructor();

        int lastIndex = 0;
        int startPosition = 0;

        Vector<UString::Range, 16> sourceRanges;
        Vector<UString, 16> replacements;

        // This is either a loop (if global is set) or a one-way (if not).
        do {
            int matchIndex;
            int matchLen;
            int* ovector;
            regExpObj->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
            if (matchIndex < 0)
                break;

            sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));

            if (callType != CallTypeNone) {
                int completeMatchStart = ovector[0];
                ArgList args;

                for (unsigned i = 0; i < reg->numSubpatterns() + 1; ++i) {
                    int matchStart = ovector[i * 2];
                    int matchLen = ovector[i * 2 + 1] - matchStart;

                    if (matchStart < 0)
                        args.append(jsUndefined());
                    else
                        args.append(jsSubstring(exec, source, matchStart, matchLen));
                }

                args.append(jsNumber(exec, completeMatchStart));
                args.append(sourceVal);

                replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args)->toString(exec));
            } else
                replacements.append(substituteBackreferences(replacementString, source, ovector, reg));

            lastIndex = matchIndex + matchLen;
            startPosition = lastIndex;

            // special case of empty match
            if (matchLen == 0) {
                startPosition++;
                if (startPosition > source.size())
                    break;
            }
        } while (global);

        if (lastIndex < source.size())
            sourceRanges.append(UString::Range(lastIndex, source.size() - lastIndex));

        UString result = source.spliceSubstringsWithSeparators(sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size());

        if (result == source)
            return sourceVal;

        return jsString(exec, result);
    }

    // First arg is a string
    UString patternString = pattern->toString(exec);
    int matchPos = source.find(patternString);
    int matchLen = patternString.size();
    // Do the replacement
    if (matchPos == -1)
        return sourceVal;

    if (callType != CallTypeNone) {
        ArgList args;
        args.append(jsSubstring(exec, source, matchPos, matchLen));
        args.append(jsNumber(exec, matchPos));
        args.append(sourceVal);

        replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args)->toString(exec);
    }

    return jsString(exec, source.substr(0, matchPos) + replacementString + source.substr(matchPos + matchLen));
}