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 |