OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010-2011 Google Inc. All rights reserved. | 2 * Copyright (c) 2010-2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 12 matching lines...) Expand all Loading... |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "bindings/v8/ScriptDebugServer.h" | 32 #include "bindings/v8/ScriptDebugServer.h" |
33 | |
34 #include "DebuggerScriptSource.h" | 33 #include "DebuggerScriptSource.h" |
35 #include "V8JavaScriptCallFrame.h" | 34 #include "V8JavaScriptCallFrame.h" |
36 #include "bindings/dart/DartDebugServer.h" | 35 #include "bindings/dart/DartScriptDebugServer.h" |
37 #include "bindings/v8/ScopedPersistent.h" | 36 #include "bindings/v8/ScopedPersistent.h" |
| 37 #include "bindings/v8/ScriptCallStackFactory.h" |
38 #include "bindings/v8/ScriptController.h" | 38 #include "bindings/v8/ScriptController.h" |
39 #include "bindings/v8/ScriptObject.h" | 39 #include "bindings/v8/ScriptObject.h" |
40 #include "bindings/v8/ScriptSourceCode.h" | 40 #include "bindings/v8/ScriptSourceCode.h" |
41 #include "bindings/v8/V8Binding.h" | 41 #include "bindings/v8/V8Binding.h" |
42 #include "bindings/v8/V8ScriptRunner.h" | 42 #include "bindings/v8/V8ScriptRunner.h" |
43 #include "core/inspector/JavaScriptCallFrame.h" | 43 #include "core/inspector/JavaScriptCallFrame.h" |
| 44 #include "core/inspector/ScriptCallFrame.h" |
44 #include "core/inspector/ScriptDebugListener.h" | 45 #include "core/inspector/ScriptDebugListener.h" |
45 #include "platform/JSONValues.h" | 46 #include "platform/JSONValues.h" |
46 #include "wtf/StdLibExtras.h" | 47 #include "wtf/StdLibExtras.h" |
47 #include "wtf/Vector.h" | 48 #include "wtf/Vector.h" |
48 #include "wtf/dtoa/utils.h" | 49 #include "wtf/dtoa/utils.h" |
49 #include "wtf/text/CString.h" | 50 #include "wtf/text/CString.h" |
50 | 51 |
51 namespace WebCore { | 52 namespace WebCore { |
52 | 53 |
53 namespace { | 54 namespace { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 | 166 |
166 v8::Handle<v8::Value> argv[] = { v8::Int32::New(m_isolate, pauseOnExceptions
State) }; | 167 v8::Handle<v8::Value> argv[] = { v8::Int32::New(m_isolate, pauseOnExceptions
State) }; |
167 callDebuggerMethod("setPauseOnExceptionsState", 1, argv); | 168 callDebuggerMethod("setPauseOnExceptionsState", 1, argv); |
168 } | 169 } |
169 | 170 |
170 void ScriptDebugServer::setPauseOnNextStatement(bool pause) | 171 void ScriptDebugServer::setPauseOnNextStatement(bool pause) |
171 { | 172 { |
172 if (isPaused()) | 173 if (isPaused()) |
173 return; | 174 return; |
174 if (pause) { | 175 if (pause) { |
175 DartDebugServer::shared().debugBreak(); | |
176 v8::Debug::DebugBreak(m_isolate); | 176 v8::Debug::DebugBreak(m_isolate); |
177 } else { | 177 } else { |
178 DartDebugServer::shared().cancelDebugBreak(); | |
179 v8::Debug::CancelDebugBreak(m_isolate); | 178 v8::Debug::CancelDebugBreak(m_isolate); |
180 } | 179 } |
181 } | 180 } |
182 | 181 |
183 bool ScriptDebugServer::canBreakProgram() | 182 bool ScriptDebugServer::canBreakProgram() |
184 { | 183 { |
185 if (!m_breakpointsActivated) | 184 if (!m_breakpointsActivated) |
186 return false; | 185 return false; |
187 v8::HandleScope scope(m_isolate); | 186 v8::HandleScope scope(m_isolate); |
188 return !m_isolate->GetCurrentContext().IsEmpty(); | 187 return !m_isolate->GetCurrentContext().IsEmpty(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 | 235 |
237 v8::Handle<v8::Value> argv[] = { | 236 v8::Handle<v8::Value> argv[] = { |
238 m_executionState.newLocal(m_isolate), | 237 m_executionState.newLocal(m_isolate), |
239 callFrame | 238 callFrame |
240 }; | 239 }; |
241 | 240 |
242 callDebuggerMethod(functionName, 2, argv); | 241 callDebuggerMethod(functionName, 2, argv); |
243 continueProgram(); | 242 continueProgram(); |
244 } | 243 } |
245 | 244 |
246 void ScriptDebugServer::stepOverStatement(const ScriptValue& frame) | 245 void ScriptDebugServer::stepOverStatement(const ActivationFrame& frame) |
247 { | 246 { |
248 stepCommandWithFrame("stepOverStatement", frame); | 247 ASSERT(frame.isJavaScript()); |
| 248 stepCommandWithFrame("stepOverStatement", frame.asJavaScript()); |
249 } | 249 } |
250 | 250 |
251 void ScriptDebugServer::stepOutOfFunction(const ScriptValue& frame) | 251 void ScriptDebugServer::stepOutOfFunction(const ActivationFrame& frame) |
252 { | 252 { |
253 stepCommandWithFrame(stepOutV8MethodName, frame); | 253 ASSERT(frame.isJavaScript()); |
| 254 stepCommandWithFrame(stepOutV8MethodName, frame.asJavaScript()); |
254 } | 255 } |
255 | 256 |
256 bool ScriptDebugServer::setScriptSource(const String& sourceID, const String& ne
wContent, bool preview, String* error, RefPtr<TypeBuilder::Debugger::SetScriptSo
urceError>& errorData, ScriptValue* newCallFrames, RefPtr<JSONObject>* result) | 257 bool ScriptDebugServer::setScriptSource(const String& sourceID, const String& ne
wContent, bool preview, String* error, RefPtr<TypeBuilder::Debugger::SetScriptSo
urceError>& errorData, StackTrace* newCallFrames, RefPtr<JSONObject>& result) |
257 { | 258 { |
258 class EnableLiveEditScope { | 259 class EnableLiveEditScope { |
259 public: | 260 public: |
260 explicit EnableLiveEditScope(v8::Isolate* isolate) : m_isolate(isolate)
{ v8::Debug::SetLiveEditEnabled(m_isolate, true); } | 261 explicit EnableLiveEditScope(v8::Isolate* isolate) : m_isolate(isolate)
{ v8::Debug::SetLiveEditEnabled(m_isolate, true); } |
261 ~EnableLiveEditScope() { v8::Debug::SetLiveEditEnabled(m_isolate, false)
; } | 262 ~EnableLiveEditScope() { v8::Debug::SetLiveEditEnabled(m_isolate, false)
; } |
262 private: | 263 private: |
263 v8::Isolate* m_isolate; | 264 v8::Isolate* m_isolate; |
264 }; | 265 }; |
265 | 266 |
266 ensureDebuggerScriptCompiled(); | 267 ensureDebuggerScriptCompiled(); |
(...skipping 23 matching lines...) Expand all Loading... |
290 } | 291 } |
291 ASSERT(!v8result.IsEmpty()); | 292 ASSERT(!v8result.IsEmpty()); |
292 v8::Local<v8::Object> resultTuple = v8result->ToObject(); | 293 v8::Local<v8::Object> resultTuple = v8result->ToObject(); |
293 int code = static_cast<int>(resultTuple->Get(0)->ToInteger()->Value()); | 294 int code = static_cast<int>(resultTuple->Get(0)->ToInteger()->Value()); |
294 switch (code) { | 295 switch (code) { |
295 case 0: | 296 case 0: |
296 { | 297 { |
297 v8::Local<v8::Value> normalResult = resultTuple->Get(1); | 298 v8::Local<v8::Value> normalResult = resultTuple->Get(1); |
298 RefPtr<JSONValue> jsonResult = v8ToJSONValue(m_isolate, normalResult
, JSONValue::maxDepth); | 299 RefPtr<JSONValue> jsonResult = v8ToJSONValue(m_isolate, normalResult
, JSONValue::maxDepth); |
299 if (jsonResult) | 300 if (jsonResult) |
300 *result = jsonResult->asObject(); | 301 result = jsonResult->asObject(); |
301 // Call stack may have changed after if the edited function was on t
he stack. | 302 // Call stack may have changed after if the edited function was on t
he stack. |
302 if (!preview && isPaused()) | 303 if (!preview && isPaused()) |
303 *newCallFrames = currentCallFrames(); | 304 *newCallFrames = currentCallFrames(); |
304 return true; | 305 return true; |
305 } | 306 } |
306 // Compile error. | 307 // Compile error. |
307 case 1: | 308 case 1: |
308 { | 309 { |
309 RefPtr<TypeBuilder::Debugger::SetScriptSourceError::CompileError> co
mpileError = | 310 RefPtr<TypeBuilder::Debugger::SetScriptSourceError::CompileError> co
mpileError = |
310 TypeBuilder::Debugger::SetScriptSourceError::CompileError::creat
e() | 311 TypeBuilder::Debugger::SetScriptSourceError::CompileError::creat
e() |
(...skipping 24 matching lines...) Expand all Loading... |
335 } else { | 336 } else { |
336 v8::Handle<v8::Value> argv[] = { executionState, v8::Integer::New(m_isol
ate, data) }; | 337 v8::Handle<v8::Value> argv[] = { executionState, v8::Integer::New(m_isol
ate, data) }; |
337 currentCallFrameV8 = callDebuggerMethod("currentCallFrame", WTF_ARRAY_LE
NGTH(argv), argv); | 338 currentCallFrameV8 = callDebuggerMethod("currentCallFrame", WTF_ARRAY_LE
NGTH(argv), argv); |
338 } | 339 } |
339 ASSERT(!currentCallFrameV8.IsEmpty()); | 340 ASSERT(!currentCallFrameV8.IsEmpty()); |
340 if (!currentCallFrameV8->IsObject()) | 341 if (!currentCallFrameV8->IsObject()) |
341 return PassRefPtr<JavaScriptCallFrame>(); | 342 return PassRefPtr<JavaScriptCallFrame>(); |
342 return JavaScriptCallFrame::create(v8::Debug::GetDebugContext(), v8::Handle<
v8::Object>::Cast(currentCallFrameV8)); | 343 return JavaScriptCallFrame::create(v8::Debug::GetDebugContext(), v8::Handle<
v8::Object>::Cast(currentCallFrameV8)); |
343 } | 344 } |
344 | 345 |
345 ScriptValue ScriptDebugServer::currentCallFramesInner(ScopeInfoDetails scopeDeta
ils) | 346 StackTrace ScriptDebugServer::currentCallFramesInner(ScopeInfoDetails scopeDetai
ls) |
346 { | 347 { |
347 v8::HandleScope scope(m_isolate); | 348 v8::HandleScope scope(m_isolate); |
348 v8::Handle<v8::Context> pausedContext = m_pausedContext.IsEmpty() ? m_isolat
e->GetCurrentContext() : m_pausedContext; | 349 v8::Handle<v8::Context> pausedContext = m_pausedContext.IsEmpty() ? m_isolat
e->GetCurrentContext() : m_pausedContext; |
349 if (pausedContext.IsEmpty()) | 350 if (pausedContext.IsEmpty()) |
350 return ScriptValue(); | 351 return StackTrace(ScriptValue()); |
351 | 352 |
352 RefPtr<JavaScriptCallFrame> currentCallFrame = wrapCallFrames(m_executionSta
te.newLocal(m_isolate), 0, scopeDetails); | 353 RefPtr<JavaScriptCallFrame> currentCallFrame = wrapCallFrames(m_executionSta
te.newLocal(m_isolate), 0, scopeDetails); |
353 if (!currentCallFrame) | 354 if (!currentCallFrame) |
354 return ScriptValue(); | 355 return StackTrace(ScriptValue()); |
355 | 356 |
356 v8::Context::Scope contextScope(pausedContext); | 357 v8::Context::Scope contextScope(pausedContext); |
357 return ScriptValue(ScriptState::from(pausedContext), toV8(currentCallFrame.r
elease(), v8::Handle<v8::Object>(), pausedContext->GetIsolate())); | 358 return StackTrace(ScriptValue(ScriptState::from(pausedContext), toV8(current
CallFrame.release(), v8::Handle<v8::Object>(), pausedContext->GetIsolate()))); |
358 } | 359 } |
359 | 360 |
360 ScriptValue ScriptDebugServer::currentCallFrames() | 361 StackTrace ScriptDebugServer::currentCallFrames() |
361 { | 362 { |
362 return currentCallFramesInner(AllScopes); | 363 return currentCallFramesInner(AllScopes); |
363 } | 364 } |
364 | 365 |
365 ScriptValue ScriptDebugServer::currentCallFramesForAsyncStack() | 366 StackTrace ScriptDebugServer::currentCallFramesForAsyncStack() |
366 { | 367 { |
367 return currentCallFramesInner(FastAsyncScopes); | 368 return currentCallFramesInner(FastAsyncScopes); |
368 } | 369 } |
369 | 370 |
370 void ScriptDebugServer::interruptAndRun(PassOwnPtr<Task> task, v8::Isolate* isol
ate) | 371 void ScriptDebugServer::interruptAndRun(PassOwnPtr<Task> task, v8::Isolate* isol
ate) |
371 { | 372 { |
372 v8::Debug::DebugBreakForCommand(isolate, new ClientDataImpl(task)); | 373 v8::Debug::DebugBreakForCommand(isolate, new ClientDataImpl(task)); |
373 } | 374 } |
374 | 375 |
375 void ScriptDebugServer::runPendingTasks() | 376 void ScriptDebugServer::runPendingTasks() |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 if (!stackTrace->GetFrameCount()) { | 488 if (!stackTrace->GetFrameCount()) { |
488 // FIXME: we would prefer to remove the outer check for whether | 489 // FIXME: we would prefer to remove the outer check for whether |
489 // the V8 stack trace is empty and instead just perform the | 490 // the V8 stack trace is empty and instead just perform the |
490 // following check which works correctly for both V8 and Dart. | 491 // following check which works correctly for both V8 and Dart. |
491 v8::Handle<v8::Value> argv[] = { eventDetails.GetExecutionState(
) }; | 492 v8::Handle<v8::Value> argv[] = { eventDetails.GetExecutionState(
) }; |
492 v8::Handle<v8::Value> currentCallFrame = callDebuggerMethod("cur
rentCallFrame", 1, argv); | 493 v8::Handle<v8::Value> currentCallFrame = callDebuggerMethod("cur
rentCallFrame", 1, argv); |
493 ASSERT(!currentCallFrame.IsEmpty()); | 494 ASSERT(!currentCallFrame.IsEmpty()); |
494 if (!currentCallFrame->IsObject()) | 495 if (!currentCallFrame->IsObject()) |
495 return; | 496 return; |
496 } | 497 } |
497 RefPtr<JavaScriptCallFrame> topFrame = wrapCallFrames(eventDetails.G
etExecutionState(), 1, NoScopes); | 498 |
498 if (executeSkipPauseRequest(listener->shouldSkipExceptionPause(topFr
ame), eventDetails.GetExecutionState())) | 499 if (stackTrace->GetFrameCount() && executeSkipPauseRequest(listener-
>shouldSkipExceptionPause(toScriptCallFrame(stackTrace->GetFrame(0))), eventDeta
ils.GetExecutionState())) |
499 return; | 500 return; |
500 v8::Handle<v8::Object> eventData = eventDetails.GetEventData(); | 501 v8::Handle<v8::Object> eventData = eventDetails.GetEventData(); |
501 v8::Handle<v8::Value> exceptionGetterValue = eventData->Get(v8Atomic
String(m_isolate, "exception")); | 502 v8::Handle<v8::Value> exceptionGetterValue = eventData->Get(v8Atomic
String(m_isolate, "exception")); |
502 ASSERT(!exceptionGetterValue.IsEmpty() && exceptionGetterValue->IsFu
nction()); | 503 ASSERT(!exceptionGetterValue.IsEmpty() && exceptionGetterValue->IsFu
nction()); |
503 v8::Handle<v8::Value> exception = V8ScriptRunner::callInternalFuncti
on(v8::Handle<v8::Function>::Cast(exceptionGetterValue), eventData, 0, 0, m_isol
ate); | 504 v8::Handle<v8::Value> exception = V8ScriptRunner::callInternalFuncti
on(v8::Handle<v8::Function>::Cast(exceptionGetterValue), eventData, 0, 0, m_isol
ate); |
504 handleProgramBreak(eventDetails, exception, v8::Handle<v8::Array>())
; | 505 handleProgramBreak(eventDetails, exception, v8::Handle<v8::Array>())
; |
505 } else if (event == v8::Break) { | 506 } else if (event == v8::Break) { |
506 v8::Handle<v8::Function> getBreakpointNumbersFunction = v8::Local<v8
::Function>::Cast(debuggerScript->Get(v8AtomicString(m_isolate, "getBreakpointNu
mbers"))); | 507 v8::Handle<v8::Function> getBreakpointNumbersFunction = v8::Local<v8
::Function>::Cast(debuggerScript->Get(v8AtomicString(m_isolate, "getBreakpointNu
mbers"))); |
507 v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; | 508 v8::Handle<v8::Value> argv[] = { eventDetails.GetEventData() }; |
508 v8::Handle<v8::Value> hitBreakpoints = V8ScriptRunner::callInternalF
unction(getBreakpointNumbersFunction, debuggerScript, WTF_ARRAY_LENGTH(argv), ar
gv, m_isolate); | 509 v8::Handle<v8::Value> hitBreakpoints = V8ScriptRunner::callInternalF
unction(getBreakpointNumbersFunction, debuggerScript, WTF_ARRAY_LENGTH(argv), ar
gv, m_isolate); |
509 ASSERT(hitBreakpoints->IsArray()); | 510 ASSERT(hitBreakpoints->IsArray()); |
510 RefPtr<JavaScriptCallFrame> topFrame = wrapCallFrames(eventDetails.G
etExecutionState(), 1, NoScopes); | 511 v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackT
race(m_isolate, 1); |
| 512 ScriptCallFrame topCallFrame = toScriptCallFrame(stackTrace->GetFram
e(0)); |
| 513 |
511 ScriptDebugListener::SkipPauseRequest skipRequest; | 514 ScriptDebugListener::SkipPauseRequest skipRequest; |
512 if (v8::Handle<v8::Array>::Cast(hitBreakpoints)->Length()) | 515 if (v8::Handle<v8::Array>::Cast(hitBreakpoints)->Length()) |
513 skipRequest = listener->shouldSkipBreakpointPause(topFrame); | 516 skipRequest = listener->shouldSkipBreakpointPause(topCallFrame); |
514 else | 517 else |
515 skipRequest = listener->shouldSkipStepPause(topFrame); | 518 skipRequest = listener->shouldSkipStepPause(topCallFrame); |
516 if (executeSkipPauseRequest(skipRequest, eventDetails.GetExecutionSt
ate())) | 519 if (executeSkipPauseRequest(skipRequest, eventDetails.GetExecutionSt
ate())) |
517 return; | 520 return; |
518 handleProgramBreak(eventDetails, v8::Handle<v8::Value>(), hitBreakpo
ints.As<v8::Array>()); | 521 handleProgramBreak(eventDetails, v8::Handle<v8::Value>(), hitBreakpo
ints.As<v8::Array>()); |
519 } | 522 } |
520 } | 523 } |
521 } | 524 } |
522 | 525 |
523 void ScriptDebugServer::dispatchDidParseSource(ScriptDebugListener* listener, v8
::Handle<v8::Object> object) | 526 void ScriptDebugServer::dispatchDidParseSource(ScriptDebugListener* listener, v8
::Handle<v8::Object> object) |
524 { | 527 { |
525 v8::Handle<v8::Value> id = object->Get(v8AtomicString(m_isolate, "id")); | 528 v8::Handle<v8::Value> id = object->Get(v8AtomicString(m_isolate, "id")); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 { | 657 { |
655 return PassOwnPtr<ScriptSourceCode>(); | 658 return PassOwnPtr<ScriptSourceCode>(); |
656 } | 659 } |
657 | 660 |
658 String ScriptDebugServer::preprocessEventListener(LocalFrame*, const String& sou
rce, const String& url, const String& functionName) | 661 String ScriptDebugServer::preprocessEventListener(LocalFrame*, const String& sou
rce, const String& url, const String& functionName) |
659 { | 662 { |
660 return source; | 663 return source; |
661 } | 664 } |
662 | 665 |
663 } // namespace WebCore | 666 } // namespace WebCore |
OLD | NEW |