void JavaScriptDebugServer::sourceParsed(ExecState* exec, int sourceID, const UString& sourceURL, const SourceProvider& source, int startingLineNumber, int errorLine, const UString& errorMessage) { if (m_callingListeners) return; Page* page = toPage(exec->dynamicGlobalObject()); if (!page) return; m_callingListeners = true; ASSERT(hasListeners()); bool isError = errorLine != -1; if (!m_listeners.isEmpty()) { if (isError) dispatchFailedToParseSource(m_listeners, exec, source, startingLineNumber, sourceURL, errorLine, errorMessage); else dispatchDidParseSource(m_listeners, exec, source, startingLineNumber, sourceURL, sourceID); } if (ListenerSet* pageListeners = m_pageListenersMap.get(page)) { ASSERT(!pageListeners->isEmpty()); if (isError) dispatchFailedToParseSource(*pageListeners, exec, source, startingLineNumber, sourceURL, errorLine, errorMessage); else dispatchDidParseSource(*pageListeners, exec, source, startingLineNumber, sourceURL, sourceID); } m_callingListeners = false; }
void WorkerScriptDebugServer::addListener(ScriptDebugListener* listener, WorkerContext* workerContext) { v8::HandleScope scope; v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext(); v8::Context::Scope contextScope(debuggerContext); if (!m_listenersMap.size()) { // FIXME: synchronize access to this code. ensureDebuggerScriptCompiled(); ASSERT(!m_debuggerScript.get()->IsUndefined()); v8::Debug::SetDebugEventListener2(&WorkerScriptDebugServer::v8DebugEventCallback, v8::External::New(this)); } m_listenersMap.set(workerContext, listener); WorkerContextExecutionProxy* proxy = workerContext->script()->proxy(); if (!proxy) return; v8::Handle<v8::Context> context = proxy->context(); v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getWorkerScripts"))); v8::Handle<v8::Value> argv[] = { v8::Handle<v8::Value>() }; v8::Handle<v8::Value> value = getScriptsFunction->Call(m_debuggerScript.get(), 0, argv); if (value.IsEmpty()) return; ASSERT(!value->IsUndefined() && value->IsArray()); v8::Handle<v8::Array> scriptsArray = v8::Handle<v8::Array>::Cast(value); for (unsigned i = 0; i < scriptsArray->Length(); ++i) dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(i)))); }
void ScriptDebugServer::handleV8DebugMessage(const v8::Debug::Message& message) { v8::HandleScope scope; if (!message.IsEvent()) return; // Ignore unsupported event types. if (message.GetEvent() != v8::AfterCompile && message.GetEvent() != v8::Break && message.GetEvent() != v8::Exception) return; v8::Handle<v8::Context> context = message.GetEventContext(); // If the context is from one of the inpected tabs it should have its context // data. Skip events from unknown contexts. if (context.IsEmpty()) return; // Test that context has associated global dom window object. v8::Handle<v8::Object> global = context->Global(); if (global.IsEmpty()) return; global = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), global); if (global.IsEmpty()) return; bool handled = false; Frame* frame = V8Proxy::retrieveFrame(context); if (frame) { ScriptDebugListener* listener = m_listenersMap.get(frame->page()); if (listener) { if (message.GetEvent() == v8::AfterCompile) { handled = true; v8::Context::Scope contextScope(v8::Debug::GetDebugContext()); v8::Local<v8::Object> args = v8::Object::New(); args->Set(v8::String::New("eventData"), message.GetEventData()); v8::Handle<v8::Function> onAfterCompileFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getAfterCompileScript"))); v8::Handle<v8::Value> argv[] = { message.GetExecutionState(), args }; v8::Handle<v8::Value> value = onAfterCompileFunction->Call(m_debuggerScript.get(), 2, argv); ASSERT(value->IsObject()); v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); dispatchDidParseSource(listener, object); } else if (message.GetEvent() == v8::Break || message.GetEvent() == v8::Exception) { handled = true; m_executionState.set(message.GetExecutionState()); m_currentCallFrameState = mainWorldScriptState(frame); listener->didPause(); m_currentCallFrameState = 0; } } } if (!handled && !message.WillStartRunning()) continueProgram(); }
void ScriptDebugServer::handleV8DebugEvent(const v8::Debug::EventDetails& eventDetails) { v8::DebugEvent event = eventDetails.GetEvent(); if (event == v8::BreakForCommand) { ClientDataImpl* data = static_cast<ClientDataImpl*>(eventDetails.GetClientData()); data->task()->run(); return; } if (event != v8::Break && event != v8::Exception && event != v8::AfterCompile) return; v8::Handle<v8::Context> eventContext = eventDetails.GetEventContext(); ASSERT(!eventContext.IsEmpty()); ScriptDebugListener* listener = getDebugListenerForContext(eventContext); if (listener) { v8::HandleScope scope; if (event == v8::AfterCompile) { v8::Context::Scope contextScope(v8::Debug::GetDebugContext()); v8::Handle<v8::Function> onAfterCompileFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getAfterCompileScript"))); v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; v8::Handle<v8::Value> value = onAfterCompileFunction->Call(m_debuggerScript.get(), 1, argv); ASSERT(value->IsObject()); v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); dispatchDidParseSource(listener, object); } else if (event == v8::Break || event == v8::Exception) { v8::Handle<v8::Value> exception; if (event == v8::Exception) { v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(1); // Stack trace is empty in case of syntax error. Silently continue execution in such cases. if (!stackTrace->GetFrameCount()) return; v8::Handle<v8::Object> eventData = eventDetails.GetEventData(); v8::Handle<v8::Value> exceptionGetterValue = eventData->Get(v8::String::New("exception")); ASSERT(!exceptionGetterValue.IsEmpty() && exceptionGetterValue->IsFunction()); v8::Handle<v8::Value> argv[] = { v8::Handle<v8::Value>() }; V8RecursionScope::MicrotaskSuppression scope; exception = v8::Handle<v8::Function>::Cast(exceptionGetterValue)->Call(eventData, 0, argv); } m_pausedContext = *eventContext; breakProgram(eventDetails.GetExecutionState(), exception); m_pausedContext.Clear(); } } }
void ScriptDebugServer::sourceParsed(ExecState* exec, SourceProvider* sourceProvider, int errorLine, const String& errorMessage) { if (m_callingListeners) return; ListenerSet& listeners = getListeners(); if (listeners.isEmpty()) return; TemporaryChange<bool> change(m_callingListeners, true); bool isError = errorLine != -1; if (isError) dispatchFailedToParseSource(listeners, sourceProvider, errorLine, errorMessage); else dispatchDidParseSource(listeners, sourceProvider, isContentScript(exec)); }
void ScriptDebugServer::sourceParsed(ExecState* exec, SourceProvider* sourceProvider, int errorLine, const UString& errorMessage) { if (m_callingListeners) return; ListenerSet* listeners = getListenersForGlobalObject(exec->lexicalGlobalObject()); if (!listeners) return; ASSERT(!listeners->isEmpty()); m_callingListeners = true; bool isError = errorLine != -1; if (isError) dispatchFailedToParseSource(*listeners, sourceProvider, errorLine, ustringToString(errorMessage)); else dispatchDidParseSource(*listeners, sourceProvider, isContentScript(exec)); m_callingListeners = false; }
void WorkerScriptDebugServer::addListener(ScriptDebugListener* listener) { v8::HandleScope scope; v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext(); v8::Context::Scope contextScope(debuggerContext); ASSERT(!m_listener); m_listener = listener; ensureDebuggerScriptCompiled(); ASSERT(!m_debuggerScript.get()->IsUndefined()); v8::Debug::SetDebugEventListener2(&WorkerScriptDebugServer::v8DebugEventCallback, v8::External::New(this)); v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::NewSymbol("getWorkerScripts"))); v8::Handle<v8::Value> argv[] = { v8Undefined() }; v8::Handle<v8::Value> value = getScriptsFunction->Call(m_debuggerScript.get(), 0, argv); if (value.IsEmpty()) return; ASSERT(!value->IsUndefined() && value->IsArray()); v8::Handle<v8::Array> scriptsArray = v8::Handle<v8::Array>::Cast(value); for (unsigned i = 0; i < scriptsArray->Length(); ++i) dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8Integer(i, debuggerContext->GetIsolate())))); }
void WorkerScriptDebugServer::addListener(ScriptDebugListener* listener) { v8::HandleScope scope(m_isolate); v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext(); v8::Context::Scope contextScope(debuggerContext); ASSERT(!m_listener); m_listener = listener; ensureDebuggerScriptCompiled(); v8::Local<v8::Object> debuggerScript = m_debuggerScript.newLocal(m_isolate); ASSERT(!debuggerScript->IsUndefined()); v8::Debug::SetDebugEventListener2(&WorkerScriptDebugServer::v8DebugEventCallback, v8::External::New(m_isolate, this)); v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(debuggerScript->Get(v8AtomicString(m_isolate, "getWorkerScripts"))); v8::Handle<v8::Value> value = V8ScriptRunner::callInternalFunction(getScriptsFunction, debuggerScript, 0, 0, m_isolate); if (value.IsEmpty()) return; ASSERT(!value->IsUndefined() && value->IsArray()); v8::Handle<v8::Array> scriptsArray = v8::Handle<v8::Array>::Cast(value); for (unsigned i = 0; i < scriptsArray->Length(); ++i) dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(m_isolate, i)))); }