Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: Source/bindings/dart/DartDebugServer.cpp

Issue 300393002: Merge DevTools Refactor CL to Blink36 (Closed) Base URL: svn://svn.chromium.org/blink/branches/dart/1985
Patch Set: PTAL Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/bindings/dart/DartDebugServer.h ('k') | Source/bindings/dart/DartInjectedScript.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 #include "config.h"
31 #include "bindings/dart/DartDebugServer.h"
32
33 #include "DartDebugHooksSource.h"
34 #include "bindings/dart/DartController.h"
35 #include "bindings/dart/DartHandleProxy.h"
36 #include "bindings/dart/DartUtilities.h"
37 #include "bindings/dart/V8Converter.h"
38 #include "bindings/v8/PageScriptDebugServer.h"
39 #include "bindings/v8/ScriptController.h"
40 #include "bindings/dart/DartScriptState.h"
41 #include "bindings/v8/V8Binding.h"
42 #include "core/dom/Document.h"
43 #include "core/frame/DOMWindow.h"
44 #include "core/inspector/InspectorController.h"
45 #include "core/inspector/InspectorDebuggerAgent.h"
46 #include "core/inspector/InspectorInstrumentation.h"
47 #include "core/inspector/InstrumentingAgents.h"
48 #include "core/page/Page.h"
49 #include "platform/Logging.h"
50
51 #include "wtf/HashMap.h"
52 #include "wtf/Vector.h"
53 #include <v8-debug.h>
54
55
56 namespace WebCore {
57
58 class V8EventDetails : public v8::Debug::EventDetails {
59 public:
60 V8EventDetails(v8::DebugEvent event, v8::Handle<v8::Object> executionState, v8::Handle<v8::Object> eventData)
61 : m_event(event)
62 , m_executionState(executionState)
63 , m_eventData(eventData)
64 {
65 LocalFrame* frame = DartUtilities::domWindowForCurrentIsolate()->frame() ;
66 m_eventContext = toV8Context(v8::Isolate::GetCurrent(), frame, DOMWrappe rWorld::mainWorld());
67 }
68
69 virtual v8::DebugEvent GetEvent() const { return m_event; }
70 virtual v8::Handle<v8::Object> GetExecutionState() const { return m_executio nState; }
71 virtual v8::Handle<v8::Object> GetEventData() const { return m_eventData; }
72 virtual v8::Handle<v8::Context> GetEventContext() const { return m_eventCont ext; }
73 virtual v8::Handle<v8::Value> GetCallbackData() const { return v8::Undefined (v8::Isolate::GetCurrent()); }
74 virtual v8::Debug::ClientData* GetClientData() const { return 0; }
75
76 private:
77 v8::DebugEvent m_event;
78 v8::Handle<v8::Object> m_executionState;
79 v8::Handle<v8::Object> m_eventData;
80 v8::Handle<v8::Context> m_eventContext;
81 };
82
83 template<typename T>
84 class HandleMap {
85 public:
86 HandleMap() : m_lastHandle(0)
87 {
88 }
89
90 int add(T value)
91 {
92 int handle = ++m_lastHandle;
93 m_handleToValueMap.set(handle, value);
94 m_valueToHandleMap.set(value, handle);
95 return handle;
96 }
97
98 T get(int handle)
99 {
100 return m_handleToValueMap.get(handle);
101 }
102
103 int getByValue(T value)
104 {
105 ASSERT(m_valueToHandleMap.contains(value));
106 return m_valueToHandleMap.get(value);
107 }
108
109 T remove(int handle)
110 {
111 T value = m_handleToValueMap.take(handle);
112 m_valueToHandleMap.remove(value);
113 return value;
114 }
115
116 int removeByValue(T value)
117 {
118 int handle = m_valueToHandleMap.take(value);
119 m_handleToValueMap.remove(handle);
120 return handle;
121 }
122
123 void copyValues(Vector<T>& values)
124 {
125 copyKeysToVector(m_valueToHandleMap, values);
126 }
127
128 private:
129 int m_lastHandle;
130 HashMap<int, T> m_handleToValueMap;
131 HashMap<T, int> m_valueToHandleMap;
132 };
133
134 static HandleMap<Dart_Isolate>& isolateMap()
135 {
136 DEFINE_STATIC_LOCAL(HandleMap<Dart_Isolate>, map, ());
137 return map;
138 }
139
140 DartDebugServer& DartDebugServer::shared()
141 {
142 DEFINE_STATIC_LOCAL(DartDebugServer, server, ());
143 return server;
144 }
145
146 DartDebugServer::DartDebugServer()
147 {
148 }
149
150 void DartDebugServer::registerIsolate(Dart_Isolate isolate)
151 {
152 {
153 DartIsolateScope scope(isolate);
154 DartApiScope apiScope;
155 Dart_SetBreakpointHandler(breakpointHandler);
156 Dart_SetExceptionThrownHandler(exceptionHandler);
157 Dart_SetIsolateEventHandler(isolateEventHandler);
158 }
159
160 ensureHooksInstalled();
161
162 int isolateHandle = isolateMap().add(isolate);
163
164 V8Scope v8Scope(0, v8::Debug::GetDebugContext());
165 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
166 v8::Local<v8::Function> registerIsolate = v8::Local<v8::Function>::Cast(dart DebugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "registerIsolate")));
167 v8::Handle<v8::Value> args[] = { v8::Number::New(v8Isolate, isolateHandle) } ;
168 registerIsolate->Call(dartDebugObject(), 1, args);
169 }
170
171 void DartDebugServer::debugBreak()
172 {
173 Vector<Dart_Isolate> isolates;
174 isolateMap().copyValues(isolates);
175 for (Vector<Dart_Isolate>::iterator it = isolates.begin(); it != isolates.en d(); ++it) {
176 Dart_Isolate isolate = *it;
177 if (!m_interruptCalled.contains(isolate)) {
178 m_interruptCalled.add(isolate);
179 Dart_InterruptIsolate(isolate);
180 }
181 m_interruptCancelled.remove(isolate);
182 }
183 }
184
185 void DartDebugServer::cancelDebugBreak()
186 {
187 // FIXME: it would be nice if the DartVM provided an API to directly cancel
188 // a debug break call like V8 does.
189 for (HashSet<Dart_Isolate>::iterator it = m_interruptCalled.begin(); it != m _interruptCalled.end(); ++it) {
190 m_interruptCancelled.add(*it);
191 }
192 }
193
194 void DartDebugServer::unregisterIsolate(Dart_Isolate isolate)
195 {
196 int isolateHandle = isolateMap().removeByValue(isolate);
197
198 // The constructor for V8Scope expects Dart_InitOnce to have been
199 // invoked while it accesses the script execution context
200 // (DartUtilities::scriptExecutionContext). The assert below ensures
201 // that by making sure the DartDebugObject has been setup.
202 ASSERT(!m_dartDebugObject.isEmpty());
203 V8Scope v8Scope(0, v8::Debug::GetDebugContext());
204 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
205 v8::Local<v8::Function> unregisterIsolate = v8::Local<v8::Function>::Cast(da rtDebugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "unregisterIsolate")));
206 v8::Handle<v8::Value> args[] = { v8::Number::New(v8Isolate, isolateHandle) } ;
207 unregisterIsolate->Call(dartDebugObject(), 1, args);
208 }
209
210 void DartDebugServer::isolateLoaded()
211 {
212 Page* page = DartUtilities::domWindowForCurrentIsolate()->document()->page() ;
213 if (!page || !instrumentationForPage(page)->inspectorDebuggerAgent())
214 return;
215
216 ASSERT(Dart_CurrentIsolate());
217 V8Scope v8Scope(DartDOMData::current(), v8::Debug::GetDebugContext());
218
219 int isolateHandle = isolateMap().getByValue(Dart_CurrentIsolate());
220
221 LocalFrame* frame = DartUtilities::domWindowForCurrentIsolate()->frame();
222 DartController* controller = DartController::retrieve(frame);
223 Vector<DartScriptState*> scriptStates;
224 controller->collectScriptStatesForIsolate(Dart_CurrentIsolate(), DartUtiliti es::currentV8Context(), scriptStates);
225 for (size_t i = 0; i< scriptStates.size(); i++)
226 InspectorInstrumentation::didCreateIsolatedContext(frame, scriptStates[i ], 0);
227
228 ASSERT(!m_dartDebugObject.isEmpty());
229 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
230 v8::Local<v8::Function> isolateLoaded = v8::Local<v8::Function>::Cast(dartDe bugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "isolateLoaded")));
231 v8::Handle<v8::Value> args[] = { v8::Number::New(v8Isolate, isolateHandle) } ;
232 isolateLoaded->Call(dartDebugObject(), 1, args);
233 }
234
235 void DartDebugServer::disable()
236 {
237 // Only invoke the disable method when Dart code was executed on the page.
238 if (m_dartDebugObject.isEmpty())
239 return;
240 V8Scope v8Scope(0, v8::Debug::GetDebugContext());
241 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
242 v8::Local<v8::Function> disable = v8::Local<v8::Function>::Cast(dartDebugObj ect()->Get(v8::String::NewFromUtf8(v8Isolate, "disable")));
243 disable->Call(dartDebugObject(), 0, 0);
244 }
245
246 bool lookupTokenLineNumber(const Dart_CodeLocation& location, int* lineNumber, i nt* columnNumber)
247 {
248 Dart_Handle info = Dart_ScriptGetTokenInfo(location.library_id, location.scr ipt_url);
249 ASSERT(Dart_IsList(info));
250 intptr_t infoLength = 0;
251 Dart_Handle ALLOW_UNUSED result = Dart_ListLength(info, &infoLength);
252 ASSERT(!Dart_IsError(result));
253 Dart_Handle elem;
254 bool lineStart = true;
255 int currentLineNumber = 0;
256 for (intptr_t i = 0; i < infoLength; i++) {
257 elem = Dart_ListGetAt(info, i);
258 if (Dart_IsNull(elem)) {
259 lineStart = true;
260 } else {
261 ASSERT(Dart_IsInteger(elem));
262 Dart_Handle exception = 0;
263 int64_t value = DartUtilities::toInteger(elem, exception);
264 ASSERT(!exception);
265 if (lineStart) {
266 // Line number.
267 currentLineNumber = value;
268 lineStart = false;
269 } else {
270 // Token offset.
271 if (value == location.token_pos) {
272 *lineNumber = currentLineNumber;
273 ASSERT(i + 1 < infoLength);
274 *columnNumber = DartUtilities::toInteger(Dart_ListGetAt(info , i + 1), exception);
275 ASSERT(!exception);
276 return true;
277 }
278 i++; // skip columnNumber.
279 }
280 }
281 }
282 return false;
283 }
284
285 v8::Handle<v8::Object> DartDebugServer::createExecutionState(Dart_StackTrace tra ce)
286 {
287 intptr_t length = 0;
288 Dart_Handle ALLOW_UNUSED result = Dart_StackTraceLength(trace, &length);
289 ASSERT(!Dart_IsError(result));
290 ASSERT(length);
291 ASSERT(Dart_CurrentIsolate());
292 int isolateHandle = isolateMap().getByValue(Dart_CurrentIsolate());
293
294 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
295 v8::Local<v8::Array> callFrames = v8::Array::New(v8Isolate, length);
296 for (int i = length - 1; i >= 0; --i) {
297 Dart_ActivationFrame frame = 0;
298 result = Dart_GetActivationFrame(trace, i, &frame);
299 ASSERT(!Dart_IsError(result));
300 Dart_Handle functionName = 0;
301 Dart_Handle function = 0;
302
303 Dart_CodeLocation location;
304 result = Dart_ActivationFrameGetLocation(frame, &functionName, &function , &location);
305 int lineNumber = 0;
306 int columnNumber = 0;
307 lookupTokenLineNumber(location, &lineNumber, &columnNumber);
308 ASSERT(!Dart_IsError(result));
309 Dart_Handle libraryURL = Dart_GetLibraryURL(location.library_id);
310 ASSERT(!Dart_IsError(libraryURL));
311 Dart_Handle library = Dart_LookupLibrary(libraryURL);
312 Dart_Handle localVariablesHandle = Dart_GetLocalVariables(frame);
313
314 v8::Local<v8::Object> callFrame = v8::Object::New(v8Isolate);
315 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "functionName"), V8Con verter::stringToV8(functionName));
316 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "functionProxy"), Dart HandleProxy::create(function));
317 Dart_Handle functionOwner = function;
318 // Walk up the chain of function owners until we reach a type or library handle.
319 while (Dart_IsFunction(functionOwner))
320 functionOwner = Dart_FunctionOwner(functionOwner);
321
322 if (Dart_IsType(functionOwner)) {
323 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "classProxy"), Dar tHandleProxy::createTypeProxy(functionOwner, true));
324 }
325
326 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "scriptURL"), V8Conver ter::stringToV8(location.script_url));
327 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "lineNumber"), v8::Num ber::New(v8Isolate, lineNumber - 1));
328 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "columnNumber"), v8::N umber::New(v8Isolate, columnNumber - 1));
329 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "libraryProxy"), DartH andleProxy::createLibraryProxy(library, location.library_id, Dart_Null(), true)) ;
330 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "localScopeProxy"), Da rtHandleProxy::createLocalScopeProxy(
331 localVariablesHandle));
332 {
333 v8::Local<v8::Object> librariesMap = v8::Object::New(v8Isolate);
334 Dart_Handle libraries = Dart_GetLibraryIds();
335 ASSERT(Dart_IsList(libraries));
336
337 intptr_t librariesLength = 0;
338 Dart_Handle ALLOW_UNUSED result = Dart_ListLength(libraries, &librar iesLength);
339 ASSERT(!Dart_IsError(result));
340 for (intptr_t i = 0; i < librariesLength; ++i) {
341 Dart_Handle libraryIdHandle = Dart_ListGetAt(libraries, i);
342 ASSERT(!Dart_IsError(libraryIdHandle));
343 Dart_Handle exception = 0;
344 int64_t libraryId = DartUtilities::toInteger(libraryIdHandle, ex ception);
345 v8::Local<v8::String> libraryName = V8Converter::stringToV8(Dart _GetLibraryURL(libraryId));
346 v8::Local<v8::Value> libraryProxy = DartHandleProxy::createLibra ryProxy(Dart_GetLibraryFromId(libraryId), libraryId, Dart_Null(), false);
347 librariesMap->Set(libraryName, libraryProxy);
348 }
349 librariesMap->Set(v8::String::NewFromUtf8(v8Isolate, "__proto__"), v 8::Null(v8Isolate));
350 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "librariesProxy"), librariesMap);
351 }
352 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "localVariables"), Dar tHandleProxy::create(localVariablesHandle));
353 callFrame->Set(v8::String::NewFromUtf8(v8Isolate, "isolateHandle"), v8:: Number::New(v8Isolate, isolateHandle));
354 callFrames->Set(i, callFrame);
355 }
356
357 ASSERT(!m_dartDebugObject.isEmpty());
358 v8::Handle<v8::Function> executionStateConstructor = v8::Local<v8::Function> ::Cast(dartDebugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "ExecutionState ")));
359 v8::Handle<v8::Value> args[] = { callFrames };
360 return v8::Local<v8::Object>::Cast(executionStateConstructor->CallAsConstruc tor(1, args));
361 }
362
363 void DartDebugServer::breakpointHandler(Dart_IsolateId isolateId, Dart_Breakpoin t breakpoint, Dart_StackTrace trace)
364 {
365 DartDebugServer::shared().handleBreakpoint(breakpoint, trace);
366 }
367
368 void DartDebugServer::handleBreakpoint(Dart_Breakpoint, Dart_StackTrace trace)
369 {
370 // The constructor for V8Scope expects Dart_InitOnce to have been
371 // invoked while it accesses the script execution context
372 // (DartUtilities::scriptExecutionContext). The assert below ensures
373 // that by making sure the DartDebugObject has been setup.
374 ASSERT(!m_dartDebugObject.isEmpty());
375 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
376 V8Scope v8Scope(0, v8::Debug::GetDebugContext());
377 V8Scope v8WorldScope(0, DartUtilities::currentV8Context());
378 V8EventDetails eventDetails(v8::Break, createExecutionState(trace), v8::Obje ct::New(v8Isolate));
379 PageScriptDebugServer::shared().handleV8DebugEvent(eventDetails);
380 }
381
382 void DartDebugServer::exceptionHandler(Dart_IsolateId isolateId, Dart_Handle exc eption, Dart_StackTrace trace)
383 {
384 DartDebugServer::shared().handleException(exception, trace);
385 }
386
387 void DartDebugServer::isolateEventHandler(Dart_IsolateId isolateId, Dart_Isolate Event kind)
388 {
389 if (kind == kInterrupted) {
390 DartDebugServer::shared().handleInterrupted(isolateId);
391 }
392 }
393
394 void DartDebugServer::handleInterrupted(Dart_IsolateId isolateId)
395 {
396 Dart_Isolate isolate = Dart_GetIsolate(isolateId);
397
398 if (isolate) {
399 ASSERT(isolate == Dart_CurrentIsolate());
400 ASSERT(m_interruptCalled.contains(isolate));
401 m_interruptCalled.remove(isolate);
402 if (m_interruptCancelled.contains(isolate)) {
403 m_interruptCancelled.remove(isolate);
404 return;
405 }
406
407 // FIXME: this is a bit of a hack. V8 was also set to pause on the next
408 // code execution. If it attempts to pause while in the middle of
409 // internal V8 debugger logic it will crash so before we do anything we
410 // need to cancel the pending pause sent to V8.
411 // Perhaps it would be slightly less hacky to send a message to
412 // ScriptDebugServer instructing it to cancel pausing V8.
413 v8::Debug::CancelDebugBreak(DartUtilities::currentV8Context()->GetIsolat e());
414
415 // The user really wants to be paused at the start of the first line of
416 // the Dart method not at the method invocation itself. Otherwise,
417 // stepping to the next call steps out of the executing Dart code
418 // which is not what the user expects.
419 Dart_SetStepInto();
420 }
421 }
422
423 void DartDebugServer::handleException(Dart_Handle exception, Dart_StackTrace tra ce)
424 {
425 // The constructor for V8Scope expects Dart_InitOnce to have been
426 // invoked while it accesses the script execution context
427 // (DartUtilities::scriptExecutionContext). The assert below ensures
428 // that by making sure the DartDebugObject has been setup.
429 ASSERT(!m_dartDebugObject.isEmpty());
430 V8Scope v8Scope(0, v8::Debug::GetDebugContext());
431 V8Scope v8WorldScope(0, DartUtilities::currentV8Context());
432 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
433 v8::Handle<v8::Function> eventDataConstructor = v8::Local<v8::Function>::Cas t(dartDebugObject()->Get(v8::String::NewFromUtf8(v8Isolate, "EventData")));
434 v8::Handle<v8::Value> args[] = { DartHandleProxy::create(exception) };
435 v8::Handle<v8::Object> eventData = v8::Local<v8::Object>::Cast(eventDataCons tructor->CallAsConstructor(1, args));
436 V8EventDetails eventDetails(v8::Exception, createExecutionState(trace), even tData);
437 PageScriptDebugServer::shared().handleV8DebugEvent(eventDetails);
438 }
439
440 static void handleDebugEvent(const v8::FunctionCallbackInfo<v8::Value>& args)
441 {
442 v8::DebugEvent event = static_cast<v8::DebugEvent>(args[0]->Int32Value());
443 v8::Local<v8::Object> executionState = v8::Local<v8::Object>::Cast(args[1]);
444 v8::Local<v8::Object> eventData = v8::Local<v8::Object>::Cast(args[2]);
445 V8EventDetails eventDetails(event, executionState, eventData);
446 PageScriptDebugServer::shared().handleV8DebugEvent(eventDetails);
447 }
448
449 static void scriptsForIsolate(const v8::FunctionCallbackInfo<v8::Value>& args)
450 {
451 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
452 v8::Handle<v8::Array> v8Scripts = v8::Array::New(v8Isolate);
453
454 Dart_Isolate isolate = isolateMap().get(args[0]->Int32Value());
455
456 DartIsolateScope scope(isolate);
457 DartApiScope apiScope;
458
459 LocalFrame* frame = DartUtilities::domWindowForCurrentIsolate()->frame();
460 v8::Handle<v8::Value> contextData = toV8Context(v8Isolate, frame, DOMWrapper World::mainWorld())->GetEmbedderData(0);
461
462 Dart_Handle libraries = Dart_GetLibraryIds();
463 ASSERT(Dart_IsList(libraries));
464
465 intptr_t librariesLength = 0;
466 Dart_Handle ALLOW_UNUSED result = Dart_ListLength(libraries, &librariesLengt h);
467 ASSERT(!Dart_IsError(result));
468 for (intptr_t i = 0; i < librariesLength; ++i) {
469 Dart_Handle libraryIdHandle = Dart_ListGetAt(libraries, i);
470 ASSERT(!Dart_IsError(libraryIdHandle));
471 Dart_Handle exception = 0;
472 int64_t int64LibraryId = DartUtilities::toInteger(libraryIdHandle, excep tion);
473 ASSERT(!exception);
474 intptr_t libraryId = static_cast<intptr_t>(int64LibraryId);
475 ASSERT(libraryId == int64LibraryId);
476
477 Dart_Handle libraryURL = Dart_GetLibraryURL(libraryId);
478 ASSERT(Dart_IsString(libraryURL));
479
480 Dart_SetLibraryDebuggable(libraryId, true);
481
482 Dart_Handle scripts = Dart_GetScriptURLs(libraryURL);
483 ASSERT(Dart_IsList(scripts));
484
485 intptr_t scriptsLength = 0;
486 result = Dart_ListLength(scripts, &scriptsLength);
487 ASSERT(!Dart_IsError(result));
488 for (intptr_t j = 0; j < scriptsLength; ++j) {
489 Dart_Handle scriptURL = Dart_ListGetAt(scripts, j);
490 ASSERT(Dart_IsString(scriptURL));
491
492 Dart_Handle source = Dart_ScriptGetSource(libraryId, scriptURL);
493 ASSERT(Dart_IsString(source));
494
495 v8::Handle<v8::Object> v8Script = v8::Object::New(v8Isolate);
496 v8Script->Set(v8::String::NewFromUtf8(v8Isolate, "libraryId"), v8::N umber::New(v8Isolate, libraryId));
497 v8Script->Set(v8::String::NewFromUtf8(v8Isolate, "scriptURL"), V8Con verter::stringToV8(scriptURL));
498 v8Script->Set(v8::String::NewFromUtf8(v8Isolate, "source"), V8Conver ter::stringToV8(source));
499 v8Script->Set(v8::String::NewFromUtf8(v8Isolate, "contextData"), con textData);
500
501 v8Scripts->Set(v8::Integer::New(v8Isolate, v8Scripts->Length()), v8S cript);
502 }
503 }
504 v8SetReturnValue(args, v8Scripts);
505 }
506
507 static void setBreakpoint(const v8::FunctionCallbackInfo<v8::Value>& args)
508 {
509 Dart_Isolate isolate = isolateMap().get(args[0]->Int32Value());
510
511 DartIsolateScope scope(isolate);
512 DartApiScope apiScope;
513
514 Dart_Handle scriptURL = V8Converter::stringToDart(args[1]);
515 Dart_Handle breakpointId = Dart_SetBreakpoint(scriptURL, args[2]->Int32Value ());
516 if (!Dart_IsError(breakpointId))
517 v8SetReturnValue(args, V8Converter::numberToV8(breakpointId));
518 }
519
520 static void removeBreakpoint(const v8::FunctionCallbackInfo<v8::Value>& args)
521 {
522 Dart_Isolate isolate = isolateMap().get(args[0]->Int32Value());
523
524 DartIsolateScope scope(isolate);
525 DartApiScope apiScope;
526 Dart_Handle ALLOW_UNUSED result = Dart_RemoveBreakpoint(args[1]->Int32Value( ));
527 ASSERT(!Dart_IsError(result));
528 }
529
530 static void getBreakpointLine(const v8::FunctionCallbackInfo<v8::Value>& args)
531 {
532 Dart_Isolate isolate = isolateMap().get(args[0]->Int32Value());
533
534 DartIsolateScope scope(isolate);
535 DartApiScope apiScope;
536 v8SetReturnValue(args, V8Converter::numberToV8(Dart_GetBreakpointLine(args[1 ]->Int32Value())));
537 }
538
539 static void setExceptionPauseInfo(const v8::FunctionCallbackInfo<v8::Value>& arg s)
540 {
541 Dart_Isolate isolate = isolateMap().get(args[0]->Int32Value());
542 bool pauseOnAllExceptions = args[1]->BooleanValue();
543 bool pauseOnUnhandledExceptions = args[2]->BooleanValue();
544
545 DartIsolateScope scope(isolate);
546 DartApiScope apiScope;
547 Dart_ExceptionPauseInfo pauseInfo = kNoPauseOnExceptions;
548 if (pauseOnUnhandledExceptions)
549 pauseInfo = kPauseOnUnhandledExceptions;
550 if (pauseOnAllExceptions)
551 pauseInfo = kPauseOnAllExceptions;
552 Dart_SetExceptionPauseInfo(pauseInfo);
553 }
554
555 static void stepInto(const v8::FunctionCallbackInfo<v8::Value>& args)
556 {
557 Dart_SetStepInto();
558 }
559
560 static void stepOver(const v8::FunctionCallbackInfo<v8::Value>& args)
561 {
562 Dart_SetStepOver();
563 }
564
565 static void stepOut(const v8::FunctionCallbackInfo<v8::Value>& args)
566 {
567 Dart_SetStepOut();
568 }
569
570 static void evaluateInScope(const v8::FunctionCallbackInfo<v8::Value>& args)
571 {
572 v8::Handle<v8::String> expression = args[0]->ToString();
573 v8::Handle<v8::Value> receiver = args[1];
574 v8::Handle<v8::Object> functionProxy = args[2].As<v8::Object>();
575 v8::Handle<v8::Value> localVariablesProxy = args[3];
576 bool disableBreak = args[4]->BooleanValue();
577
578 DartScopes scopes(functionProxy, disableBreak);
579 Dart_Handle target = 0;
580 if (receiver->IsNull() || receiver->IsUndefined()) {
581 target = scopes.handle;
582 // Dart_EvaluateExpr cannot handle targets that are function handles so
583 // we walk up the chain of function owners until we reach a type
584 // or library handle.
585 while (Dart_IsFunction(target))
586 target = Dart_FunctionOwner(target);
587 ASSERT(Dart_IsLibrary(target) || Dart_IsType(target));
588 } else {
589 target = DartHandleProxy::unwrapValue(receiver);
590 }
591
592 ASSERT(!Dart_IsError(target));
593 Dart_Handle localVariables = DartHandleProxy::unwrapValue(localVariablesProx y);
594
595 v8SetReturnValue(args, DartHandleProxy::evaluate(target, V8Converter::string ToDart(expression), localVariables));
596 }
597
598 void DartDebugServer::ensureHooksInstalled()
599 {
600 DEFINE_STATIC_LOCAL(bool, hooksInstalled, (false));
601
602 if (hooksInstalled)
603 return;
604
605 hooksInstalled = true;
606
607 ASSERT(Dart_CurrentIsolate());
608 v8::HandleScope scope(v8::Isolate::GetCurrent());
609 V8Scope v8Scope(0, v8::Debug::GetDebugContext());
610 String dartDebugHooksSource(reinterpret_cast<const char*>(DartDebugHooksSour ce_js), sizeof(DartDebugHooksSource_js));
611
612 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent();
613 m_dartDebugObject.set(v8Isolate, v8::Local<v8::Object>::Cast(v8::Script::Com pile(v8String(v8Isolate, dartDebugHooksSource))->Run()));
614
615 // We must set the v8 context to the page's context before invoking Dart
616 // code because of security checks in the console.log implementation
617 // (see InjectedScriptManager::canAccessInspectedWindow).
618 DartUtilities::currentV8Context()->Enter();
619 v8::Local<v8::Object> evaluateInScopeFunction = v8::FunctionTemplate::New(v8 Isolate, &evaluateInScope)->GetFunction();
620 DartUtilities::currentV8Context()->Exit();
621
622 v8::Local<v8::Object> nativeCallbacks = v8::Object::New(v8Isolate);
623 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "handleDebugEvent"), v8::FunctionTemplate::New(v8Isolate, &handleDebugEvent)->GetFunction());
624 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "scriptsForIsolate") , v8::FunctionTemplate::New(v8Isolate, &scriptsForIsolate)->GetFunction());
625 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "setBreakpoint"), v8 ::FunctionTemplate::New(v8Isolate, &setBreakpoint)->GetFunction());
626 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "removeBreakpoint"), v8::FunctionTemplate::New(v8Isolate, &removeBreakpoint)->GetFunction());
627 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "getBreakpointLine") , v8::FunctionTemplate::New(v8Isolate, &getBreakpointLine)->GetFunction());
628 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "setExceptionPauseIn fo"), v8::FunctionTemplate::New(v8Isolate, &setExceptionPauseInfo)->GetFunction( ));
629 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "stepInto"), v8::Fun ctionTemplate::New(v8Isolate, &stepInto)->GetFunction());
630 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "stepOver"), v8::Fun ctionTemplate::New(v8Isolate, &stepOver)->GetFunction());
631 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "stepOut"), v8::Func tionTemplate::New(v8Isolate, &stepOut)->GetFunction());
632 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "evaluateInScope"), evaluateInScopeFunction);
633 {
634 // Trampoline script is required to properly set calling context before
635 // invoking Dart code because of security checks in console.log
636 // implementation (see InjectedScriptManager::canAccessInspectedWindow).
637 V8Scope v8scope(0);
638 v8::Handle<v8::String> trampolineScript = v8::String::NewFromUtf8(v8Isol ate, "(function (func, args) { return func.apply(this, args); })");
639 v8::Local<v8::Function> trampoline = v8::Local<v8::Function>::Cast(v8::S cript::Compile(trampolineScript)->Run());
640 nativeCallbacks->Set(v8::String::NewFromUtf8(v8Isolate, "invocationTramp oline"), trampoline);
641 }
642 dartDebugObject()->Set(v8::String::NewFromUtf8(v8Isolate, "nativeCallbacks") , nativeCallbacks);
643 }
644
645 v8::Local<v8::Object> DartDebugServer::dartDebugObject()
646 {
647 return m_dartDebugObject.newLocal(v8::Isolate::GetCurrent());
648 }
649
650 }
OLDNEW
« no previous file with comments | « Source/bindings/dart/DartDebugServer.h ('k') | Source/bindings/dart/DartInjectedScript.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698