Index: Source/bindings/dart/DartDebugServer.cpp |
diff --git a/Source/bindings/dart/DartDebugServer.cpp b/Source/bindings/dart/DartDebugServer.cpp |
deleted file mode 100644 |
index 55b68cdafe22dabe92a7929a221d9c24abfb2e67..0000000000000000000000000000000000000000 |
--- a/Source/bindings/dart/DartDebugServer.cpp |
+++ /dev/null |
@@ -1,650 +0,0 @@ |
-/* |
- * Copyright (C) 2012 Google Inc. All rights reserved. |
- * |
- * Redistribution and use in source and binary forms, with or without |
- * modification, are permitted provided that the following conditions are |
- * met: |
- * |
- * * Redistributions of source code must retain the above copyright |
- * notice, this list of conditions and the following disclaimer. |
- * * Redistributions in binary form must reproduce the above |
- * copyright notice, this list of conditions and the following disclaimer |
- * in the documentation and/or other materials provided with the |
- * distribution. |
- * * Neither the name of Google Inc. nor the names of its |
- * contributors may be used to endorse or promote products derived from |
- * this software without specific prior written permission. |
- * |
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- */ |
-#include "config.h" |
-#include "bindings/dart/DartDebugServer.h" |
- |
-#include "DartDebugHooksSource.h" |
-#include "bindings/dart/DartController.h" |
-#include "bindings/dart/DartHandleProxy.h" |
-#include "bindings/dart/DartUtilities.h" |
-#include "bindings/dart/V8Converter.h" |
-#include "bindings/v8/PageScriptDebugServer.h" |
-#include "bindings/v8/ScriptController.h" |
-#include "bindings/dart/DartScriptState.h" |
-#include "bindings/v8/V8Binding.h" |
-#include "core/dom/Document.h" |
-#include "core/frame/DOMWindow.h" |
-#include "core/inspector/InspectorController.h" |
-#include "core/inspector/InspectorDebuggerAgent.h" |
-#include "core/inspector/InspectorInstrumentation.h" |
-#include "core/inspector/InstrumentingAgents.h" |
-#include "core/page/Page.h" |
-#include "platform/Logging.h" |
- |
-#include "wtf/HashMap.h" |
-#include "wtf/Vector.h" |
-#include <v8-debug.h> |
- |
- |
-namespace WebCore { |
- |
-class V8EventDetails : public v8::Debug::EventDetails { |
-public: |
- V8EventDetails(v8::DebugEvent event, v8::Handle<v8::Object> executionState, v8::Handle<v8::Object> eventData) |
- : m_event(event) |
- , m_executionState(executionState) |
- , m_eventData(eventData) |
- { |
- LocalFrame* frame = DartUtilities::domWindowForCurrentIsolate()->frame(); |
- m_eventContext = toV8Context(v8::Isolate::GetCurrent(), frame, DOMWrapperWorld::mainWorld()); |
- } |
- |
- virtual v8::DebugEvent GetEvent() const { return m_event; } |
- virtual v8::Handle<v8::Object> GetExecutionState() const { return m_executionState; } |
- virtual v8::Handle<v8::Object> GetEventData() const { return m_eventData; } |
- virtual v8::Handle<v8::Context> GetEventContext() const { return m_eventContext; } |
- virtual v8::Handle<v8::Value> GetCallbackData() const { return v8::Undefined(v8::Isolate::GetCurrent()); } |
- virtual v8::Debug::ClientData* GetClientData() const { return 0; } |
- |
-private: |
- v8::DebugEvent m_event; |
- v8::Handle<v8::Object> m_executionState; |
- v8::Handle<v8::Object> m_eventData; |
- v8::Handle<v8::Context> m_eventContext; |
-}; |
- |
-template<typename T> |
-class HandleMap { |
-public: |
- HandleMap() : m_lastHandle(0) |
- { |
- } |
- |
- int add(T value) |
- { |
- int handle = ++m_lastHandle; |
- m_handleToValueMap.set(handle, value); |
- m_valueToHandleMap.set(value, handle); |
- return handle; |
- } |
- |
- T get(int handle) |
- { |
- return m_handleToValueMap.get(handle); |
- } |
- |
- int getByValue(T value) |
- { |
- ASSERT(m_valueToHandleMap.contains(value)); |
- return m_valueToHandleMap.get(value); |
- } |
- |
- T remove(int handle) |
- { |
- T value = m_handleToValueMap.take(handle); |
- m_valueToHandleMap.remove(value); |
- return value; |
- } |
- |
- int removeByValue(T value) |
- { |
- int handle = m_valueToHandleMap.take(value); |
- m_handleToValueMap.remove(handle); |
- return handle; |
- } |
- |
- void copyValues(Vector<T>& values) |
- { |
- copyKeysToVector(m_valueToHandleMap, values); |
- } |
- |
-private: |
- int m_lastHandle; |
- HashMap<int, T> m_handleToValueMap; |
- HashMap<T, int> m_valueToHandleMap; |
-}; |
- |
-static HandleMap<Dart_Isolate>& isolateMap() |
-{ |
- DEFINE_STATIC_LOCAL(HandleMap<Dart_Isolate>, map, ()); |
- return map; |
-} |
- |
-DartDebugServer& DartDebugServer::shared() |
-{ |
- DEFINE_STATIC_LOCAL(DartDebugServer, server, ()); |
- return server; |
-} |
- |
-DartDebugServer::DartDebugServer() |
-{ |
-} |
- |
-void DartDebugServer::registerIsolate(Dart_Isolate isolate) |
-{ |
- { |
- DartIsolateScope scope(isolate); |
- DartApiScope apiScope; |
- Dart_SetBreakpointHandler(breakpointHandler); |
- Dart_SetExceptionThrownHandler(exceptionHandler); |
- Dart_SetIsolateEventHandler(isolateEventHandler); |
- } |
- |
- ensureHooksInstalled(); |
- |
- int isolateHandle = isolateMap().add(isolate); |
- |
- V8Scope v8Scope(0, v8::Debug::GetDebugContext()); |
- v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); |
- v8::Local<v8::Function> registerIsolate = v8::Local<v8::Function>::Cast(dartDebugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "registerIsolate"))); |
- v8::Handle<v8::Value> args[] = { v8::Number::New(v8Isolate, isolateHandle) }; |
- registerIsolate->Call(dartDebugObject(), 1, args); |
-} |
- |
-void DartDebugServer::debugBreak() |
-{ |
- Vector<Dart_Isolate> isolates; |
- isolateMap().copyValues(isolates); |
- for (Vector<Dart_Isolate>::iterator it = isolates.begin(); it != isolates.end(); ++it) { |
- Dart_Isolate isolate = *it; |
- if (!m_interruptCalled.contains(isolate)) { |
- m_interruptCalled.add(isolate); |
- Dart_InterruptIsolate(isolate); |
- } |
- m_interruptCancelled.remove(isolate); |
- } |
-} |
- |
-void DartDebugServer::cancelDebugBreak() |
-{ |
- // FIXME: it would be nice if the DartVM provided an API to directly cancel |
- // a debug break call like V8 does. |
- for (HashSet<Dart_Isolate>::iterator it = m_interruptCalled.begin(); it != m_interruptCalled.end(); ++it) { |
- m_interruptCancelled.add(*it); |
- } |
-} |
- |
-void DartDebugServer::unregisterIsolate(Dart_Isolate isolate) |
-{ |
- int isolateHandle = isolateMap().removeByValue(isolate); |
- |
- // The constructor for V8Scope expects Dart_InitOnce to have been |
- // invoked while it accesses the script execution context |
- // (DartUtilities::scriptExecutionContext). The assert below ensures |
- // that by making sure the DartDebugObject has been setup. |
- ASSERT(!m_dartDebugObject.isEmpty()); |
- V8Scope v8Scope(0, v8::Debug::GetDebugContext()); |
- v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); |
- v8::Local<v8::Function> unregisterIsolate = v8::Local<v8::Function>::Cast(dartDebugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "unregisterIsolate"))); |
- v8::Handle<v8::Value> args[] = { v8::Number::New(v8Isolate, isolateHandle) }; |
- unregisterIsolate->Call(dartDebugObject(), 1, args); |
-} |
- |
-void DartDebugServer::isolateLoaded() |
-{ |
- Page* page = DartUtilities::domWindowForCurrentIsolate()->document()->page(); |
- if (!page || !instrumentationForPage(page)->inspectorDebuggerAgent()) |
- return; |
- |
- ASSERT(Dart_CurrentIsolate()); |
- V8Scope v8Scope(DartDOMData::current(), v8::Debug::GetDebugContext()); |
- |
- int isolateHandle = isolateMap().getByValue(Dart_CurrentIsolate()); |
- |
- LocalFrame* frame = DartUtilities::domWindowForCurrentIsolate()->frame(); |
- DartController* controller = DartController::retrieve(frame); |
- Vector<DartScriptState*> scriptStates; |
- controller->collectScriptStatesForIsolate(Dart_CurrentIsolate(), DartUtilities::currentV8Context(), scriptStates); |
- for (size_t i = 0; i< scriptStates.size(); i++) |
- InspectorInstrumentation::didCreateIsolatedContext(frame, scriptStates[i], 0); |
- |
- ASSERT(!m_dartDebugObject.isEmpty()); |
- v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); |
- v8::Local<v8::Function> isolateLoaded = v8::Local<v8::Function>::Cast(dartDebugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "isolateLoaded"))); |
- v8::Handle<v8::Value> args[] = { v8::Number::New(v8Isolate, isolateHandle) }; |
- isolateLoaded->Call(dartDebugObject(), 1, args); |
-} |
- |
-void DartDebugServer::disable() |
-{ |
- // Only invoke the disable method when Dart code was executed on the page. |
- if (m_dartDebugObject.isEmpty()) |
- return; |
- V8Scope v8Scope(0, v8::Debug::GetDebugContext()); |
- v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); |
- v8::Local<v8::Function> disable = v8::Local<v8::Function>::Cast(dartDebugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "disable"))); |
- disable->Call(dartDebugObject(), 0, 0); |
-} |
- |
-bool lookupTokenLineNumber(const Dart_CodeLocation& location, int* lineNumber, int* columnNumber) |
-{ |
- Dart_Handle info = Dart_ScriptGetTokenInfo(location.library_id, location.script_url); |
- ASSERT(Dart_IsList(info)); |
- intptr_t infoLength = 0; |
- Dart_Handle ALLOW_UNUSED result = Dart_ListLength(info, &infoLength); |
- ASSERT(!Dart_IsError(result)); |
- Dart_Handle elem; |
- bool lineStart = true; |
- int currentLineNumber = 0; |
- for (intptr_t i = 0; i < infoLength; i++) { |
- elem = Dart_ListGetAt(info, i); |
- if (Dart_IsNull(elem)) { |
- lineStart = true; |
- } else { |
- ASSERT(Dart_IsInteger(elem)); |
- Dart_Handle exception = 0; |
- int64_t value = DartUtilities::toInteger(elem, exception); |
- ASSERT(!exception); |
- if (lineStart) { |
- // Line number. |
- currentLineNumber = value; |
- lineStart = false; |
- } else { |
- // Token offset. |
- if (value == location.token_pos) { |
- *lineNumber = currentLineNumber; |
- ASSERT(i + 1 < infoLength); |
- *columnNumber = DartUtilities::toInteger(Dart_ListGetAt(info, i + 1), exception); |
- ASSERT(!exception); |
- return true; |
- } |
- i++; // skip columnNumber. |
- } |
- } |
- } |
- return false; |
-} |
- |
-v8::Handle<v8::Object> DartDebugServer::createExecutionState(Dart_StackTrace trace) |
-{ |
- intptr_t length = 0; |
- Dart_Handle ALLOW_UNUSED result = Dart_StackTraceLength(trace, &length); |
- ASSERT(!Dart_IsError(result)); |
- ASSERT(length); |
- ASSERT(Dart_CurrentIsolate()); |
- int isolateHandle = isolateMap().getByValue(Dart_CurrentIsolate()); |
- |
- v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); |
- v8::Local<v8::Array> callFrames = v8::Array::New(v8Isolate, length); |
- for (int i = length - 1; i >= 0; --i) { |
- Dart_ActivationFrame frame = 0; |
- result = Dart_GetActivationFrame(trace, i, &frame); |
- ASSERT(!Dart_IsError(result)); |
- Dart_Handle functionName = 0; |
- Dart_Handle function = 0; |
- |
- Dart_CodeLocation location; |
- result = Dart_ActivationFrameGetLocation(frame, &functionName, &function, &location); |
- int lineNumber = 0; |
- int columnNumber = 0; |
- lookupTokenLineNumber(location, &lineNumber, &columnNumber); |
- ASSERT(!Dart_IsError(result)); |
- Dart_Handle libraryURL = Dart_GetLibraryURL(location.library_id); |
- ASSERT(!Dart_IsError(libraryURL)); |
- Dart_Handle library = Dart_LookupLibrary(libraryURL); |
- Dart_Handle localVariablesHandle = Dart_GetLocalVariables(frame); |
- |
- v8::Local<v8::Object> callFrame = v8::Object::New(v8Isolate); |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "functionName"), V8Converter::stringToV8(functionName)); |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "functionProxy"), DartHandleProxy::create(function)); |
- Dart_Handle functionOwner = function; |
- // Walk up the chain of function owners until we reach a type or library handle. |
- while (Dart_IsFunction(functionOwner)) |
- functionOwner = Dart_FunctionOwner(functionOwner); |
- |
- if (Dart_IsType(functionOwner)) { |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "classProxy"), DartHandleProxy::createTypeProxy(functionOwner, true)); |
- } |
- |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "scriptURL"), V8Converter::stringToV8(location.script_url)); |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "lineNumber"), v8::Number::New(v8Isolate, lineNumber - 1)); |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "columnNumber"), v8::Number::New(v8Isolate, columnNumber - 1)); |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "libraryProxy"), DartHandleProxy::createLibraryProxy(library, location.library_id, Dart_Null(), true)); |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "localScopeProxy"), DartHandleProxy::createLocalScopeProxy( |
- localVariablesHandle)); |
- { |
- v8::Local<v8::Object> librariesMap = v8::Object::New(v8Isolate); |
- Dart_Handle libraries = Dart_GetLibraryIds(); |
- ASSERT(Dart_IsList(libraries)); |
- |
- intptr_t librariesLength = 0; |
- Dart_Handle ALLOW_UNUSED result = Dart_ListLength(libraries, &librariesLength); |
- ASSERT(!Dart_IsError(result)); |
- for (intptr_t i = 0; i < librariesLength; ++i) { |
- Dart_Handle libraryIdHandle = Dart_ListGetAt(libraries, i); |
- ASSERT(!Dart_IsError(libraryIdHandle)); |
- Dart_Handle exception = 0; |
- int64_t libraryId = DartUtilities::toInteger(libraryIdHandle, exception); |
- v8::Local<v8::String> libraryName = V8Converter::stringToV8(Dart_GetLibraryURL(libraryId)); |
- v8::Local<v8::Value> libraryProxy = DartHandleProxy::createLibraryProxy(Dart_GetLibraryFromId(libraryId), libraryId, Dart_Null(), false); |
- librariesMap->Set(libraryName, libraryProxy); |
- } |
- librariesMap->Set(v8::String::NewFromUtf8(v8Isolate, "__proto__"), v8::Null(v8Isolate)); |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "librariesProxy"), librariesMap); |
- } |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "localVariables"), DartHandleProxy::create(localVariablesHandle)); |
- callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "isolateHandle"), v8::Number::New(v8Isolate, isolateHandle)); |
- callFrames->Set(i, callFrame); |
- } |
- |
- ASSERT(!m_dartDebugObject.isEmpty()); |
- v8::Handle<v8::Function> executionStateConstructor = v8::Local<v8::Function>::Cast(dartDebugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "ExecutionState"))); |
- v8::Handle<v8::Value> args[] = { callFrames }; |
- return v8::Local<v8::Object>::Cast(executionStateConstructor->CallAsConstructor(1, args)); |
-} |
- |
-void DartDebugServer::breakpointHandler(Dart_IsolateId isolateId, Dart_Breakpoint breakpoint, Dart_StackTrace trace) |
-{ |
- DartDebugServer::shared().handleBreakpoint(breakpoint, trace); |
-} |
- |
-void DartDebugServer::handleBreakpoint(Dart_Breakpoint, Dart_StackTrace trace) |
-{ |
- // The constructor for V8Scope expects Dart_InitOnce to have been |
- // invoked while it accesses the script execution context |
- // (DartUtilities::scriptExecutionContext). The assert below ensures |
- // that by making sure the DartDebugObject has been setup. |
- ASSERT(!m_dartDebugObject.isEmpty()); |
- v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); |
- V8Scope v8Scope(0, v8::Debug::GetDebugContext()); |
- V8Scope v8WorldScope(0, DartUtilities::currentV8Context()); |
- V8EventDetails eventDetails(v8::Break, createExecutionState(trace), v8::Object::New(v8Isolate)); |
- PageScriptDebugServer::shared().handleV8DebugEvent(eventDetails); |
-} |
- |
-void DartDebugServer::exceptionHandler(Dart_IsolateId isolateId, Dart_Handle exception, Dart_StackTrace trace) |
-{ |
- DartDebugServer::shared().handleException(exception, trace); |
-} |
- |
-void DartDebugServer::isolateEventHandler(Dart_IsolateId isolateId, Dart_IsolateEvent kind) |
-{ |
- if (kind == kInterrupted) { |
- DartDebugServer::shared().handleInterrupted(isolateId); |
- } |
-} |
- |
-void DartDebugServer::handleInterrupted(Dart_IsolateId isolateId) |
-{ |
- Dart_Isolate isolate = Dart_GetIsolate(isolateId); |
- |
- if (isolate) { |
- ASSERT(isolate == Dart_CurrentIsolate()); |
- ASSERT(m_interruptCalled.contains(isolate)); |
- m_interruptCalled.remove(isolate); |
- if (m_interruptCancelled.contains(isolate)) { |
- m_interruptCancelled.remove(isolate); |
- return; |
- } |
- |
- // FIXME: this is a bit of a hack. V8 was also set to pause on the next |
- // code execution. If it attempts to pause while in the middle of |
- // internal V8 debugger logic it will crash so before we do anything we |
- // need to cancel the pending pause sent to V8. |
- // Perhaps it would be slightly less hacky to send a message to |
- // ScriptDebugServer instructing it to cancel pausing V8. |
- v8::Debug::CancelDebugBreak(DartUtilities::currentV8Context()->GetIsolate()); |
- |
- // The user really wants to be paused at the start of the first line of |
- // the Dart method not at the method invocation itself. Otherwise, |
- // stepping to the next call steps out of the executing Dart code |
- // which is not what the user expects. |
- Dart_SetStepInto(); |
- } |
-} |
- |
-void DartDebugServer::handleException(Dart_Handle exception, Dart_StackTrace trace) |
-{ |
- // The constructor for V8Scope expects Dart_InitOnce to have been |
- // invoked while it accesses the script execution context |
- // (DartUtilities::scriptExecutionContext). The assert below ensures |
- // that by making sure the DartDebugObject has been setup. |
- ASSERT(!m_dartDebugObject.isEmpty()); |
- V8Scope v8Scope(0, v8::Debug::GetDebugContext()); |
- V8Scope v8WorldScope(0, DartUtilities::currentV8Context()); |
- v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); |
- v8::Handle<v8::Function> eventDataConstructor = v8::Local<v8::Function>::Cast(dartDebugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "EventData"))); |
- v8::Handle<v8::Value> args[] = { DartHandleProxy::create(exception) }; |
- v8::Handle<v8::Object> eventData = v8::Local<v8::Object>::Cast(eventDataConstructor->CallAsConstructor(1, args)); |
- V8EventDetails eventDetails(v8::Exception, createExecutionState(trace), eventData); |
- PageScriptDebugServer::shared().handleV8DebugEvent(eventDetails); |
-} |
- |
-static void handleDebugEvent(const v8::FunctionCallbackInfo<v8::Value>& args) |
-{ |
- v8::DebugEvent event = static_cast<v8::DebugEvent>(args[0]->Int32Value()); |
- v8::Local<v8::Object> executionState = v8::Local<v8::Object>::Cast(args[1]); |
- v8::Local<v8::Object> eventData = v8::Local<v8::Object>::Cast(args[2]); |
- V8EventDetails eventDetails(event, executionState, eventData); |
- PageScriptDebugServer::shared().handleV8DebugEvent(eventDetails); |
-} |
- |
-static void scriptsForIsolate(const v8::FunctionCallbackInfo<v8::Value>& args) |
-{ |
- v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); |
- v8::Handle<v8::Array> v8Scripts = v8::Array::New(v8Isolate); |
- |
- Dart_Isolate isolate = isolateMap().get(args[0]->Int32Value()); |
- |
- DartIsolateScope scope(isolate); |
- DartApiScope apiScope; |
- |
- LocalFrame* frame = DartUtilities::domWindowForCurrentIsolate()->frame(); |
- v8::Handle<v8::Value> contextData = toV8Context(v8Isolate, frame, DOMWrapperWorld::mainWorld())->GetEmbedderData(0); |
- |
- Dart_Handle libraries = Dart_GetLibraryIds(); |
- ASSERT(Dart_IsList(libraries)); |
- |
- intptr_t librariesLength = 0; |
- Dart_Handle ALLOW_UNUSED result = Dart_ListLength(libraries, &librariesLength); |
- ASSERT(!Dart_IsError(result)); |
- for (intptr_t i = 0; i < librariesLength; ++i) { |
- Dart_Handle libraryIdHandle = Dart_ListGetAt(libraries, i); |
- ASSERT(!Dart_IsError(libraryIdHandle)); |
- Dart_Handle exception = 0; |
- int64_t int64LibraryId = DartUtilities::toInteger(libraryIdHandle, exception); |
- ASSERT(!exception); |
- intptr_t libraryId = static_cast<intptr_t>(int64LibraryId); |
- ASSERT(libraryId == int64LibraryId); |
- |
- Dart_Handle libraryURL = Dart_GetLibraryURL(libraryId); |
- ASSERT(Dart_IsString(libraryURL)); |
- |
- Dart_SetLibraryDebuggable(libraryId, true); |
- |
- Dart_Handle scripts = Dart_GetScriptURLs(libraryURL); |
- ASSERT(Dart_IsList(scripts)); |
- |
- intptr_t scriptsLength = 0; |
- result = Dart_ListLength(scripts, &scriptsLength); |
- ASSERT(!Dart_IsError(result)); |
- for (intptr_t j = 0; j < scriptsLength; ++j) { |
- Dart_Handle scriptURL = Dart_ListGetAt(scripts, j); |
- ASSERT(Dart_IsString(scriptURL)); |
- |
- Dart_Handle source = Dart_ScriptGetSource(libraryId, scriptURL); |
- ASSERT(Dart_IsString(source)); |
- |
- v8::Handle<v8::Object> v8Script = v8::Object::New(v8Isolate); |
- v8Script->Set(v8::String::NewFromUtf8(v8Isolate, "libraryId"), v8::Number::New(v8Isolate, libraryId)); |
- v8Script->Set(v8::String::NewFromUtf8(v8Isolate, "scriptURL"), V8Converter::stringToV8(scriptURL)); |
- v8Script->Set(v8::String::NewFromUtf8(v8Isolate, "source"), V8Converter::stringToV8(source)); |
- v8Script->Set(v8::String::NewFromUtf8(v8Isolate, "contextData"), contextData); |
- |
- v8Scripts->Set(v8::Integer::New(v8Isolate, v8Scripts->Length()), v8Script); |
- } |
- } |
- v8SetReturnValue(args, v8Scripts); |
-} |
- |
-static void setBreakpoint(const v8::FunctionCallbackInfo<v8::Value>& args) |
-{ |
- Dart_Isolate isolate = isolateMap().get(args[0]->Int32Value()); |
- |
- DartIsolateScope scope(isolate); |
- DartApiScope apiScope; |
- |
- Dart_Handle scriptURL = V8Converter::stringToDart(args[1]); |
- Dart_Handle breakpointId = Dart_SetBreakpoint(scriptURL, args[2]->Int32Value()); |
- if (!Dart_IsError(breakpointId)) |
- v8SetReturnValue(args, V8Converter::numberToV8(breakpointId)); |
-} |
- |
-static void removeBreakpoint(const v8::FunctionCallbackInfo<v8::Value>& args) |
-{ |
- Dart_Isolate isolate = isolateMap().get(args[0]->Int32Value()); |
- |
- DartIsolateScope scope(isolate); |
- DartApiScope apiScope; |
- Dart_Handle ALLOW_UNUSED result = Dart_RemoveBreakpoint(args[1]->Int32Value()); |
- ASSERT(!Dart_IsError(result)); |
-} |
- |
-static void getBreakpointLine(const v8::FunctionCallbackInfo<v8::Value>& args) |
-{ |
- Dart_Isolate isolate = isolateMap().get(args[0]->Int32Value()); |
- |
- DartIsolateScope scope(isolate); |
- DartApiScope apiScope; |
- v8SetReturnValue(args, V8Converter::numberToV8(Dart_GetBreakpointLine(args[1]->Int32Value()))); |
-} |
- |
-static void setExceptionPauseInfo(const v8::FunctionCallbackInfo<v8::Value>& args) |
-{ |
- Dart_Isolate isolate = isolateMap().get(args[0]->Int32Value()); |
- bool pauseOnAllExceptions = args[1]->BooleanValue(); |
- bool pauseOnUnhandledExceptions = args[2]->BooleanValue(); |
- |
- DartIsolateScope scope(isolate); |
- DartApiScope apiScope; |
- Dart_ExceptionPauseInfo pauseInfo = kNoPauseOnExceptions; |
- if (pauseOnUnhandledExceptions) |
- pauseInfo = kPauseOnUnhandledExceptions; |
- if (pauseOnAllExceptions) |
- pauseInfo = kPauseOnAllExceptions; |
- Dart_SetExceptionPauseInfo(pauseInfo); |
-} |
- |
-static void stepInto(const v8::FunctionCallbackInfo<v8::Value>& args) |
-{ |
- Dart_SetStepInto(); |
-} |
- |
-static void stepOver(const v8::FunctionCallbackInfo<v8::Value>& args) |
-{ |
- Dart_SetStepOver(); |
-} |
- |
-static void stepOut(const v8::FunctionCallbackInfo<v8::Value>& args) |
-{ |
- Dart_SetStepOut(); |
-} |
- |
-static void evaluateInScope(const v8::FunctionCallbackInfo<v8::Value>& args) |
-{ |
- v8::Handle<v8::String> expression = args[0]->ToString(); |
- v8::Handle<v8::Value> receiver = args[1]; |
- v8::Handle<v8::Object> functionProxy = args[2].As<v8::Object>(); |
- v8::Handle<v8::Value> localVariablesProxy = args[3]; |
- bool disableBreak = args[4]->BooleanValue(); |
- |
- DartScopes scopes(functionProxy, disableBreak); |
- Dart_Handle target = 0; |
- if (receiver->IsNull() || receiver->IsUndefined()) { |
- target = scopes.handle; |
- // Dart_EvaluateExpr cannot handle targets that are function handles so |
- // we walk up the chain of function owners until we reach a type |
- // or library handle. |
- while (Dart_IsFunction(target)) |
- target = Dart_FunctionOwner(target); |
- ASSERT(Dart_IsLibrary(target) || Dart_IsType(target)); |
- } else { |
- target = DartHandleProxy::unwrapValue(receiver); |
- } |
- |
- ASSERT(!Dart_IsError(target)); |
- Dart_Handle localVariables = DartHandleProxy::unwrapValue(localVariablesProxy); |
- |
- v8SetReturnValue(args, DartHandleProxy::evaluate(target, V8Converter::stringToDart(expression), localVariables)); |
-} |
- |
-void DartDebugServer::ensureHooksInstalled() |
-{ |
- DEFINE_STATIC_LOCAL(bool, hooksInstalled, (false)); |
- |
- if (hooksInstalled) |
- return; |
- |
- hooksInstalled = true; |
- |
- ASSERT(Dart_CurrentIsolate()); |
- v8::HandleScope scope(v8::Isolate::GetCurrent()); |
- V8Scope v8Scope(0, v8::Debug::GetDebugContext()); |
- String dartDebugHooksSource(reinterpret_cast<const char*>(DartDebugHooksSource_js), sizeof(DartDebugHooksSource_js)); |
- |
- v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); |
- m_dartDebugObject.set(v8Isolate, v8::Local<v8::Object>::Cast(v8::Script::Compile(v8String(v8Isolate, dartDebugHooksSource))->Run())); |
- |
- // We must set the v8 context to the page's context before invoking Dart |
- // code because of security checks in the console.log implementation |
- // (see InjectedScriptManager::canAccessInspectedWindow). |
- DartUtilities::currentV8Context()->Enter(); |
- v8::Local<v8::Object> evaluateInScopeFunction = v8::FunctionTemplate::New(v8Isolate, &evaluateInScope)->GetFunction(); |
- DartUtilities::currentV8Context()->Exit(); |
- |
- v8::Local<v8::Object> nativeCallbacks = v8::Object::New(v8Isolate); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "handleDebugEvent"), v8::FunctionTemplate::New(v8Isolate, &handleDebugEvent)->GetFunction()); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "scriptsForIsolate"), v8::FunctionTemplate::New(v8Isolate, &scriptsForIsolate)->GetFunction()); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "setBreakpoint"), v8::FunctionTemplate::New(v8Isolate, &setBreakpoint)->GetFunction()); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "removeBreakpoint"), v8::FunctionTemplate::New(v8Isolate, &removeBreakpoint)->GetFunction()); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "getBreakpointLine"), v8::FunctionTemplate::New(v8Isolate, &getBreakpointLine)->GetFunction()); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "setExceptionPauseInfo"), v8::FunctionTemplate::New(v8Isolate, &setExceptionPauseInfo)->GetFunction()); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "stepInto"), v8::FunctionTemplate::New(v8Isolate, &stepInto)->GetFunction()); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "stepOver"), v8::FunctionTemplate::New(v8Isolate, &stepOver)->GetFunction()); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "stepOut"), v8::FunctionTemplate::New(v8Isolate, &stepOut)->GetFunction()); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "evaluateInScope"), evaluateInScopeFunction); |
- { |
- // Trampoline script is required to properly set calling context before |
- // invoking Dart code because of security checks in console.log |
- // implementation (see InjectedScriptManager::canAccessInspectedWindow). |
- V8Scope v8scope(0); |
- v8::Handle<v8::String> trampolineScript = v8::String::NewFromUtf8(v8Isolate, "(function (func, args) { return func.apply(this, args); })"); |
- v8::Local<v8::Function> trampoline = v8::Local<v8::Function>::Cast(v8::Script::Compile(trampolineScript)->Run()); |
- nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "invocationTrampoline"), trampoline); |
- } |
- dartDebugObject()->Set(v8::String::NewFromUtf8(v8Isolate, "nativeCallbacks"), nativeCallbacks); |
-} |
- |
-v8::Local<v8::Object> DartDebugServer::dartDebugObject() |
-{ |
- return m_dartDebugObject.newLocal(v8::Isolate::GetCurrent()); |
-} |
- |
-} |