Chromium Code Reviews| Index: third_party/WebKit/Source/platform/v8_inspector/V8Debugger.cpp |
| diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.cpp |
| index 3502ecf39cc825862ffbf157d6ad48cfd982170a..e06e721edfbcfab3f259b4d7af673ba368d60055 100644 |
| --- a/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.cpp |
| +++ b/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.cpp |
| @@ -28,6 +28,36 @@ inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) |
| return value ? v8::True(isolate) : v8::False(isolate); |
| } |
| +v8::Local<v8::Value> createInternalLocation(v8::Isolate* isolate, v8::Local<v8::Context> context, v8::Local<v8::String> scriptId, v8::Local<v8::Number> lineNumber, v8::Local<v8::Number> columnNumber) |
| +{ |
| + v8::Local<v8::Object> location = v8::Object::New(isolate); |
| + if (!location->SetPrototype(context, v8::Null(isolate)).FromMaybe(false)) |
| + return v8::Null(isolate); |
| + if (!location->Set(context, toV8StringInternalized(isolate, "scriptId"), scriptId).FromMaybe(false)) |
| + return v8::Null(isolate); |
| + if (!location->Set(context, toV8StringInternalized(isolate, "lineNumber"), lineNumber).FromMaybe(false)) |
| + return v8::Null(isolate); |
| + if (!location->Set(context, toV8StringInternalized(isolate, "columnNumber"), columnNumber).FromMaybe(false)) |
| + return v8::Null(isolate); |
| + if (!markAsInternal(context, location, V8InternalValueType::kLocation)) |
| + return v8::Null(isolate); |
| + return location; |
| +} |
| + |
| +v8::Local<v8::Value> createInternalLocation(v8::Isolate* isolate, v8::Local<v8::Context> fromContext, v8::Local<v8::Context> toContext, v8::Local<v8::Object> location) |
| +{ |
| + v8::Local<v8::Value> scriptId; |
| + if (!location->Get(fromContext, toV8StringInternalized(isolate, "scriptId")).ToLocal(&scriptId) || !scriptId->IsString()) |
| + return v8::Null(isolate); |
| + v8::Local<v8::Value> lineNumber; |
| + if (!location->Get(fromContext, toV8StringInternalized(isolate, "lineNumber")).ToLocal(&lineNumber) || !lineNumber->IsNumber()) |
| + return v8::Null(isolate); |
| + v8::Local<v8::Value> columnNumber; |
| + if (!location->Get(fromContext, toV8StringInternalized(isolate, "columnNumber")).ToLocal(&columnNumber) || !columnNumber->IsNumber()) |
| + return v8::Null(isolate); |
| + return createInternalLocation(isolate, toContext, scriptId.As<v8::String>(), lineNumber.As<v8::Number>(), columnNumber.As<v8::Number>()); |
| +} |
| + |
| } |
| static bool inLiveEditScope = false; |
| @@ -581,7 +611,7 @@ v8::Local<v8::Context> V8Debugger::debuggerContext() const |
| return m_debuggerContext.Get(m_isolate); |
| } |
| -v8::MaybeLocal<v8::Value> V8Debugger::functionScopes(v8::Local<v8::Function> function) |
| +v8::MaybeLocal<v8::Value> V8Debugger::functionScopes(v8::Local<v8::Context> context, v8::Local<v8::Function> function) |
| { |
| if (!enabled()) { |
| NOTREACHED(); |
| @@ -592,14 +622,69 @@ v8::MaybeLocal<v8::Value> V8Debugger::functionScopes(v8::Local<v8::Function> fun |
| if (!callDebuggerMethod("getFunctionScopes", 1, argv).ToLocal(&scopesValue) || !scopesValue->IsArray()) |
| return v8::MaybeLocal<v8::Value>(); |
| v8::Local<v8::Array> scopes = scopesValue.As<v8::Array>(); |
| - v8::Local<v8::Context> context = m_debuggerContext.Get(m_isolate); |
| - if (!markAsInternal(context, scopes, V8InternalValueType::kScopeList)) |
| + |
| + v8::Local<v8::Array> result = v8::Array::New(m_isolate, scopes->Length()); |
|
pfeldman
2016/08/16 17:07:36
This is too fragile and adhock. You leak one array
dgozman
2016/08/17 00:58:32
Updated.
|
| + if (!result->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) |
| return v8::MaybeLocal<v8::Value>(); |
| - if (!markArrayEntriesAsInternal(context, scopes, V8InternalValueType::kScope)) |
| + if (!markAsInternal(context, result, V8InternalValueType::kScopeList)) |
| return v8::MaybeLocal<v8::Value>(); |
| - if (!scopes->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) |
| - return v8::Undefined(m_isolate); |
| - return scopes; |
| + |
| + for (size_t i = 0; i < scopes->Length(); ++i) { |
| + v8::Local<v8::Value> scopeValue; |
| + if (!scopes->Get(debuggerContext(), i).ToLocal(&scopeValue) || !scopeValue->IsObject()) |
| + return v8::MaybeLocal<v8::Value>(); |
| + v8::Local<v8::Object> scope = scopeValue.As<v8::Object>(); |
| + |
| + v8::Local<v8::Object> resultScope = v8::Object::New(m_isolate); |
| + if (!resultScope->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) |
| + return v8::MaybeLocal<v8::Value>(); |
| + if (!markAsInternal(context, resultScope, V8InternalValueType::kScope)) |
| + return v8::MaybeLocal<v8::Value>(); |
| + |
| + v8::Local<v8::Value> type; |
| + if (!scope->Get(debuggerContext(), toV8StringInternalized(m_isolate, "type")).ToLocal(&type) || !type->IsString()) |
| + return v8::MaybeLocal<v8::Value>(); |
| + if (!resultScope->Set(context, toV8StringInternalized(m_isolate, "type"), type).FromMaybe(false)) |
| + return v8::MaybeLocal<v8::Value>(); |
| + |
| + v8::Local<v8::Value> object; |
| + if (!scope->Get(debuggerContext(), toV8StringInternalized(m_isolate, "object")).ToLocal(&object) || !object->IsObject()) |
| + return v8::MaybeLocal<v8::Value>(); |
| + if (!resultScope->Set(context, toV8StringInternalized(m_isolate, "object"), object).FromMaybe(false)) |
| + return v8::MaybeLocal<v8::Value>(); |
| + |
| + if (scope->HasOwnProperty(debuggerContext(), toV8StringInternalized(m_isolate, "name")).FromMaybe(false)) { |
| + v8::Local<v8::Value> name; |
| + if (!scope->Get(debuggerContext(), toV8StringInternalized(m_isolate, "name")).ToLocal(&name) || !name->IsString()) |
| + return v8::MaybeLocal<v8::Value>(); |
| + if (!resultScope->Set(context, toV8StringInternalized(m_isolate, "name"), name).FromMaybe(false)) |
| + return v8::MaybeLocal<v8::Value>(); |
| + } |
| + |
| + if (scope->HasOwnProperty(debuggerContext(), toV8StringInternalized(m_isolate, "startLocation")).FromMaybe(false)) { |
| + v8::Local<v8::Value> startLocation; |
| + if (!scope->Get(debuggerContext(), toV8StringInternalized(m_isolate, "startLocation")).ToLocal(&startLocation) || !startLocation->IsObject()) |
| + return v8::MaybeLocal<v8::Value>(); |
| + v8::Local<v8::Object> startLocationObject = startLocation.As<v8::Object>(); |
| + v8::Local<v8::Value> resultStartLocation = createInternalLocation(m_isolate, debuggerContext(), context, startLocationObject); |
| + if (resultStartLocation->IsNull() || !resultScope->Set(context, toV8StringInternalized(m_isolate, "startLocation"), resultStartLocation).FromMaybe(false)) |
| + return v8::MaybeLocal<v8::Value>(); |
| + } |
| + |
| + if (scope->HasOwnProperty(debuggerContext(), toV8StringInternalized(m_isolate, "endLocation")).FromMaybe(false)) { |
| + v8::Local<v8::Value> endLocation; |
| + if (!scope->Get(debuggerContext(), toV8StringInternalized(m_isolate, "endLocation")).ToLocal(&endLocation) || !endLocation->IsObject()) |
| + return v8::MaybeLocal<v8::Value>(); |
| + v8::Local<v8::Object> endLocationObject = endLocation.As<v8::Object>(); |
| + v8::Local<v8::Value> resultEndLocation = createInternalLocation(m_isolate, debuggerContext(), context, endLocationObject); |
| + if (resultEndLocation->IsNull() || !resultScope->Set(context, toV8StringInternalized(m_isolate, "endLocation"), resultEndLocation).FromMaybe(false)) |
| + return v8::MaybeLocal<v8::Value>(); |
| + } |
| + |
| + if (!result->Set(context, i, resultScope).FromMaybe(false)) |
| + return v8::MaybeLocal<v8::Value>(); |
| + } |
| + return result; |
| } |
| v8::MaybeLocal<v8::Array> V8Debugger::internalProperties(v8::Local<v8::Context> context, v8::Local<v8::Value> value) |
| @@ -629,7 +714,7 @@ v8::MaybeLocal<v8::Array> V8Debugger::internalProperties(v8::Local<v8::Context> |
| } |
| } |
| if (value->IsGeneratorObject()) { |
| - v8::Local<v8::Value> location = generatorObjectLocation(v8::Local<v8::Object>::Cast(value)); |
| + v8::Local<v8::Value> location = generatorObjectLocation(context, v8::Local<v8::Object>::Cast(value)); |
| if (location->IsObject()) { |
| properties->Set(properties->Length(), toV8StringInternalized(m_isolate, "[[GeneratorLocation]]")); |
| properties->Set(properties->Length(), location); |
| @@ -639,7 +724,7 @@ v8::MaybeLocal<v8::Array> V8Debugger::internalProperties(v8::Local<v8::Context> |
| v8::Local<v8::Function> function = value.As<v8::Function>(); |
| v8::Local<v8::Value> boundFunction = function->GetBoundFunction(); |
| v8::Local<v8::Value> scopes; |
| - if (boundFunction->IsUndefined() && functionScopes(function).ToLocal(&scopes)) { |
| + if (boundFunction->IsUndefined() && functionScopes(context, function).ToLocal(&scopes)) { |
| properties->Set(properties->Length(), toV8StringInternalized(m_isolate, "[[Scopes]]")); |
| properties->Set(properties->Length(), scopes); |
| } |
| @@ -658,27 +743,55 @@ v8::Local<v8::Value> V8Debugger::collectionEntries(v8::Local<v8::Context> contex |
| if (!entriesValue->IsArray()) |
| return v8::Undefined(m_isolate); |
| v8::Local<v8::Array> entries = entriesValue.As<v8::Array>(); |
| - if (!markArrayEntriesAsInternal(context, entries, V8InternalValueType::kEntry)) |
| - return v8::Undefined(m_isolate); |
| - if (!entries->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) |
| + |
| + v8::Local<v8::Array> result = v8::Array::New(m_isolate, entries->Length()); |
| + if (!result->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) |
| return v8::Undefined(m_isolate); |
| - return entries; |
| + |
| + for (size_t i = 0; i < entries->Length(); ++i) { |
| + v8::Local<v8::Value> entryValue; |
| + if (!entries->Get(debuggerContext(), i).ToLocal(&entryValue) || !entryValue->IsObject()) |
| + return v8::Undefined(m_isolate); |
| + v8::Local<v8::Object> entry = entryValue.As<v8::Object>(); |
| + |
| + v8::Local<v8::Object> resultEntry = v8::Object::New(m_isolate); |
| + if (!resultEntry->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) |
| + return v8::Undefined(m_isolate); |
| + if (!markAsInternal(context, resultEntry, V8InternalValueType::kEntry)) |
| + return v8::Undefined(m_isolate); |
| + |
| + v8::Local<v8::Value> value; |
| + if (!entry->Get(debuggerContext(), toV8StringInternalized(m_isolate, "value")).ToLocal(&value)) |
| + return v8::Undefined(m_isolate); |
| + if (!resultEntry->Set(context, toV8StringInternalized(m_isolate, "value"), value).FromMaybe(false)) |
| + return v8::Undefined(m_isolate); |
| + |
| + if (entry->HasOwnProperty(debuggerContext(), toV8StringInternalized(m_isolate, "key")).FromMaybe(false)) { |
| + v8::Local<v8::Value> key; |
| + if (!entry->Get(debuggerContext(), toV8StringInternalized(m_isolate, "key")).ToLocal(&key)) |
| + return v8::Undefined(m_isolate); |
| + if (!resultEntry->Set(context, toV8StringInternalized(m_isolate, "key"), key).FromMaybe(false)) |
| + return v8::Undefined(m_isolate); |
| + } |
| + |
| + if (!result->Set(context, i, resultEntry).FromMaybe(false)) |
| + return v8::Undefined(m_isolate); |
| + } |
| + return result; |
| } |
| -v8::Local<v8::Value> V8Debugger::generatorObjectLocation(v8::Local<v8::Object> object) |
| +v8::Local<v8::Value> V8Debugger::generatorObjectLocation(v8::Local<v8::Context> context, v8::Local<v8::Object> object) |
| { |
| if (!enabled()) { |
| NOTREACHED(); |
| return v8::Null(m_isolate); |
| } |
| v8::Local<v8::Value> argv[] = { object }; |
| - v8::Local<v8::Value> location = callDebuggerMethod("getGeneratorObjectLocation", 1, argv).ToLocalChecked(); |
| - if (!location->IsObject()) |
| - return v8::Null(m_isolate); |
| - v8::Local<v8::Context> context = m_debuggerContext.Get(m_isolate); |
| - if (!markAsInternal(context, v8::Local<v8::Object>::Cast(location), V8InternalValueType::kLocation)) |
| + v8::Local<v8::Value> locationValue = callDebuggerMethod("getGeneratorObjectLocation", 1, argv).ToLocalChecked(); |
| + if (!locationValue->IsObject()) |
| return v8::Null(m_isolate); |
| - return location; |
| + v8::Local<v8::Object> location = locationValue.As<v8::Object>(); |
| + return createInternalLocation(m_isolate, debuggerContext(), context, location); |
| } |
| v8::Local<v8::Value> V8Debugger::functionLocation(v8::Local<v8::Context> context, v8::Local<v8::Function> function) |
| @@ -690,16 +803,7 @@ v8::Local<v8::Value> V8Debugger::functionLocation(v8::Local<v8::Context> context |
| int columnNumber = function->GetScriptColumnNumber(); |
| if (lineNumber == v8::Function::kLineOffsetNotFound || columnNumber == v8::Function::kLineOffsetNotFound) |
| return v8::Null(m_isolate); |
| - v8::Local<v8::Object> location = v8::Object::New(m_isolate); |
| - if (!location->Set(context, toV8StringInternalized(m_isolate, "scriptId"), toV8String(m_isolate, String16::fromInteger(scriptId))).FromMaybe(false)) |
| - return v8::Null(m_isolate); |
| - if (!location->Set(context, toV8StringInternalized(m_isolate, "lineNumber"), v8::Integer::New(m_isolate, lineNumber)).FromMaybe(false)) |
| - return v8::Null(m_isolate); |
| - if (!location->Set(context, toV8StringInternalized(m_isolate, "columnNumber"), v8::Integer::New(m_isolate, columnNumber)).FromMaybe(false)) |
| - return v8::Null(m_isolate); |
| - if (!markAsInternal(context, location, V8InternalValueType::kLocation)) |
| - return v8::Null(m_isolate); |
| - return location; |
| + return createInternalLocation(m_isolate, context, toV8String(m_isolate, String16::fromInteger(scriptId)), v8::Integer::New(m_isolate, lineNumber), v8::Integer::New(m_isolate, columnNumber)); |
| } |
| bool V8Debugger::isPaused() |