Index: src/inspector/v8-debugger.cc |
diff --git a/src/inspector/v8-debugger.cc b/src/inspector/v8-debugger.cc |
index 9e0c9b4526d973c3bd3d65f9b3056f395116fc57..f706e6700720790705dfd1f591c3735aa134bd95 100644 |
--- a/src/inspector/v8-debugger.cc |
+++ b/src/inspector/v8-debugger.cc |
@@ -42,6 +42,44 @@ V8DebuggerAgentImpl* agentForScript(V8InspectorImpl* inspector, |
return inspector->enabledDebuggerAgentForGroup(contextGroupId); |
} |
+v8::MaybeLocal<v8::Array> collectionsEntries(v8::Local<v8::Context> context, |
+ v8::Local<v8::Value> value) { |
+ v8::Isolate* isolate = context->GetIsolate(); |
+ v8::Local<v8::Array> entries; |
+ bool isKeyValue = false; |
+ if (!v8::debug::EntriesPreview(isolate, value, &isKeyValue).ToLocal(&entries)) |
+ return v8::MaybeLocal<v8::Array>(); |
+ |
+ v8::Local<v8::Array> wrappedEntries = v8::Array::New(isolate); |
+ CHECK(!isKeyValue || wrappedEntries->Length() % 2 == 0); |
+ if (!wrappedEntries->SetPrototype(context, v8::Null(isolate)) |
+ .FromMaybe(false)) |
+ return v8::MaybeLocal<v8::Array>(); |
+ for (uint32_t i = 0; i < entries->Length(); i += isKeyValue ? 2 : 1) { |
+ v8::Local<v8::Value> item; |
+ if (!entries->Get(context, i).ToLocal(&item)) continue; |
+ v8::Local<v8::Value> value; |
+ if (isKeyValue && !entries->Get(context, i + 1).ToLocal(&value)) continue; |
+ v8::Local<v8::Object> wrapper = v8::Object::New(isolate); |
+ if (!wrapper->SetPrototype(context, v8::Null(isolate)).FromMaybe(false)) |
+ continue; |
+ createDataProperty( |
+ context, wrapper, |
+ toV8StringInternalized(isolate, isKeyValue ? "key" : "value"), item); |
+ if (isKeyValue) { |
+ createDataProperty(context, wrapper, |
+ toV8StringInternalized(isolate, "value"), value); |
+ } |
+ createDataProperty(context, wrappedEntries, wrappedEntries->Length(), |
+ wrapper); |
+ } |
+ if (!markArrayEntriesAsInternal(context, wrappedEntries, |
+ V8InternalValueType::kEntry)) { |
+ return v8::MaybeLocal<v8::Array>(); |
+ } |
+ return wrappedEntries; |
+} |
+ |
} // namespace |
static bool inLiveEditScope = false; |
@@ -266,15 +304,8 @@ bool V8Debugger::canBreakProgram() { |
} |
void V8Debugger::breakProgram() { |
- if (isPaused()) { |
- DCHECK(!m_runningNestedMessageLoop); |
- v8::Local<v8::Value> exception; |
- v8::Local<v8::Array> hitBreakpoints; |
- handleProgramBreak(m_pausedContext, m_executionState, exception, |
- hitBreakpoints); |
- return; |
- } |
- |
+ // Don't allow nested breaks. |
+ if (isPaused()) return; |
if (!canBreakProgram()) return; |
v8::HandleScope scope(m_isolate); |
@@ -413,27 +444,14 @@ Response V8Debugger::setScriptSource( |
} |
JavaScriptCallFrames V8Debugger::currentCallFrames(int limit) { |
- if (!m_isolate->InContext()) return JavaScriptCallFrames(); |
+ if (!isPaused()) return JavaScriptCallFrames(); |
v8::Local<v8::Value> currentCallFramesV8; |
- if (m_executionState.IsEmpty()) { |
- v8::Local<v8::Function> currentCallFramesFunction = |
- v8::Local<v8::Function>::Cast( |
- m_debuggerScript.Get(m_isolate) |
- ->Get(debuggerContext(), |
- toV8StringInternalized(m_isolate, "currentCallFrames")) |
- .ToLocalChecked()); |
- if (!v8::debug::Call(debuggerContext(), currentCallFramesFunction, |
- v8::Integer::New(m_isolate, limit)) |
- .ToLocal(¤tCallFramesV8)) |
- return JavaScriptCallFrames(); |
- } else { |
- v8::Local<v8::Value> argv[] = {m_executionState, |
- v8::Integer::New(m_isolate, limit)}; |
- if (!callDebuggerMethod("currentCallFrames", arraysize(argv), argv, true) |
- .ToLocal(¤tCallFramesV8)) |
- return JavaScriptCallFrames(); |
+ v8::Local<v8::Value> argv[] = {m_executionState, |
+ v8::Integer::New(m_isolate, limit)}; |
+ if (!callDebuggerMethod("currentCallFrames", arraysize(argv), argv, true) |
+ .ToLocal(¤tCallFramesV8)) { |
+ return JavaScriptCallFrames(); |
} |
- DCHECK(!currentCallFramesV8.IsEmpty()); |
if (!currentCallFramesV8->IsArray()) return JavaScriptCallFrames(); |
v8::Local<v8::Array> callFramesArray = currentCallFramesV8.As<v8::Array>(); |
JavaScriptCallFrames callFrames; |
@@ -703,17 +721,13 @@ v8::MaybeLocal<v8::Array> V8Debugger::internalProperties( |
v8::True(m_isolate)); |
} |
} |
- if (!enabled()) return properties; |
- if (value->IsMap() || value->IsWeakMap() || value->IsSet() || |
- value->IsWeakSet() || value->IsSetIterator() || value->IsMapIterator()) { |
- v8::Local<v8::Value> entries = |
- collectionEntries(context, v8::Local<v8::Object>::Cast(value)); |
- if (entries->IsArray()) { |
- createDataProperty(context, properties, properties->Length(), |
- toV8StringInternalized(m_isolate, "[[Entries]]")); |
- createDataProperty(context, properties, properties->Length(), entries); |
- } |
+ v8::Local<v8::Array> entries; |
+ if (collectionsEntries(context, value).ToLocal(&entries)) { |
+ createDataProperty(context, properties, properties->Length(), |
+ toV8StringInternalized(m_isolate, "[[Entries]]")); |
+ createDataProperty(context, properties, properties->Length(), entries); |
} |
+ if (!enabled()) return properties; |
if (value->IsGeneratorObject()) { |
v8::Local<v8::Value> location = |
generatorObjectLocation(context, v8::Local<v8::Object>::Cast(value)); |
@@ -744,43 +758,6 @@ v8::MaybeLocal<v8::Array> V8Debugger::internalProperties( |
return properties; |
} |
-v8::Local<v8::Value> V8Debugger::collectionEntries( |
- v8::Local<v8::Context> context, v8::Local<v8::Object> object) { |
- if (!enabled()) { |
- UNREACHABLE(); |
- return v8::Undefined(m_isolate); |
- } |
- v8::Local<v8::Value> argv[] = {object}; |
- v8::Local<v8::Value> entriesValue; |
- if (!callDebuggerMethod("getCollectionEntries", 1, argv, true) |
- .ToLocal(&entriesValue) || |
- !entriesValue->IsArray()) |
- return v8::Undefined(m_isolate); |
- |
- v8::Local<v8::Array> entries = entriesValue.As<v8::Array>(); |
- v8::Local<v8::Array> copiedArray = |
- v8::Array::New(m_isolate, entries->Length()); |
- if (!copiedArray->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) |
- return v8::Undefined(m_isolate); |
- for (uint32_t i = 0; i < entries->Length(); ++i) { |
- v8::Local<v8::Value> item; |
- if (!entries->Get(debuggerContext(), i).ToLocal(&item)) |
- return v8::Undefined(m_isolate); |
- v8::Local<v8::Value> copied; |
- if (!copyValueFromDebuggerContext(m_isolate, debuggerContext(), context, |
- item) |
- .ToLocal(&copied)) |
- return v8::Undefined(m_isolate); |
- if (!createDataProperty(context, copiedArray, i, copied).FromMaybe(false)) |
- return v8::Undefined(m_isolate); |
- } |
- if (!markArrayEntriesAsInternal(context, |
- v8::Local<v8::Array>::Cast(copiedArray), |
- V8InternalValueType::kEntry)) |
- return v8::Undefined(m_isolate); |
- return copiedArray; |
-} |
- |
v8::Local<v8::Value> V8Debugger::generatorObjectLocation( |
v8::Local<v8::Context> context, v8::Local<v8::Object> object) { |
if (!enabled()) { |