void JSErrorHandler::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event) { if (!event->hasInterface(eventNames().interfaceForErrorEvent)) return JSEventListener::handleEvent(scriptExecutionContext, event); ASSERT(scriptExecutionContext); if (!scriptExecutionContext) return; ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event); JSLock lock(SilenceAssertionsOnly); JSObject* jsFunction = this->jsFunction(scriptExecutionContext); if (!jsFunction) return; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext, isolatedWorld()); if (!globalObject) return; ExecState* exec = globalObject->globalExec(); CallData callData; CallType callType = jsFunction->methodTable()->getCallData(jsFunction, callData); if (callType != CallTypeNone) { RefPtr<JSErrorHandler> protectedctor(this); Event* savedEvent = globalObject->currentEvent(); globalObject->setCurrentEvent(event); MarkedArgumentBuffer args; args.append(jsString(exec, errorEvent->message())); args.append(jsString(exec, errorEvent->filename())); args.append(jsNumber(errorEvent->lineno())); JSGlobalData& globalData = globalObject->globalData(); DynamicGlobalObjectScope globalObjectScope(globalData, globalData.dynamicGlobalObject ? globalData.dynamicGlobalObject : globalObject); JSValue thisValue = globalObject->methodTable()->toThisObject(globalObject, exec); globalData.timeoutChecker.start(); JSValue returnValue = scriptExecutionContext->isDocument() ? JSMainThreadExecState::call(exec, jsFunction, callType, callData, thisValue, args) : JSC::call(exec, jsFunction, callType, callData, thisValue, args); globalData.timeoutChecker.stop(); globalObject->setCurrentEvent(savedEvent); if (exec->hadException()) reportCurrentException(exec); else { if (returnValue.isTrue()) event->preventDefault(); } } }
void JSWorkerContextErrorHandler::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event) { ASSERT(scriptExecutionContext); if (!scriptExecutionContext) return; JSLock lock(SilenceAssertionsOnly); JSObject* jsFunction = this->jsFunction(scriptExecutionContext); if (!jsFunction) return; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext, isolatedWorld()); if (!globalObject) return; ExecState* exec = globalObject->globalExec(); CallData callData; CallType callType = jsFunction->getCallData(callData); if (callType != CallTypeNone) { ref(); Event* savedEvent = globalObject->currentEvent(); globalObject->setCurrentEvent(event); ASSERT(event->isErrorEvent()); ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event); MarkedArgumentBuffer args; args.append(jsString(exec, errorEvent->message())); args.append(jsString(exec, errorEvent->filename())); args.append(jsNumber(exec, errorEvent->lineno())); JSGlobalData* globalData = globalObject->globalData(); DynamicGlobalObjectScope globalObjectScope(exec, globalData->dynamicGlobalObject ? globalData->dynamicGlobalObject : globalObject); JSValue thisValue = globalObject->toThisObject(exec); globalData->timeoutChecker.start(); JSValue returnValue = JSC::call(exec, jsFunction, callType, callData, thisValue, args); globalData->timeoutChecker.stop(); globalObject->setCurrentEvent(savedEvent); if (exec->hadException()) reportCurrentException(exec); else { bool retvalbool; if (returnValue.getBoolean(retvalbool) && !retvalbool) event->preventDefault(); } deref(); } }
JSObject* JSLazyEventListener::initializeJSFunction(ScriptExecutionContext* executionContext) const { ASSERT(executionContext); ASSERT(executionContext->isDocument()); if (!executionContext) return 0; Document* document = static_cast<Document*>(executionContext); if (!document->frame()) return 0; if (!document->contentSecurityPolicy()->allowInlineEventHandlers()) return 0; ScriptController* script = document->frame()->script(); if (!script->canExecuteScripts(AboutToExecuteScript) || script->isPaused()) return 0; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(executionContext, isolatedWorld()); if (!globalObject) return 0; ExecState* exec = globalObject->globalExec(); MarkedArgumentBuffer args; args.append(jsNontrivialString(exec, stringToUString(m_eventParameterName))); args.append(jsString(exec, m_code)); JSObject* jsFunction = constructFunctionSkippingEvalEnabledCheck(exec, exec->lexicalGlobalObject(), args, Identifier(exec, stringToUString(m_functionName)), stringToUString(m_sourceURL), m_position); // FIXME: is globalExec ok? if (exec->hadException()) { reportCurrentException(exec); exec->clearException(); return 0; } JSFunction* listenerAsFunction = jsCast<JSFunction*>(jsFunction); if (m_originalNode) { if (!wrapper()) { // Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating. JSLock lock(SilenceAssertionsOnly); // FIXME: Should pass the global object associated with the node setWrapper(exec->globalData(), asObject(toJS(exec, globalObject, m_originalNode))); } // Add the event's home element to the scope // (and the document, and the form - see JSHTMLElement::eventHandlerScope) listenerAsFunction->setScope(exec->globalData(), jsCast<JSNode*>(wrapper())->pushEventHandlerScope(exec, listenerAsFunction->scope())); } // Since we only parse once, there's no need to keep data used for parsing around anymore. m_functionName = String(); m_code = String(); m_eventParameterName = String(); m_sourceURL = String(); return jsFunction; }
void JSErrorHandler::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event) { if (!is<ErrorEvent>(*event)) return JSEventListener::handleEvent(scriptExecutionContext, event); ASSERT(scriptExecutionContext); if (!scriptExecutionContext) return; ErrorEvent& errorEvent = downcast<ErrorEvent>(*event); JSLockHolder lock(scriptExecutionContext->vm()); JSObject* jsFunction = this->jsFunction(scriptExecutionContext); if (!jsFunction) return; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext, isolatedWorld()); if (!globalObject) return; ExecState* exec = globalObject->globalExec(); CallData callData; CallType callType = jsFunction->methodTable()->getCallData(jsFunction, callData); if (callType != CallTypeNone) { Ref<JSErrorHandler> protectedctor(*this); Event* savedEvent = globalObject->currentEvent(); globalObject->setCurrentEvent(event); MarkedArgumentBuffer args; args.append(jsStringWithCache(exec, errorEvent.message())); args.append(jsStringWithCache(exec, errorEvent.filename())); args.append(jsNumber(errorEvent.lineno())); args.append(jsNumber(errorEvent.colno())); VM& vm = globalObject->vm(); VMEntryScope entryScope(vm, vm.entryScope ? vm.entryScope->globalObject() : globalObject); NakedPtr<Exception> exception; JSValue returnValue = scriptExecutionContext->isDocument() ? JSMainThreadExecState::call(exec, jsFunction, callType, callData, globalObject, args, exception) : JSC::call(exec, jsFunction, callType, callData, globalObject, args, exception); globalObject->setCurrentEvent(savedEvent); if (exception) reportException(exec, exception); else { if (returnValue.isTrue()) event->preventDefault(); } } }
void DOMWrapperWorld::makeContextWeak(v8::Handle<v8::Context> context) { ASSERT(isIsolatedWorld()); ASSERT(isolatedWorld(context) == this); v8::Isolate* isolate = context->GetIsolate(); v8::Persistent<v8::Context> persistent = v8::Persistent<v8::Context>::New(isolate, context); WeakHandleListener<DOMWrapperWorld>::makeWeak(isolate, persistent, this); // Matching deref is in weak callback. this->ref(); }
JSObject* JSLazyEventListener::initializeJSFunction(ScriptExecutionContext* executionContext) const { ASSERT(is<Document>(executionContext)); if (!executionContext) return nullptr; ASSERT(!m_code.isNull()); ASSERT(!m_eventParameterName.isNull()); if (m_code.isNull() || m_eventParameterName.isNull()) return nullptr; Document& document = downcast<Document>(*executionContext); if (!document.frame()) return nullptr; if (!document.contentSecurityPolicy()->allowInlineEventHandlers(m_sourceURL, m_sourcePosition.m_line)) return nullptr; ScriptController& script = document.frame()->script(); if (!script.canExecuteScripts(AboutToExecuteScript) || script.isPaused()) return nullptr; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(executionContext, isolatedWorld()); if (!globalObject) return nullptr; VM& vm = globalObject->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); ExecState* exec = globalObject->globalExec(); MarkedArgumentBuffer args; args.append(jsNontrivialString(exec, m_eventParameterName)); args.append(jsStringWithCache(exec, m_code)); // We want all errors to refer back to the line on which our attribute was // declared, regardless of any newlines in our JavaScript source text. int overrideLineNumber = m_sourcePosition.m_line.oneBasedInt(); JSObject* jsFunction = constructFunctionSkippingEvalEnabledCheck( exec, exec->lexicalGlobalObject(), args, Identifier::fromString(exec, m_functionName), m_sourceURL, m_sourcePosition, overrideLineNumber); if (UNLIKELY(scope.exception())) { reportCurrentException(exec); scope.clearException(); return nullptr; } JSFunction* listenerAsFunction = jsCast<JSFunction*>(jsFunction); if (m_originalNode) { if (!wrapper()) { // Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating. // FIXME: Should pass the global object associated with the node setWrapper(vm, asObject(toJS(exec, globalObject, *m_originalNode))); } // Add the event's home element to the scope // (and the document, and the form - see JSHTMLElement::eventHandlerScope) listenerAsFunction->setScope(vm, jsCast<JSNode*>(wrapper())->pushEventHandlerScope(exec, listenerAsFunction->scope())); } return jsFunction; }
JSObject* JSLazyEventListener::initializeJSFunction(ScriptExecutionContext* executionContext) const { ASSERT(executionContext); ASSERT(executionContext->isDocument()); if (!executionContext) return 0; Frame* frame = static_cast<Document*>(executionContext)->frame(); if (!frame) return 0; ScriptController* scriptController = frame->script(); if (!scriptController->canExecuteScripts(AboutToExecuteScript)) return 0; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(executionContext, isolatedWorld()); if (!globalObject) return 0; if (executionContext->isDocument()) { JSDOMWindow* window = static_cast<JSDOMWindow*>(globalObject); Frame* frame = window->impl()->frame(); if (!frame) return 0; // FIXME: Is this check needed for non-Document contexts? ScriptController* script = frame->script(); if (!script->canExecuteScripts(AboutToExecuteScript) || script->isPaused()) return 0; } ExecState* exec = globalObject->globalExec(); MarkedArgumentBuffer args; args.append(jsNontrivialString(exec, stringToUString(m_eventParameterName))); args.append(jsString(exec, m_code)); JSObject* jsFunction = constructFunction(exec, args, Identifier(exec, stringToUString(m_functionName)), stringToUString(m_sourceURL), m_lineNumber); // FIXME: is globalExec ok? if (exec->hadException()) { exec->clearException(); return 0; } JSFunction* listenerAsFunction = static_cast<JSFunction*>(jsFunction); if (m_originalNode) { if (!wrapper()) { // Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating. JSLock lock(SilenceAssertionsOnly); // FIXME: Should pass the global object associated with the node setWrapper(asObject(toJS(globalObject->globalExec(), globalObject, m_originalNode))); } // Add the event's home element to the scope // (and the document, and the form - see JSHTMLElement::eventHandlerScope) ScopeChain scope = listenerAsFunction->scope(); static_cast<JSNode*>(wrapper())->pushEventHandlerScope(exec, scope); listenerAsFunction->setScope(scope); } // Since we only parse once, there's no need to keep data used for parsing around anymore. m_functionName = String(); m_code = String(); m_eventParameterName = String(); m_sourceURL = String(); return jsFunction; }