Commit 52d65418 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by V8 LUCI CQ

Refactor toProtocolValue in src/inspector

The refactoring makes it explicit that a v8::Array results in a
protocol::ListValue, and a v8::Object in a protocol::DictionaryValue,
which will be useful in a follow-up.

Bug: chromium:1213393
Change-Id: I0d6e5b013a828e12cb3200672d4fd9b14a14a807
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2919831Reviewed-by: 's avatarPhilip Pfaffe <pfaffe@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74839}
parent 3d4bda74
...@@ -45,41 +45,11 @@ V8InternalValueType v8InternalValueTypeFrom(v8::Local<v8::Context> context, ...@@ -45,41 +45,11 @@ V8InternalValueType v8InternalValueTypeFrom(v8::Local<v8::Context> context,
Response toProtocolValue(v8::Local<v8::Context> context, Response toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> value, int maxDepth, v8::Local<v8::Value> value, int maxDepth,
std::unique_ptr<protocol::Value>* result) { std::unique_ptr<protocol::Value>* result);
if (!maxDepth)
return Response::ServerError("Object reference chain is too long");
maxDepth--;
if (value->IsNull() || value->IsUndefined()) { Response arrayToProtocolValue(v8::Local<v8::Context> context,
*result = protocol::Value::null(); v8::Local<v8::Array> array, int maxDepth,
return Response::Success(); std::unique_ptr<protocol::ListValue>* result) {
}
if (value->IsBoolean()) {
*result =
protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value());
return Response::Success();
}
if (value->IsNumber()) {
double doubleValue = value.As<v8::Number>()->Value();
if (doubleValue >= std::numeric_limits<int>::min() &&
doubleValue <= std::numeric_limits<int>::max() &&
bit_cast<int64_t>(doubleValue) != bit_cast<int64_t>(-0.0)) {
int intValue = static_cast<int>(doubleValue);
if (intValue == doubleValue) {
*result = protocol::FundamentalValue::create(intValue);
return Response::Success();
}
}
*result = protocol::FundamentalValue::create(doubleValue);
return Response::Success();
}
if (value->IsString()) {
*result = protocol::StringValue::create(
toProtocolString(context->GetIsolate(), value.As<v8::String>()));
return Response::Success();
}
if (value->IsArray()) {
v8::Local<v8::Array> array = value.As<v8::Array>();
std::unique_ptr<protocol::ListValue> inspectorArray = std::unique_ptr<protocol::ListValue> inspectorArray =
protocol::ListValue::create(); protocol::ListValue::create();
uint32_t length = array->Length(); uint32_t length = array->Length();
...@@ -88,17 +58,19 @@ Response toProtocolValue(v8::Local<v8::Context> context, ...@@ -88,17 +58,19 @@ Response toProtocolValue(v8::Local<v8::Context> context,
if (!array->Get(context, i).ToLocal(&value)) if (!array->Get(context, i).ToLocal(&value))
return Response::InternalError(); return Response::InternalError();
std::unique_ptr<protocol::Value> element; std::unique_ptr<protocol::Value> element;
Response response = toProtocolValue(context, value, maxDepth, &element); Response response = toProtocolValue(context, value, maxDepth - 1, &element);
if (!response.IsSuccess()) return response; if (!response.IsSuccess()) return response;
inspectorArray->pushValue(std::move(element)); inspectorArray->pushValue(std::move(element));
} }
*result = std::move(inspectorArray); *result = std::move(inspectorArray);
return Response::Success(); return Response::Success();
} }
if (value->IsObject()) {
Response objectToProtocolValue(
v8::Local<v8::Context> context, v8::Local<v8::Object> object, int maxDepth,
std::unique_ptr<protocol::DictionaryValue>* result) {
std::unique_ptr<protocol::DictionaryValue> jsonObject = std::unique_ptr<protocol::DictionaryValue> jsonObject =
protocol::DictionaryValue::create(); protocol::DictionaryValue::create();
v8::Local<v8::Object> object = value.As<v8::Object>();
v8::Local<v8::Array> propertyNames; v8::Local<v8::Array> propertyNames;
if (!object->GetPropertyNames(context).ToLocal(&propertyNames)) if (!object->GetPropertyNames(context).ToLocal(&propertyNames))
return Response::InternalError(); return Response::InternalError();
...@@ -107,12 +79,11 @@ Response toProtocolValue(v8::Local<v8::Context> context, ...@@ -107,12 +79,11 @@ Response toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> name; v8::Local<v8::Value> name;
if (!propertyNames->Get(context, i).ToLocal(&name)) if (!propertyNames->Get(context, i).ToLocal(&name))
return Response::InternalError(); return Response::InternalError();
// FIXME(yurys): v8::Object should support GetOwnPropertyNames
if (name->IsString()) { if (name->IsString()) {
v8::Maybe<bool> hasRealNamedProperty = v8::Maybe<bool> hasRealNamedProperty =
object->HasRealNamedProperty(context, name.As<v8::String>()); object->HasRealNamedProperty(context, name.As<v8::String>());
if (hasRealNamedProperty.IsNothing() || // Don't access properties with interceptors.
!hasRealNamedProperty.FromJust()) if (hasRealNamedProperty.IsNothing() || !hasRealNamedProperty.FromJust())
continue; continue;
} }
v8::Local<v8::String> propertyName; v8::Local<v8::String> propertyName;
...@@ -123,14 +94,68 @@ Response toProtocolValue(v8::Local<v8::Context> context, ...@@ -123,14 +94,68 @@ Response toProtocolValue(v8::Local<v8::Context> context,
if (property->IsUndefined()) continue; if (property->IsUndefined()) continue;
std::unique_ptr<protocol::Value> propertyValue; std::unique_ptr<protocol::Value> propertyValue;
Response response = Response response =
toProtocolValue(context, property, maxDepth, &propertyValue); toProtocolValue(context, property, maxDepth - 1, &propertyValue);
if (!response.IsSuccess()) return response; if (!response.IsSuccess()) return response;
jsonObject->setValue( jsonObject->setValue(toProtocolString(context->GetIsolate(), propertyName),
toProtocolString(context->GetIsolate(), propertyName),
std::move(propertyValue)); std::move(propertyValue));
} }
*result = std::move(jsonObject); *result = std::move(jsonObject);
return Response::Success(); return Response::Success();
}
std::unique_ptr<protocol::FundamentalValue> toProtocolValue(
double doubleValue) {
if (doubleValue >= std::numeric_limits<int>::min() &&
doubleValue <= std::numeric_limits<int>::max() &&
bit_cast<int64_t>(doubleValue) != bit_cast<int64_t>(-0.0)) {
int intValue = static_cast<int>(doubleValue);
if (intValue == doubleValue) {
return protocol::FundamentalValue::create(intValue);
}
}
return protocol::FundamentalValue::create(doubleValue);
}
Response toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> value, int maxDepth,
std::unique_ptr<protocol::Value>* result) {
if (maxDepth <= 0)
return Response::ServerError("Object reference chain is too long");
if (value->IsNull() || value->IsUndefined()) {
*result = protocol::Value::null();
return Response::Success();
}
if (value->IsBoolean()) {
*result =
protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value());
return Response::Success();
}
if (value->IsNumber()) {
double doubleValue = value.As<v8::Number>()->Value();
*result = toProtocolValue(doubleValue);
return Response::Success();
}
if (value->IsString()) {
*result = protocol::StringValue::create(
toProtocolString(context->GetIsolate(), value.As<v8::String>()));
return Response::Success();
}
if (value->IsArray()) {
v8::Local<v8::Array> array = value.As<v8::Array>();
std::unique_ptr<protocol::ListValue> list_result;
auto response =
arrayToProtocolValue(context, array, maxDepth, &list_result);
*result = std::move(list_result);
return response;
}
if (value->IsObject()) {
v8::Local<v8::Object> object = value.As<v8::Object>();
std::unique_ptr<protocol::DictionaryValue> dict_result;
auto response =
objectToProtocolValue(context, object, maxDepth, &dict_result);
*result = std::move(dict_result);
return response;
} }
return Response::ServerError("Object couldn't be returned by value"); return Response::ServerError("Object couldn't be returned by value");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment