| 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/v8-debugger.h" |     5 #include "src/inspector/v8-debugger.h" | 
|     6  |     6  | 
|     7 #include "src/inspector/debugger-script.h" |     7 #include "src/inspector/debugger-script.h" | 
|     8 #include "src/inspector/inspected-context.h" |     8 #include "src/inspector/inspected-context.h" | 
|     9 #include "src/inspector/protocol/Protocol.h" |     9 #include "src/inspector/protocol/Protocol.h" | 
|    10 #include "src/inspector/script-breakpoint.h" |    10 #include "src/inspector/script-breakpoint.h" | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    65 V8Debugger::~V8Debugger() {} |    65 V8Debugger::~V8Debugger() {} | 
|    66  |    66  | 
|    67 void V8Debugger::enable() { |    67 void V8Debugger::enable() { | 
|    68   if (m_enableCount++) return; |    68   if (m_enableCount++) return; | 
|    69   DCHECK(!enabled()); |    69   DCHECK(!enabled()); | 
|    70   v8::HandleScope scope(m_isolate); |    70   v8::HandleScope scope(m_isolate); | 
|    71   v8::debug::SetDebugEventListener(m_isolate, &V8Debugger::v8DebugEventCallback, |    71   v8::debug::SetDebugEventListener(m_isolate, &V8Debugger::v8DebugEventCallback, | 
|    72                                    v8::External::New(m_isolate, this)); |    72                                    v8::External::New(m_isolate, this)); | 
|    73   v8::debug::SetAsyncTaskListener(m_isolate, &V8Debugger::v8AsyncTaskListener, |    73   v8::debug::SetAsyncTaskListener(m_isolate, &V8Debugger::v8AsyncTaskListener, | 
|    74                                   this); |    74                                   this); | 
 |    75   v8::debug::SetCompileEventListener(m_isolate, | 
 |    76                                      &V8Debugger::v8CompileEventListener, this); | 
|    75   m_debuggerContext.Reset(m_isolate, v8::debug::GetDebugContext(m_isolate)); |    77   m_debuggerContext.Reset(m_isolate, v8::debug::GetDebugContext(m_isolate)); | 
|    76   v8::debug::ChangeBreakOnException(m_isolate, v8::debug::NoBreakOnException); |    78   v8::debug::ChangeBreakOnException(m_isolate, v8::debug::NoBreakOnException); | 
|    77   m_pauseOnExceptionsState = v8::debug::NoBreakOnException; |    79   m_pauseOnExceptionsState = v8::debug::NoBreakOnException; | 
|    78   compileDebuggerScript(); |    80   compileDebuggerScript(); | 
|    79 } |    81 } | 
|    80  |    82  | 
|    81 void V8Debugger::disable() { |    83 void V8Debugger::disable() { | 
|    82   if (--m_enableCount) return; |    84   if (--m_enableCount) return; | 
|    83   DCHECK(enabled()); |    85   DCHECK(enabled()); | 
|    84   clearBreakpoints(); |    86   clearBreakpoints(); | 
|    85   m_debuggerScript.Reset(); |    87   m_debuggerScript.Reset(); | 
|    86   m_debuggerContext.Reset(); |    88   m_debuggerContext.Reset(); | 
|    87   allAsyncTasksCanceled(); |    89   allAsyncTasksCanceled(); | 
|    88   m_wasmTranslation.Clear(); |    90   m_wasmTranslation.Clear(); | 
|    89   v8::debug::SetDebugEventListener(m_isolate, nullptr); |    91   v8::debug::SetDebugEventListener(m_isolate, nullptr); | 
|    90   v8::debug::SetAsyncTaskListener(m_isolate, nullptr, nullptr); |    92   v8::debug::SetAsyncTaskListener(m_isolate, nullptr, nullptr); | 
 |    93   v8::debug::SetCompileEventListener(m_isolate, nullptr, nullptr); | 
|    91 } |    94 } | 
|    92  |    95  | 
|    93 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); } |    96 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); } | 
|    94  |    97  | 
|    95 void V8Debugger::getCompiledScripts( |    98 void V8Debugger::getCompiledScripts( | 
|    96     int contextGroupId, |    99     int contextGroupId, | 
|    97     std::vector<std::unique_ptr<V8DebuggerScript>>& result) { |   100     std::vector<std::unique_ptr<V8DebuggerScript>>& result) { | 
|    98   v8::HandleScope scope(m_isolate); |   101   v8::HandleScope scope(m_isolate); | 
|    99   v8::PersistentValueVector<v8::debug::Script> scripts(m_isolate); |   102   v8::PersistentValueVector<v8::debug::Script> scripts(m_isolate); | 
|   100   v8::debug::GetLoadedScripts(m_isolate, scripts); |   103   v8::debug::GetLoadedScripts(m_isolate, scripts); | 
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   529       ->Call(m_isolate->GetCurrentContext(), object, 0, nullptr) |   532       ->Call(m_isolate->GetCurrentContext(), object, 0, nullptr) | 
|   530       .ToLocalChecked(); |   533       .ToLocalChecked(); | 
|   531 } |   534 } | 
|   532  |   535  | 
|   533 void V8Debugger::handleV8DebugEvent( |   536 void V8Debugger::handleV8DebugEvent( | 
|   534     const v8::debug::EventDetails& eventDetails) { |   537     const v8::debug::EventDetails& eventDetails) { | 
|   535   if (!enabled()) return; |   538   if (!enabled()) return; | 
|   536   v8::HandleScope scope(m_isolate); |   539   v8::HandleScope scope(m_isolate); | 
|   537  |   540  | 
|   538   v8::DebugEvent event = eventDetails.GetEvent(); |   541   v8::DebugEvent event = eventDetails.GetEvent(); | 
|   539   if (event != v8::Break && event != v8::Exception && |   542   if (event != v8::Break && event != v8::Exception) return; | 
|   540       event != v8::AfterCompile && event != v8::CompileError) |  | 
|   541     return; |  | 
|   542  |   543  | 
|   543   v8::Local<v8::Context> eventContext = eventDetails.GetEventContext(); |   544   v8::Local<v8::Context> eventContext = eventDetails.GetEventContext(); | 
|   544   DCHECK(!eventContext.IsEmpty()); |   545   DCHECK(!eventContext.IsEmpty()); | 
|   545   V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup( |   546   V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup( | 
|   546       m_inspector->contextGroupId(eventContext)); |   547       m_inspector->contextGroupId(eventContext)); | 
|   547   if (!agent) return; |   548   if (!agent) return; | 
|   548  |   549  | 
|   549   if (event == v8::AfterCompile || event == v8::CompileError) { |   550   if (event == v8::Exception) { | 
|   550     v8::Context::Scope contextScope(debuggerContext()); |  | 
|   551     // Determine if the script is a wasm script. |  | 
|   552     v8::Local<v8::Value> scriptMirror = |  | 
|   553         callInternalGetterFunction(eventDetails.GetEventData(), "script"); |  | 
|   554     DCHECK(scriptMirror->IsObject()); |  | 
|   555     v8::Local<v8::Value> scriptWrapper = |  | 
|   556         callInternalGetterFunction(scriptMirror.As<v8::Object>(), "value"); |  | 
|   557     DCHECK(scriptWrapper->IsObject()); |  | 
|   558     v8::Local<v8::debug::Script> script; |  | 
|   559     if (!v8::debug::Script::Wrap(m_isolate, scriptWrapper.As<v8::Object>()) |  | 
|   560              .ToLocal(&script)) { |  | 
|   561       return; |  | 
|   562     } |  | 
|   563     if (script->IsWasm()) { |  | 
|   564       m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent); |  | 
|   565     } else if (m_ignoreScriptParsedEventsCounter == 0) { |  | 
|   566       agent->didParseSource( |  | 
|   567           V8DebuggerScript::Create(m_isolate, script, inLiveEditScope), |  | 
|   568           event == v8::AfterCompile); |  | 
|   569     } |  | 
|   570   } else if (event == v8::Exception) { |  | 
|   571     v8::Local<v8::Context> context = debuggerContext(); |   551     v8::Local<v8::Context> context = debuggerContext(); | 
|   572     v8::Local<v8::Object> eventData = eventDetails.GetEventData(); |   552     v8::Local<v8::Object> eventData = eventDetails.GetEventData(); | 
|   573     v8::Local<v8::Value> exception = |   553     v8::Local<v8::Value> exception = | 
|   574         callInternalGetterFunction(eventData, "exception"); |   554         callInternalGetterFunction(eventData, "exception"); | 
|   575     v8::Local<v8::Value> promise = |   555     v8::Local<v8::Value> promise = | 
|   576         callInternalGetterFunction(eventData, "promise"); |   556         callInternalGetterFunction(eventData, "promise"); | 
|   577     bool isPromiseRejection = !promise.IsEmpty() && promise->IsObject(); |   557     bool isPromiseRejection = !promise.IsEmpty() && promise->IsObject(); | 
|   578     v8::Local<v8::Value> uncaught = |   558     v8::Local<v8::Value> uncaught = | 
|   579         callInternalGetterFunction(eventData, "uncaught"); |   559         callInternalGetterFunction(eventData, "uncaught"); | 
|   580     bool isUncaught = uncaught->BooleanValue(context).FromJust(); |   560     bool isUncaught = uncaught->BooleanValue(context).FromJust(); | 
|   581     handleProgramBreak(eventContext, eventDetails.GetExecutionState(), |   561     handleProgramBreak(eventContext, eventDetails.GetExecutionState(), | 
|   582                        exception, v8::Local<v8::Array>(), isPromiseRejection, |   562                        exception, v8::Local<v8::Array>(), isPromiseRejection, | 
|   583                        isUncaught); |   563                        isUncaught); | 
|   584   } else if (event == v8::Break) { |   564   } else if (event == v8::Break) { | 
|   585     v8::Local<v8::Value> argv[] = {eventDetails.GetEventData()}; |   565     v8::Local<v8::Value> argv[] = {eventDetails.GetEventData()}; | 
|   586     v8::Local<v8::Value> hitBreakpoints; |   566     v8::Local<v8::Value> hitBreakpoints; | 
|   587     if (!callDebuggerMethod("getBreakpointNumbers", 1, argv) |   567     if (!callDebuggerMethod("getBreakpointNumbers", 1, argv) | 
|   588              .ToLocal(&hitBreakpoints)) |   568              .ToLocal(&hitBreakpoints)) | 
|   589       return; |   569       return; | 
|   590     DCHECK(hitBreakpoints->IsArray()); |   570     DCHECK(hitBreakpoints->IsArray()); | 
|   591     handleProgramBreak(eventContext, eventDetails.GetExecutionState(), |   571     handleProgramBreak(eventContext, eventDetails.GetExecutionState(), | 
|   592                        v8::Local<v8::Value>(), hitBreakpoints.As<v8::Array>()); |   572                        v8::Local<v8::Value>(), hitBreakpoints.As<v8::Array>()); | 
|   593   } |   573   } | 
|   594 } |   574 } | 
|   595  |   575  | 
 |   576 void V8Debugger::v8CompileEventListener(v8::Local<v8::debug::Script> script, | 
 |   577                                         bool has_compile_error, void* data) { | 
 |   578   V8Debugger* debugger = static_cast<V8Debugger*>(data); | 
 |   579   v8::Local<v8::Value> contextData; | 
 |   580   if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) { | 
 |   581     return; | 
 |   582   } | 
 |   583   int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value()); | 
 |   584   int contextGroupId = debugger->m_inspector->contextGroupId(contextId); | 
 |   585   if (!contextGroupId) return; | 
 |   586   V8DebuggerAgentImpl* agent = | 
 |   587       debugger->m_inspector->enabledDebuggerAgentForGroup(contextGroupId); | 
 |   588   if (!agent) return; | 
 |   589   if (script->IsWasm()) { | 
 |   590     debugger->m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), | 
 |   591                                           agent); | 
 |   592   } else if (debugger->m_ignoreScriptParsedEventsCounter == 0) { | 
 |   593     agent->didParseSource( | 
 |   594         V8DebuggerScript::Create(debugger->m_isolate, script, inLiveEditScope), | 
 |   595         !has_compile_error); | 
 |   596   } | 
 |   597 } | 
 |   598  | 
