| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/inspector/V8Debugger.h" | 5 #include "src/inspector/V8Debugger.h" |
| 6 | 6 |
| 7 #include "src/inspector/DebuggerScript.h" | 7 #include "src/inspector/DebuggerScript.h" |
| 8 #include "src/inspector/ScriptBreakpoint.h" | 8 #include "src/inspector/ScriptBreakpoint.h" |
| 9 #include "src/inspector/StringUtil.h" | 9 #include "src/inspector/StringUtil.h" |
| 10 #include "src/inspector/V8Compat.h" | |
| 11 #include "src/inspector/V8DebuggerAgentImpl.h" | 10 #include "src/inspector/V8DebuggerAgentImpl.h" |
| 12 #include "src/inspector/V8InspectorImpl.h" | 11 #include "src/inspector/V8InspectorImpl.h" |
| 13 #include "src/inspector/V8InternalValueType.h" | 12 #include "src/inspector/V8InternalValueType.h" |
| 14 #include "src/inspector/V8StackTraceImpl.h" | 13 #include "src/inspector/V8StackTraceImpl.h" |
| 15 #include "src/inspector/V8ValueCopier.h" | 14 #include "src/inspector/V8ValueCopier.h" |
| 16 #include "src/inspector/protocol/Protocol.h" | 15 #include "src/inspector/protocol/Protocol.h" |
| 17 #include "src/inspector/public/V8InspectorClient.h" | |
| 18 | 16 |
| 19 namespace v8_inspector { | 17 namespace v8_inspector { |
| 20 | 18 |
| 21 namespace { | 19 namespace { |
| 22 const char stepIntoV8MethodName[] = "stepIntoStatement"; | 20 const char stepIntoV8MethodName[] = "stepIntoStatement"; |
| 23 const char stepOutV8MethodName[] = "stepOutOfFunction"; | 21 const char stepOutV8MethodName[] = "stepOutOfFunction"; |
| 24 static const char v8AsyncTaskEventEnqueue[] = "enqueue"; | 22 static const char v8AsyncTaskEventEnqueue[] = "enqueue"; |
| 25 static const char v8AsyncTaskEventWillHandle[] = "willHandle"; | 23 static const char v8AsyncTaskEventWillHandle[] = "willHandle"; |
| 26 static const char v8AsyncTaskEventDidHandle[] = "didHandle"; | 24 static const char v8AsyncTaskEventDidHandle[] = "didHandle"; |
| 27 | 25 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 v8::Context::Scope contextScope(debuggerContext()); | 184 v8::Context::Scope contextScope(debuggerContext()); |
| 187 | 185 |
| 188 v8::Local<v8::Function> clearBreakpoints = | 186 v8::Local<v8::Function> clearBreakpoints = |
| 189 v8::Local<v8::Function>::Cast(m_debuggerScript.Get(m_isolate)->Get( | 187 v8::Local<v8::Function>::Cast(m_debuggerScript.Get(m_isolate)->Get( |
| 190 toV8StringInternalized(m_isolate, "clearBreakpoints"))); | 188 toV8StringInternalized(m_isolate, "clearBreakpoints"))); |
| 191 v8::Debug::Call(debuggerContext(), clearBreakpoints).ToLocalChecked(); | 189 v8::Debug::Call(debuggerContext(), clearBreakpoints).ToLocalChecked(); |
| 192 } | 190 } |
| 193 | 191 |
| 194 void V8Debugger::setBreakpointsActivated(bool activated) { | 192 void V8Debugger::setBreakpointsActivated(bool activated) { |
| 195 if (!enabled()) { | 193 if (!enabled()) { |
| 196 NOTREACHED(); | 194 UNREACHABLE(); |
| 197 return; | 195 return; |
| 198 } | 196 } |
| 199 v8::HandleScope scope(m_isolate); | 197 v8::HandleScope scope(m_isolate); |
| 200 v8::Context::Scope contextScope(debuggerContext()); | 198 v8::Context::Scope contextScope(debuggerContext()); |
| 201 | 199 |
| 202 v8::Local<v8::Object> info = v8::Object::New(m_isolate); | 200 v8::Local<v8::Object> info = v8::Object::New(m_isolate); |
| 203 info->Set(toV8StringInternalized(m_isolate, "enabled"), | 201 info->Set(toV8StringInternalized(m_isolate, "enabled"), |
| 204 v8::Boolean::New(m_isolate, activated)); | 202 v8::Boolean::New(m_isolate, activated)); |
| 205 v8::Local<v8::Function> setBreakpointsActivated = | 203 v8::Local<v8::Function> setBreakpointsActivated = |
| 206 v8::Local<v8::Function>::Cast(m_debuggerScript.Get(m_isolate)->Get( | 204 v8::Local<v8::Function>::Cast(m_debuggerScript.Get(m_isolate)->Get( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 v8::Local<v8::Array> hitBreakpoints; | 251 v8::Local<v8::Array> hitBreakpoints; |
| 254 handleProgramBreak(m_pausedContext, m_executionState, exception, | 252 handleProgramBreak(m_pausedContext, m_executionState, exception, |
| 255 hitBreakpoints); | 253 hitBreakpoints); |
| 256 return; | 254 return; |
| 257 } | 255 } |
| 258 | 256 |
| 259 if (!canBreakProgram()) return; | 257 if (!canBreakProgram()) return; |
| 260 | 258 |
| 261 v8::HandleScope scope(m_isolate); | 259 v8::HandleScope scope(m_isolate); |
| 262 v8::Local<v8::Function> breakFunction; | 260 v8::Local<v8::Function> breakFunction; |
| 263 if (!V8_FUNCTION_NEW_REMOVE_PROTOTYPE(m_isolate->GetCurrentContext(), | 261 if (!v8::Function::New(m_isolate->GetCurrentContext(), |
| 264 &V8Debugger::breakProgramCallback, | 262 &V8Debugger::breakProgramCallback, |
| 265 v8::External::New(m_isolate, this), 0) | 263 v8::External::New(m_isolate, this), 0, |
| 264 v8::ConstructorBehavior::kThrow) |
| 266 .ToLocal(&breakFunction)) | 265 .ToLocal(&breakFunction)) |
| 267 return; | 266 return; |
| 268 v8::Debug::Call(debuggerContext(), breakFunction).ToLocalChecked(); | 267 v8::Debug::Call(debuggerContext(), breakFunction).ToLocalChecked(); |
| 269 } | 268 } |
| 270 | 269 |
| 271 void V8Debugger::continueProgram() { | 270 void V8Debugger::continueProgram() { |
| 272 if (isPaused()) m_inspector->client()->quitMessageLoopOnPause(); | 271 if (isPaused()) m_inspector->client()->quitMessageLoopOnPause(); |
| 273 m_pausedContext.Clear(); | 272 m_pausedContext.Clear(); |
| 274 m_executionState.Clear(); | 273 m_executionState.Clear(); |
| 275 } | 274 } |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 // The scopes for the ids are defined by the eventData.name namespaces. There | 585 // The scopes for the ids are defined by the eventData.name namespaces. There |
| 587 // are currently two namespaces: "Object." and "Promise.". | 586 // are currently two namespaces: "Object." and "Promise.". |
| 588 void* ptr = reinterpret_cast<void*>(id * 4 + (name[0] == 'P' ? 2 : 0) + 1); | 587 void* ptr = reinterpret_cast<void*>(id * 4 + (name[0] == 'P' ? 2 : 0) + 1); |
| 589 if (type == v8AsyncTaskEventEnqueue) | 588 if (type == v8AsyncTaskEventEnqueue) |
| 590 asyncTaskScheduled(name, ptr, false); | 589 asyncTaskScheduled(name, ptr, false); |
| 591 else if (type == v8AsyncTaskEventWillHandle) | 590 else if (type == v8AsyncTaskEventWillHandle) |
| 592 asyncTaskStarted(ptr); | 591 asyncTaskStarted(ptr); |
| 593 else if (type == v8AsyncTaskEventDidHandle) | 592 else if (type == v8AsyncTaskEventDidHandle) |
| 594 asyncTaskFinished(ptr); | 593 asyncTaskFinished(ptr); |
| 595 else | 594 else |
| 596 NOTREACHED(); | 595 UNREACHABLE(); |
| 597 } | 596 } |
| 598 | 597 |
| 599 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() { | 598 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() { |
| 600 if (!m_currentStacks.size()) return nullptr; | 599 if (!m_currentStacks.size()) return nullptr; |
| 601 return m_currentStacks.back().get(); | 600 return m_currentStacks.back().get(); |
| 602 } | 601 } |
| 603 | 602 |
| 604 void V8Debugger::compileDebuggerScript() { | 603 void V8Debugger::compileDebuggerScript() { |
| 605 if (!m_debuggerScript.IsEmpty()) { | 604 if (!m_debuggerScript.IsEmpty()) { |
| 606 NOTREACHED(); | 605 UNREACHABLE(); |
| 607 return; | 606 return; |
| 608 } | 607 } |
| 609 | 608 |
| 610 v8::HandleScope scope(m_isolate); | 609 v8::HandleScope scope(m_isolate); |
| 611 v8::Context::Scope contextScope(debuggerContext()); | 610 v8::Context::Scope contextScope(debuggerContext()); |
| 612 | 611 |
| 613 v8::Local<v8::String> scriptValue = | 612 v8::Local<v8::String> scriptValue = |
| 614 v8::String::NewFromUtf8(m_isolate, DebuggerScript_js, | 613 v8::String::NewFromUtf8(m_isolate, DebuggerScript_js, |
| 615 v8::NewStringType::kInternalized, | 614 v8::NewStringType::kInternalized, |
| 616 sizeof(DebuggerScript_js)) | 615 sizeof(DebuggerScript_js)) |
| 617 .ToLocalChecked(); | 616 .ToLocalChecked(); |
| 618 v8::Local<v8::Value> value; | 617 v8::Local<v8::Value> value; |
| 619 if (!m_inspector->compileAndRunInternalScript(debuggerContext(), scriptValue) | 618 if (!m_inspector->compileAndRunInternalScript(debuggerContext(), scriptValue) |
| 620 .ToLocal(&value)) { | 619 .ToLocal(&value)) { |
| 621 NOTREACHED(); | 620 UNREACHABLE(); |
| 622 return; | 621 return; |
| 623 } | 622 } |
| 624 DCHECK(value->IsObject()); | 623 DCHECK(value->IsObject()); |
| 625 m_debuggerScript.Reset(m_isolate, value.As<v8::Object>()); | 624 m_debuggerScript.Reset(m_isolate, value.As<v8::Object>()); |
| 626 } | 625 } |
| 627 | 626 |
| 628 v8::Local<v8::Context> V8Debugger::debuggerContext() const { | 627 v8::Local<v8::Context> V8Debugger::debuggerContext() const { |
| 629 DCHECK(!m_debuggerContext.IsEmpty()); | 628 DCHECK(!m_debuggerContext.IsEmpty()); |
| 630 return m_debuggerContext.Get(m_isolate); | 629 return m_debuggerContext.Get(m_isolate); |
| 631 } | 630 } |
| 632 | 631 |
| 633 v8::MaybeLocal<v8::Value> V8Debugger::functionScopes( | 632 v8::MaybeLocal<v8::Value> V8Debugger::functionScopes( |
| 634 v8::Local<v8::Context> context, v8::Local<v8::Function> function) { | 633 v8::Local<v8::Context> context, v8::Local<v8::Function> function) { |
| 635 if (!enabled()) { | 634 if (!enabled()) { |
| 636 NOTREACHED(); | 635 UNREACHABLE(); |
| 637 return v8::Local<v8::Value>::New(m_isolate, v8::Undefined(m_isolate)); | 636 return v8::Local<v8::Value>::New(m_isolate, v8::Undefined(m_isolate)); |
| 638 } | 637 } |
| 639 v8::Local<v8::Value> argv[] = {function}; | 638 v8::Local<v8::Value> argv[] = {function}; |
| 640 v8::Local<v8::Value> scopesValue; | 639 v8::Local<v8::Value> scopesValue; |
| 641 if (!callDebuggerMethod("getFunctionScopes", 1, argv).ToLocal(&scopesValue)) | 640 if (!callDebuggerMethod("getFunctionScopes", 1, argv).ToLocal(&scopesValue)) |
| 642 return v8::MaybeLocal<v8::Value>(); | 641 return v8::MaybeLocal<v8::Value>(); |
| 643 v8::Local<v8::Value> copied; | 642 v8::Local<v8::Value> copied; |
| 644 if (!copyValueFromDebuggerContext(m_isolate, debuggerContext(), context, | 643 if (!copyValueFromDebuggerContext(m_isolate, debuggerContext(), context, |
| 645 scopesValue) | 644 scopesValue) |
| 646 .ToLocal(&copied) || | 645 .ToLocal(&copied) || |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 toV8StringInternalized(m_isolate, "[[Scopes]]")); | 706 toV8StringInternalized(m_isolate, "[[Scopes]]")); |
| 708 createDataProperty(context, properties, properties->Length(), scopes); | 707 createDataProperty(context, properties, properties->Length(), scopes); |
| 709 } | 708 } |
| 710 } | 709 } |
| 711 return properties; | 710 return properties; |
| 712 } | 711 } |
| 713 | 712 |
| 714 v8::Local<v8::Value> V8Debugger::collectionEntries( | 713 v8::Local<v8::Value> V8Debugger::collectionEntries( |
| 715 v8::Local<v8::Context> context, v8::Local<v8::Object> object) { | 714 v8::Local<v8::Context> context, v8::Local<v8::Object> object) { |
| 716 if (!enabled()) { | 715 if (!enabled()) { |
| 717 NOTREACHED(); | 716 UNREACHABLE(); |
| 718 return v8::Undefined(m_isolate); | 717 return v8::Undefined(m_isolate); |
| 719 } | 718 } |
| 720 v8::Local<v8::Value> argv[] = {object}; | 719 v8::Local<v8::Value> argv[] = {object}; |
| 721 v8::Local<v8::Value> entriesValue = | 720 v8::Local<v8::Value> entriesValue = |
| 722 callDebuggerMethod("getCollectionEntries", 1, argv).ToLocalChecked(); | 721 callDebuggerMethod("getCollectionEntries", 1, argv).ToLocalChecked(); |
| 723 v8::Local<v8::Value> copied; | 722 v8::Local<v8::Value> copied; |
| 724 if (!copyValueFromDebuggerContext(m_isolate, debuggerContext(), context, | 723 if (!copyValueFromDebuggerContext(m_isolate, debuggerContext(), context, |
| 725 entriesValue) | 724 entriesValue) |
| 726 .ToLocal(&copied) || | 725 .ToLocal(&copied) || |
| 727 !copied->IsArray()) | 726 !copied->IsArray()) |
| 728 return v8::Undefined(m_isolate); | 727 return v8::Undefined(m_isolate); |
| 729 if (!markArrayEntriesAsInternal(context, v8::Local<v8::Array>::Cast(copied), | 728 if (!markArrayEntriesAsInternal(context, v8::Local<v8::Array>::Cast(copied), |
| 730 V8InternalValueType::kEntry)) | 729 V8InternalValueType::kEntry)) |
| 731 return v8::Undefined(m_isolate); | 730 return v8::Undefined(m_isolate); |
| 732 return copied; | 731 return copied; |
| 733 } | 732 } |
| 734 | 733 |
| 735 v8::Local<v8::Value> V8Debugger::generatorObjectLocation( | 734 v8::Local<v8::Value> V8Debugger::generatorObjectLocation( |
| 736 v8::Local<v8::Context> context, v8::Local<v8::Object> object) { | 735 v8::Local<v8::Context> context, v8::Local<v8::Object> object) { |
| 737 if (!enabled()) { | 736 if (!enabled()) { |
| 738 NOTREACHED(); | 737 UNREACHABLE(); |
| 739 return v8::Null(m_isolate); | 738 return v8::Null(m_isolate); |
| 740 } | 739 } |
| 741 v8::Local<v8::Value> argv[] = {object}; | 740 v8::Local<v8::Value> argv[] = {object}; |
| 742 v8::Local<v8::Value> location = | 741 v8::Local<v8::Value> location = |
| 743 callDebuggerMethod("getGeneratorObjectLocation", 1, argv) | 742 callDebuggerMethod("getGeneratorObjectLocation", 1, argv) |
| 744 .ToLocalChecked(); | 743 .ToLocalChecked(); |
| 745 v8::Local<v8::Value> copied; | 744 v8::Local<v8::Value> copied; |
| 746 if (!copyValueFromDebuggerContext(m_isolate, debuggerContext(), context, | 745 if (!copyValueFromDebuggerContext(m_isolate, debuggerContext(), context, |
| 747 location) | 746 location) |
| 748 .ToLocal(&copied) || | 747 .ToLocal(&copied) || |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 | 907 |
| 909 size_t stackSize = | 908 size_t stackSize = |
| 910 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; | 909 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; |
| 911 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) | 910 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) |
| 912 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; | 911 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; |
| 913 | 912 |
| 914 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); | 913 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); |
| 915 } | 914 } |
| 916 | 915 |
| 917 } // namespace v8_inspector | 916 } // namespace v8_inspector |
| OLD | NEW |