| 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 18 matching lines...) Expand all Loading... |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "core/inspector/V8Debugger.h" | 32 #include "core/inspector/V8Debugger.h" |
| 33 | 33 |
| 34 #include "bindings/core/v8/ScriptValue.h" | 34 #include "bindings/core/v8/ScriptValue.h" |
| 35 #include "bindings/core/v8/V8Binding.h" | 35 #include "bindings/core/v8/V8Binding.h" |
| 36 #include "bindings/core/v8/V8ScriptRunner.h" | 36 #include "bindings/core/v8/V8ScriptRunner.h" |
| 37 #include "bindings/core/v8/inspector/V8JavaScriptCallFrame.h" | 37 #include "bindings/core/v8/inspector/V8JavaScriptCallFrame.h" |
| 38 #include "core/inspector/JavaScriptCallFrame.h" | 38 #include "core/inspector/JavaScriptCallFrame.h" |
| 39 #include "core/inspector/ScriptDebugListener.h" | |
| 40 #include "platform/JSONValues.h" | 39 #include "platform/JSONValues.h" |
| 41 #include "wtf/StdLibExtras.h" | 40 #include "wtf/StdLibExtras.h" |
| 42 #include "wtf/Vector.h" | 41 #include "wtf/Vector.h" |
| 43 #include "wtf/dtoa/utils.h" | 42 #include "wtf/dtoa/utils.h" |
| 44 #include "wtf/text/CString.h" | 43 #include "wtf/text/CString.h" |
| 45 | 44 |
| 46 namespace blink { | 45 namespace blink { |
| 47 | 46 |
| 48 namespace { | 47 namespace { |
| 49 const char stepIntoV8MethodName[] = "stepIntoStatement"; | 48 const char stepIntoV8MethodName[] = "stepIntoStatement"; |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 v8::Local<v8::Array> hitBreakpoints; | 572 v8::Local<v8::Array> hitBreakpoints; |
| 574 thisPtr->handleProgramBreak(pausedScriptState, v8::Local<v8::Object>::Cast(i
nfo[0]), exception, hitBreakpoints); | 573 thisPtr->handleProgramBreak(pausedScriptState, v8::Local<v8::Object>::Cast(i
nfo[0]), exception, hitBreakpoints); |
| 575 } | 574 } |
| 576 | 575 |
| 577 void V8Debugger::handleProgramBreak(ScriptState* pausedScriptState, v8::Local<v8
::Object> executionState, v8::Local<v8::Value> exception, v8::Local<v8::Array> h
itBreakpointNumbers, bool isPromiseRejection) | 576 void V8Debugger::handleProgramBreak(ScriptState* pausedScriptState, v8::Local<v8
::Object> executionState, v8::Local<v8::Value> exception, v8::Local<v8::Array> h
itBreakpointNumbers, bool isPromiseRejection) |
| 578 { | 577 { |
| 579 // Don't allow nested breaks. | 578 // Don't allow nested breaks. |
| 580 if (m_runningNestedMessageLoop) | 579 if (m_runningNestedMessageLoop) |
| 581 return; | 580 return; |
| 582 | 581 |
| 583 ScriptDebugListener* listener = m_client->getDebugListenerForContext(pausedS
criptState->context()); | |
| 584 if (!listener) | |
| 585 return; | |
| 586 | |
| 587 Vector<String> breakpointIds; | 582 Vector<String> breakpointIds; |
| 588 if (!hitBreakpointNumbers.IsEmpty()) { | 583 if (!hitBreakpointNumbers.IsEmpty()) { |
| 589 breakpointIds.resize(hitBreakpointNumbers->Length()); | 584 breakpointIds.resize(hitBreakpointNumbers->Length()); |
| 590 for (size_t i = 0; i < hitBreakpointNumbers->Length(); i++) { | 585 for (size_t i = 0; i < hitBreakpointNumbers->Length(); i++) { |
| 591 v8::Local<v8::Value> hitBreakpointNumber = hitBreakpointNumbers->Get
(i); | 586 v8::Local<v8::Value> hitBreakpointNumber = hitBreakpointNumbers->Get
(i); |
| 592 ASSERT(!hitBreakpointNumber.IsEmpty() && hitBreakpointNumber->IsInt3
2()); | 587 ASSERT(!hitBreakpointNumber.IsEmpty() && hitBreakpointNumber->IsInt3
2()); |
| 593 breakpointIds[i] = String::number(hitBreakpointNumber->Int32Value())
; | 588 breakpointIds[i] = String::number(hitBreakpointNumber->Int32Value())
; |
| 594 } | 589 } |
| 595 } | 590 } |
| 596 | 591 |
| 597 m_pausedScriptState = pausedScriptState; | 592 m_pausedScriptState = pausedScriptState; |
| 598 m_executionState = executionState; | 593 m_executionState = executionState; |
| 599 SkipPauseRequest result = listener->didPause(pausedScriptState, currentCallF
rames(), ScriptValue(pausedScriptState, exception), breakpointIds, isPromiseReje
ction); | 594 SkipPauseRequest result = m_client->didPause(pausedScriptState, currentCallF
rames(), ScriptValue(pausedScriptState, exception), breakpointIds, isPromiseReje
ction); |
| 600 if (result == NoSkip) { | 595 if (result == NoSkip) { |
| 601 m_runningNestedMessageLoop = true; | 596 m_runningNestedMessageLoop = true; |
| 602 m_client->runMessageLoopOnPause(pausedScriptState->context()); | 597 m_client->runMessageLoopOnPause(pausedScriptState->context()); |
| 603 m_runningNestedMessageLoop = false; | 598 m_runningNestedMessageLoop = false; |
| 604 } | 599 } |
| 605 m_pausedScriptState.clear(); | 600 m_pausedScriptState.clear(); |
| 606 m_executionState.Clear(); | 601 m_executionState.Clear(); |
| 607 | 602 |
| 608 if (result == StepFrame) { | 603 if (result == StepFrame) { |
| 609 v8::Local<v8::Value> argv[] = { executionState }; | 604 v8::Local<v8::Value> argv[] = { executionState }; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 634 { | 629 { |
| 635 if (!enabled()) | 630 if (!enabled()) |
| 636 return; | 631 return; |
| 637 v8::DebugEvent event = eventDetails.GetEvent(); | 632 v8::DebugEvent event = eventDetails.GetEvent(); |
| 638 if (event != v8::AsyncTaskEvent && event != v8::Break && event != v8::Except
ion && event != v8::AfterCompile && event != v8::BeforeCompile && event != v8::C
ompileError && event != v8::PromiseEvent) | 633 if (event != v8::AsyncTaskEvent && event != v8::Break && event != v8::Except
ion && event != v8::AfterCompile && event != v8::BeforeCompile && event != v8::C
ompileError && event != v8::PromiseEvent) |
| 639 return; | 634 return; |
| 640 | 635 |
| 641 v8::Local<v8::Context> eventContext = eventDetails.GetEventContext(); | 636 v8::Local<v8::Context> eventContext = eventDetails.GetEventContext(); |
| 642 ASSERT(!eventContext.IsEmpty()); | 637 ASSERT(!eventContext.IsEmpty()); |
| 643 | 638 |
| 644 ScriptDebugListener* listener = m_client->getDebugListenerForContext(eventCo
ntext); | 639 v8::HandleScope scope(m_isolate); |
| 645 if (listener) { | 640 if (event == v8::AfterCompile || event == v8::CompileError) { |
| 646 v8::HandleScope scope(m_isolate); | 641 v8::Context::Scope contextScope(debuggerContext()); |
| 647 if (event == v8::AfterCompile || event == v8::CompileError) { | 642 v8::Local<v8::Value> argv[] = { eventDetails.GetEventData() }; |
| 648 v8::Context::Scope contextScope(debuggerContext()); | 643 v8::Local<v8::Value> value = callDebuggerMethod("getAfterCompileScript",
1, argv).ToLocalChecked(); |
| 649 v8::Local<v8::Value> argv[] = { eventDetails.GetEventData() }; | 644 ASSERT(value->IsObject()); |
| 650 v8::Local<v8::Value> value = callDebuggerMethod("getAfterCompileScri
pt", 1, argv).ToLocalChecked(); | 645 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value); |
| 651 ASSERT(value->IsObject()); | 646 m_client->didParseSource(eventContext, createParsedScript(object, event
!= v8::AfterCompile ? CompileError : CompileSuccess)); |
| 652 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value); | 647 } else if (event == v8::Exception) { |
| 653 listener->didParseSource(createParsedScript(object, event != v8::Aft
erCompile ? CompileError : CompileSuccess)); | 648 v8::Local<v8::Object> eventData = eventDetails.GetEventData(); |
| 654 } else if (event == v8::Exception) { | 649 v8::Local<v8::Value> exception = callInternalGetterFunction(eventData, "
exception"); |
| 655 v8::Local<v8::Object> eventData = eventDetails.GetEventData(); | 650 v8::Local<v8::Value> promise = callInternalGetterFunction(eventData, "pr
omise"); |
| 656 v8::Local<v8::Value> exception = callInternalGetterFunction(eventDat
a, "exception"); | 651 bool isPromiseRejection = !promise.IsEmpty() && promise->IsObject(); |
| 657 v8::Local<v8::Value> promise = callInternalGetterFunction(eventData,
"promise"); | 652 handleProgramBreak(ScriptState::from(eventContext), eventDetails.GetExec
utionState(), exception, v8::Local<v8::Array>(), isPromiseRejection); |
| 658 bool isPromiseRejection = !promise.IsEmpty() && promise->IsObject(); | 653 } else if (event == v8::Break) { |
| 659 handleProgramBreak(ScriptState::from(eventContext), eventDetails.Get
ExecutionState(), exception, v8::Local<v8::Array>(), isPromiseRejection); | 654 v8::Local<v8::Value> argv[] = { eventDetails.GetEventData() }; |
| 660 } else if (event == v8::Break) { | 655 v8::Local<v8::Value> hitBreakpoints = callDebuggerMethod("getBreakpointN
umbers", 1, argv).ToLocalChecked(); |
| 661 v8::Local<v8::Value> argv[] = { eventDetails.GetEventData() }; | 656 ASSERT(hitBreakpoints->IsArray()); |
| 662 v8::Local<v8::Value> hitBreakpoints = callDebuggerMethod("getBreakpo
intNumbers", 1, argv).ToLocalChecked(); | 657 handleProgramBreak(ScriptState::from(eventContext), eventDetails.GetExec
utionState(), v8::Local<v8::Value>(), hitBreakpoints.As<v8::Array>()); |
| 663 ASSERT(hitBreakpoints->IsArray()); | 658 } else if (event == v8::AsyncTaskEvent) { |
| 664 handleProgramBreak(ScriptState::from(eventContext), eventDetails.Get
ExecutionState(), v8::Local<v8::Value>(), hitBreakpoints.As<v8::Array>()); | 659 if (m_client->v8AsyncTaskEventsEnabled(ScriptState::from(eventContext))) |
| 665 } else if (event == v8::AsyncTaskEvent) { | 660 handleV8AsyncTaskEvent(ScriptState::from(eventContext), eventDetails
.GetExecutionState(), eventDetails.GetEventData()); |
| 666 if (listener->v8AsyncTaskEventsEnabled()) | 661 } else if (event == v8::PromiseEvent) { |
| 667 handleV8AsyncTaskEvent(listener, ScriptState::from(eventContext)
, eventDetails.GetExecutionState(), eventDetails.GetEventData()); | 662 if (m_client->v8PromiseEventsEnabled(ScriptState::from(eventContext))) |
| 668 } else if (event == v8::PromiseEvent) { | 663 handleV8PromiseEvent(ScriptState::from(eventContext), eventDetails.G
etExecutionState(), eventDetails.GetEventData()); |
| 669 if (listener->v8PromiseEventsEnabled()) | |
| 670 handleV8PromiseEvent(listener, ScriptState::from(eventContext),
eventDetails.GetExecutionState(), eventDetails.GetEventData()); | |
| 671 } | |
| 672 } | 664 } |
| 673 } | 665 } |
| 674 | 666 |
| 675 void V8Debugger::handleV8AsyncTaskEvent(ScriptDebugListener* listener, ScriptSta
te* pausedScriptState, v8::Local<v8::Object> executionState, v8::Local<v8::Objec
t> eventData) | 667 void V8Debugger::handleV8AsyncTaskEvent(ScriptState* pausedScriptState, v8::Loca
l<v8::Object> executionState, v8::Local<v8::Object> eventData) |
| 676 { | 668 { |
| 677 String type = toCoreStringWithUndefinedOrNullCheck(callInternalGetterFunctio
n(eventData, "type")); | 669 String type = toCoreStringWithUndefinedOrNullCheck(callInternalGetterFunctio
n(eventData, "type")); |
| 678 String name = toCoreStringWithUndefinedOrNullCheck(callInternalGetterFunctio
n(eventData, "name")); | 670 String name = toCoreStringWithUndefinedOrNullCheck(callInternalGetterFunctio
n(eventData, "name")); |
| 679 int id = callInternalGetterFunction(eventData, "id")->ToInteger(m_isolate)->
Value(); | 671 int id = callInternalGetterFunction(eventData, "id")->ToInteger(m_isolate)->
Value(); |
| 680 | 672 |
| 681 m_pausedScriptState = pausedScriptState; | 673 m_pausedScriptState = pausedScriptState; |
| 682 m_executionState = executionState; | 674 m_executionState = executionState; |
| 683 listener->didReceiveV8AsyncTaskEvent(pausedScriptState, type, name, id); | 675 m_client->didReceiveV8AsyncTaskEvent(pausedScriptState, type, name, id); |
| 684 m_pausedScriptState.clear(); | 676 m_pausedScriptState.clear(); |
| 685 m_executionState.Clear(); | 677 m_executionState.Clear(); |
| 686 } | 678 } |
| 687 | 679 |
| 688 void V8Debugger::handleV8PromiseEvent(ScriptDebugListener* listener, ScriptState
* pausedScriptState, v8::Local<v8::Object> executionState, v8::Local<v8::Object>
eventData) | 680 void V8Debugger::handleV8PromiseEvent(ScriptState* pausedScriptState, v8::Local<
v8::Object> executionState, v8::Local<v8::Object> eventData) |
| 689 { | 681 { |
| 690 v8::Local<v8::Value> argv[] = { eventData }; | 682 v8::Local<v8::Value> argv[] = { eventData }; |
| 691 v8::Local<v8::Value> value = callDebuggerMethod("getPromiseDetails", 1, argv
).ToLocalChecked(); | 683 v8::Local<v8::Value> value = callDebuggerMethod("getPromiseDetails", 1, argv
).ToLocalChecked(); |
| 692 ASSERT(value->IsObject()); | 684 ASSERT(value->IsObject()); |
| 693 v8::Local<v8::Object> promiseDetails = v8::Local<v8::Object>::Cast(value); | 685 v8::Local<v8::Object> promiseDetails = v8::Local<v8::Object>::Cast(value); |
| 694 v8::Local<v8::Object> promise = promiseDetails->Get(v8InternalizedString("pr
omise"))->ToObject(m_isolate); | 686 v8::Local<v8::Object> promise = promiseDetails->Get(v8InternalizedString("pr
omise"))->ToObject(m_isolate); |
| 695 int status = promiseDetails->Get(v8InternalizedString("status"))->ToInteger(
m_isolate)->Value(); | 687 int status = promiseDetails->Get(v8InternalizedString("status"))->ToInteger(
m_isolate)->Value(); |
| 696 v8::Local<v8::Value> parentPromise = promiseDetails->Get(v8InternalizedStrin
g("parentPromise")); | 688 v8::Local<v8::Value> parentPromise = promiseDetails->Get(v8InternalizedStrin
g("parentPromise")); |
| 697 | 689 |
| 698 m_pausedScriptState = pausedScriptState; | 690 m_pausedScriptState = pausedScriptState; |
| 699 m_executionState = executionState; | 691 m_executionState = executionState; |
| 700 listener->didReceiveV8PromiseEvent(pausedScriptState, promise, parentPromise
, status); | 692 m_client->didReceiveV8PromiseEvent(pausedScriptState, promise, parentPromise
, status); |
| 701 m_pausedScriptState.clear(); | 693 m_pausedScriptState.clear(); |
| 702 m_executionState.Clear(); | 694 m_executionState.Clear(); |
| 703 } | 695 } |
| 704 | 696 |
| 705 V8Debugger::ParsedScript V8Debugger::createParsedScript(v8::Local<v8::Object> ob
ject, CompileResult compileResult) | 697 V8Debugger::ParsedScript V8Debugger::createParsedScript(v8::Local<v8::Object> ob
ject, CompileResult compileResult) |
| 706 { | 698 { |
| 707 v8::Local<v8::Value> id = object->Get(v8InternalizedString("id")); | 699 v8::Local<v8::Value> id = object->Get(v8InternalizedString("id")); |
| 708 ASSERT(!id.IsEmpty() && id->IsInt32()); | 700 ASSERT(!id.IsEmpty() && id->IsInt32()); |
| 709 | 701 |
| 710 ParsedScript parsedScript; | 702 ParsedScript parsedScript; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 return callDebuggerMethod("setFunctionVariableValue", 4, argv); | 792 return callDebuggerMethod("setFunctionVariableValue", 4, argv); |
| 801 } | 793 } |
| 802 | 794 |
| 803 | 795 |
| 804 bool V8Debugger::isPaused() | 796 bool V8Debugger::isPaused() |
| 805 { | 797 { |
| 806 return m_pausedScriptState; | 798 return m_pausedScriptState; |
| 807 } | 799 } |
| 808 | 800 |
| 809 } // namespace blink | 801 } // namespace blink |
| OLD | NEW |