|   596 void V8Debugger::v8AsyncTaskListener(v8::debug::PromiseDebugActionType type, |   599 void V8Debugger::v8AsyncTaskListener(v8::debug::PromiseDebugActionType type, | 
|   597                                      int id, void* data) { |   600                                      int id, void* data) { | 
|   598   V8Debugger* debugger = static_cast<V8Debugger*>(data); |   601   V8Debugger* debugger = static_cast<V8Debugger*>(data); | 
|   599   if (!debugger->m_maxAsyncCallStackDepth) return; |   602   if (!debugger->m_maxAsyncCallStackDepth) return; | 
|   600   // Async task events from Promises are given misaligned pointers to prevent |   603   // Async task events from Promises are given misaligned pointers to prevent | 
|   601   // from overlapping with other Blink task identifiers. There is a single |   604   // from overlapping with other Blink task identifiers. There is a single | 
|   602   // namespace of such ids, managed by src/js/promise.js. |   605   // namespace of such ids, managed by src/js/promise.js. | 
|   603   void* ptr = reinterpret_cast<void*>(id * 2 + 1); |   606   void* ptr = reinterpret_cast<void*>(id * 2 + 1); | 
|   604   switch (type) { |   607   switch (type) { | 
|   605     case v8::debug::kDebugEnqueueAsyncFunction: |   608     case v8::debug::kDebugEnqueueAsyncFunction: | 
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   994  |   997  | 
|   995   size_t stackSize = |   998   size_t stackSize = | 
|   996       fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; |   999       fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; | 
|   997   if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) |  1000   if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) | 
|   998     stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; |  1001     stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; | 
|   999  |  1002  | 
|  1000   return V8StackTraceImpl::capture(this, contextGroupId, stackSize); |  1003   return V8StackTraceImpl::capture(this, contextGroupId, stackSize); | 
|  1001 } |  1004 } | 
|  1002  |  1005  | 
|  1003 }  // namespace v8_inspector |  1006 }  // namespace v8_inspector | 
| OLD | NEW |