Commit c674a1f6 authored by Maksim Sadym's avatar Maksim Sadym Committed by V8 LUCI CQ

Follow-up after https://crrev.com/c/3472077

1. Use `StringBuffer` instead of `StringView` in `WebDriverValue`.
2. Add some `DCHECK`s.
3. Reserve vector size.
4. Respect properties with `undefined` values.
5. Minor clean-ups.

Change-Id: Ic109acb1e3adf2d950767173c17a9203e3c816dc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3596173Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Auto-Submit: Maksim Sadym <sadym@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80296}
parent 76751fc3
......@@ -1347,7 +1347,9 @@ domain Runtime
optional string objectGroup
# Whether to throw an exception if side effect cannot be ruled out during evaluation.
experimental optional boolean throwOnSideEffect
# Whether the result should be serialized according to https://w3c.github.io/webdriver-bidi.
# Whether the result should contain `webDriverValue`, serialized according to
# https://w3c.github.io/webdriver-bidi. This is mutually exclusive with `returnByValue`, but
# resulting `objectId` is still provided.
experimental optional boolean generateWebDriverValue
returns
# Call result.
......
......@@ -207,10 +207,10 @@ class V8_EXPORT V8InspectorSession {
class V8_EXPORT WebDriverValue {
public:
explicit WebDriverValue(StringView type, v8::MaybeLocal<v8::Value> value = {})
: type(type), value(value) {}
StringView type;
explicit WebDriverValue(std::unique_ptr<StringBuffer> type,
v8::MaybeLocal<v8::Value> value = {})
: type(std::move(type)), value(value) {}
std::unique_ptr<StringBuffer> type;
v8::MaybeLocal<v8::Value> value;
};
......
......@@ -576,8 +576,8 @@ Response InjectedScript::wrapObjectMirror(
}
if (wrapMode == WrapMode::kGenerateWebDriverValue) {
int maxDepth = 1;
std::unique_ptr<protocol::Runtime::WebDriverValue> webDriverValue;
response = mirror.buildWebDriverValue(context, maxDepth, &webDriverValue);
std::unique_ptr<protocol::Runtime::WebDriverValue> webDriverValue =
mirror.buildWebDriverValue(context, maxDepth);
if (!response.IsSuccess()) return response;
(*result)->setWebDriverValue(std::move(webDriverValue));
}
......
......@@ -14,46 +14,38 @@
namespace v8_inspector {
namespace {
using protocol::Response;
// private
protocol::Response _serializeRecursively(
v8::Local<v8::Value> value, v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Value>* result) {
std::unique_ptr<protocol::Value> SerializeRecursively(
v8::Local<v8::Value> value, v8::Local<v8::Context> context, int max_depth) {
std::unique_ptr<ValueMirror> mirror = ValueMirror::create(context, value);
std::unique_ptr<protocol::Runtime::WebDriverValue> webDriver_value;
Response response =
mirror->buildWebDriverValue(context, max_depth - 1, &webDriver_value);
if (!response.IsSuccess()) return response;
if (!webDriver_value) return Response::InternalError();
std::unique_ptr<protocol::Runtime::WebDriverValue> web_driver_value =
mirror->buildWebDriverValue(context, max_depth - 1);
DCHECK(web_driver_value);
std::unique_ptr<protocol::DictionaryValue> result_dict =
protocol::DictionaryValue::create();
result_dict->setValue(
protocol::String("type"),
protocol::StringValue::create(webDriver_value->getType()));
if (webDriver_value->hasValue())
protocol::StringValue::create(web_driver_value->getType()));
if (web_driver_value->hasValue()) {
result_dict->setValue(protocol::String("value"),
webDriver_value->getValue(nullptr)->clone());
(*result) = std::move(result_dict);
return Response::Success();
}
String16 descriptionForObject(v8::Isolate* isolate,
v8::Local<v8::Object> object) {
return toProtocolString(isolate, object->GetConstructorName());
web_driver_value->getValue(nullptr)->clone());
}
return result_dict;
}
String16 descriptionForDate(v8::Local<v8::Context> context,
v8::Local<v8::Date> date) {
std::unique_ptr<protocol::Value> DescriptionForDate(
v8::Local<v8::Context> context, v8::Local<v8::Date> date) {
v8::Isolate* isolate = context->GetIsolate();
v8::TryCatch tryCatch(isolate);
v8::Local<v8::String> description;
if (!date->ToString(context).ToLocal(&description)) {
return descriptionForObject(isolate, date);
}
return toProtocolString(isolate, description);
bool success = date->ToString(context).ToLocal(&description);
DCHECK(success);
USE(success);
return protocol::StringValue::create(toProtocolString(isolate, description));
}
String16 _descriptionForRegExpFlags(v8::Local<v8::RegExp> value) {
......@@ -70,12 +62,12 @@ String16 _descriptionForRegExpFlags(v8::Local<v8::RegExp> value) {
return result_string_builder.toString();
}
protocol::Response _serializeRegexp(
v8::Local<v8::RegExp> value, v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Regexp)
.build();
std::unique_ptr<protocol::Runtime::WebDriverValue> SerializeRegexp(
v8::Local<v8::RegExp> value, v8::Local<v8::Context> context) {
std::unique_ptr<protocol::Runtime::WebDriverValue> result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Regexp)
.build();
std::unique_ptr<protocol::DictionaryValue> result_value =
protocol::DictionaryValue::create();
......@@ -85,291 +77,255 @@ protocol::Response _serializeRegexp(
context->GetIsolate(), value->GetSource())));
String16 flags = _descriptionForRegExpFlags(value);
if (!flags.isEmpty())
if (!flags.isEmpty()) {
result_value->setValue(protocol::String("flags"),
protocol::StringValue::create(flags));
(*result)->setValue(std::move(result_value));
return Response::Success();
}
result->setValue(std::move(result_value));
return result;
}
protocol::Response _serializeDate(
v8::Local<v8::Date> value, v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Date)
.build();
std::unique_ptr<protocol::Runtime::WebDriverValue> SerializeDate(
v8::Local<v8::Date> value, v8::Local<v8::Context> context) {
std::unique_ptr<protocol::Runtime::WebDriverValue> result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Date)
.build();
std::unique_ptr<protocol::Value> date_description =
DescriptionForDate(context, value.As<v8::Date>());
(*result)->setValue(protocol::StringValue::create(
descriptionForDate(context, value.As<v8::Date>())));
return Response::Success();
result->setValue(std::move(date_description));
return result;
}
protocol::Response _serializeArrayValue(
v8::Local<v8::Array> value, v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Value>* result) {
std::unique_ptr<protocol::ListValue> result_value =
protocol::ListValue::create();
std::unique_ptr<protocol::Value> SerializeArrayValue(
v8::Local<v8::Array> value, v8::Local<v8::Context> context, int max_depth) {
std::unique_ptr<protocol::ListValue> result = protocol::ListValue::create();
uint32_t length = value->Length();
result->reserve(length);
for (uint32_t i = 0; i < length; i++) {
v8::Local<v8::Value> element_value;
std::unique_ptr<protocol::Value> element_protocol_value;
if (!value->Get(context, i).ToLocal(&element_value))
return Response::InternalError();
bool success = value->Get(context, i).ToLocal(&element_value);
DCHECK(success);
USE(success);
Response response = _serializeRecursively(element_value, context, max_depth,
&element_protocol_value);
if (!response.IsSuccess()) return response;
std::unique_ptr<protocol::Value> element_protocol_value =
SerializeRecursively(element_value, context, max_depth);
result_value->pushValue(std::move(element_protocol_value));
result->pushValue(std::move(element_protocol_value));
}
*result = std::move(result_value);
return Response::Success();
return result;
}
protocol::Response _serializeArray(
v8::Local<v8::Array> value, v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Array)
.build();
if (max_depth <= 0) return Response::Success();
std::unique_ptr<protocol::Value> result_value;
Response response =
_serializeArrayValue(value, context, max_depth, &result_value);
if (!response.IsSuccess()) return response;
std::unique_ptr<protocol::Runtime::WebDriverValue> SerializeArray(
v8::Local<v8::Array> value, v8::Local<v8::Context> context, int max_depth) {
std::unique_ptr<protocol::Runtime::WebDriverValue> result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Array)
.build();
if (max_depth > 0) {
result->setValue(SerializeArrayValue(value, context, max_depth));
}
(*result)->setValue(std::move(result_value));
return Response::Success();
return result;
}
protocol::Response _serializeMap(
v8::Local<v8::Map> value, v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Map)
.build();
std::unique_ptr<protocol::Runtime::WebDriverValue> SerializeMap(
v8::Local<v8::Map> value, v8::Local<v8::Context> context, int max_depth) {
std::unique_ptr<protocol::Runtime::WebDriverValue> result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Map)
.build();
if (max_depth <= 0) return Response::Success();
if (max_depth > 0) {
std::unique_ptr<protocol::ListValue> result_value =
protocol::ListValue::create();
std::unique_ptr<protocol::ListValue> result_value =
protocol::ListValue::create();
v8::Local<v8::Array> properties_and_values = value->AsArray();
v8::Local<v8::Array> properties_and_values = value->AsArray();
uint32_t length = properties_and_values->Length();
result_value->reserve(length);
for (uint32_t i = 0; i < length; i += 2) {
v8::Local<v8::Value> key_value, property_value;
std::unique_ptr<protocol::Value> key_protocol_value,
property_protocol_value;
uint32_t length = properties_and_values->Length();
for (uint32_t i = 0; i < length; i += 2) {
v8::Local<v8::Value> key_value, property_value;
std::unique_ptr<protocol::Value> key_protocol_value,
property_protocol_value;
bool success = properties_and_values->Get(context, i).ToLocal(&key_value);
DCHECK(success);
success =
properties_and_values->Get(context, i + 1).ToLocal(&property_value);
DCHECK(success);
USE(success);
if (!properties_and_values->Get(context, i).ToLocal(&key_value))
return Response::InternalError();
if (!properties_and_values->Get(context, i + 1).ToLocal(&property_value))
return Response::InternalError();
if (property_value->IsUndefined()) continue;
if (key_value->IsString()) {
key_protocol_value = protocol::StringValue::create(toProtocolString(
context->GetIsolate(), key_value.As<v8::String>()));
} else {
key_protocol_value =
SerializeRecursively(key_value, context, max_depth);
}
if (key_value->IsString()) {
key_protocol_value = protocol::StringValue::create(
toProtocolString(context->GetIsolate(), key_value.As<v8::String>()));
} else {
Response response = _serializeRecursively(key_value, context, max_depth,
&key_protocol_value);
if (!response.IsSuccess()) return response;
}
property_protocol_value =
SerializeRecursively(property_value, context, max_depth);
Response response = _serializeRecursively(
property_value, context, max_depth, &property_protocol_value);
if (!response.IsSuccess()) return response;
std::unique_ptr<protocol::ListValue> key_value_list =
protocol::ListValue::create();
std::unique_ptr<protocol::ListValue> value_list =
protocol::ListValue::create();
// command->pushValue(protocol::StringValue::create(method));
value_list->pushValue(std::move(key_protocol_value));
value_list->pushValue(std::move(property_protocol_value));
key_value_list->pushValue(std::move(key_protocol_value));
key_value_list->pushValue(std::move(property_protocol_value));
result_value->pushValue(std::move(value_list));
result_value->pushValue(std::move(key_value_list));
}
result->setValue(std::move(result_value));
}
(*result)->setValue(std::move(result_value));
return Response::Success();
return result;
}
protocol::Response _serializeSet(
v8::Local<v8::Set> value, v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Set)
.build();
if (max_depth <= 0) return Response::Success();
std::unique_ptr<protocol::Runtime::WebDriverValue> SerializeSet(
v8::Local<v8::Set> value, v8::Local<v8::Context> context, int max_depth) {
std::unique_ptr<protocol::Runtime::WebDriverValue> result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Set)
.build();
std::unique_ptr<protocol::Value> result_value;
Response response =
_serializeArrayValue(value->AsArray(), context, max_depth, &result_value);
if (!response.IsSuccess()) return response;
(*result)->setValue(std::move(result_value));
return Response::Success();
if (max_depth > 0) {
result->setValue(SerializeArrayValue(value->AsArray(), context, max_depth));
}
return result;
}
protocol::Response _serializeObjectValue(
v8::Local<v8::Object> value, v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Value>* result) {
std::unique_ptr<protocol::ListValue> result_list =
protocol::ListValue::create();
std::unique_ptr<protocol::Value> SerializeObjectValue(
v8::Local<v8::Object> value, v8::Local<v8::Context> context,
int max_depth) {
std::unique_ptr<protocol::ListValue> result = protocol::ListValue::create();
// Iterate through object's properties.
v8::Local<v8::Array> property_names;
if (!value->GetOwnPropertyNames(context).ToLocal(&property_names))
return Response::InternalError();
bool success = value->GetOwnPropertyNames(context).ToLocal(&property_names);
DCHECK(success);
uint32_t length = property_names->Length();
result->reserve(length);
for (uint32_t i = 0; i < length; i++) {
v8::Local<v8::Value> key_value, property_value;
std::unique_ptr<protocol::Value> key_protocol_value,
property_protocol_value;
if (!property_names->Get(context, i).ToLocal(&key_value))
return Response::InternalError();
success = property_names->Get(context, i).ToLocal(&key_value);
DCHECK(success);
if (key_value->IsString()) {
v8::Maybe<bool> hasRealNamedProperty =
value->HasRealNamedProperty(context, key_value.As<v8::String>());
// Don't access properties with interceptors.
if (hasRealNamedProperty.IsNothing() || !hasRealNamedProperty.FromJust())
if (hasRealNamedProperty.IsNothing() ||
!hasRealNamedProperty.FromJust()) {
continue;
}
key_protocol_value = protocol::StringValue::create(
toProtocolString(context->GetIsolate(), key_value.As<v8::String>()));
} else {
Response response = _serializeRecursively(key_value, context, max_depth,
&key_protocol_value);
if (!response.IsSuccess()) return response;
key_protocol_value = SerializeRecursively(key_value, context, max_depth);
}
if (!value->Get(context, key_value).ToLocal(&property_value))
return Response::InternalError();
if (property_value->IsUndefined()) continue;
success = value->Get(context, key_value).ToLocal(&property_value);
DCHECK(success);
USE(success);
Response response = _serializeRecursively(
property_value, context, max_depth, &property_protocol_value);
if (!response.IsSuccess()) return response;
property_protocol_value =
SerializeRecursively(property_value, context, max_depth);
std::unique_ptr<protocol::ListValue> value_list =
std::unique_ptr<protocol::ListValue> key_value_list =
protocol::ListValue::create();
value_list->pushValue(std::move(key_protocol_value));
value_list->pushValue(std::move(property_protocol_value));
key_value_list->pushValue(std::move(key_protocol_value));
key_value_list->pushValue(std::move(property_protocol_value));
result_list->pushValue(std::move(value_list));
result->pushValue(std::move(key_value_list));
}
(*result) = std::move(result_list);
return Response::Success();
}
protocol::Response _serializeObject(
v8::Local<v8::Object> value, v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Object)
.build();
if (max_depth <= 0) return Response::Success();
std::unique_ptr<protocol::Value> result_value;
Response response = _serializeObjectValue(value.As<v8::Object>(), context,
max_depth, &result_value);
if (!response.IsSuccess()) return response;
return result;
}
(*result)->setValue(std::move(result_value));
return Response::Success();
std::unique_ptr<protocol::Runtime::WebDriverValue> SerializeObject(
v8::Local<v8::Object> value, v8::Local<v8::Context> context,
int max_depth) {
std::unique_ptr<protocol::Runtime::WebDriverValue> result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Object)
.build();
if (max_depth > 0) {
result->setValue(
SerializeObjectValue(value.As<v8::Object>(), context, max_depth));
}
return result;
}
} // namespace
protocol::Response V8WebDriverSerializer::serializeV8Value(
v8::Local<v8::Object> value, v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result) {
std::unique_ptr<protocol::Runtime::WebDriverValue>
V8WebDriverSerializer::serializeV8Value(v8::Local<v8::Object> value,
v8::Local<v8::Context> context,
int max_depth) {
if (value->IsArray()) {
Response response =
_serializeArray(value.As<v8::Array>(), context, max_depth, result);
return response;
return SerializeArray(value.As<v8::Array>(), context, max_depth);
}
if (value->IsRegExp()) {
Response response =
_serializeRegexp(value.As<v8::RegExp>(), context, max_depth, result);
return response;
return SerializeRegexp(value.As<v8::RegExp>(), context);
}
if (value->IsDate()) {
Response response =
_serializeDate(value.As<v8::Date>(), context, max_depth, result);
return response;
return SerializeDate(value.As<v8::Date>(), context);
}
if (value->IsMap()) {
Response response =
_serializeMap(value.As<v8::Map>(), context, max_depth, result);
return response;
return SerializeMap(value.As<v8::Map>(), context, max_depth);
}
if (value->IsSet()) {
Response response =
_serializeSet(value.As<v8::Set>(), context, max_depth, result);
return response;
return SerializeSet(value.As<v8::Set>(), context, max_depth);
}
if (value->IsWeakMap()) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Weakmap)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Weakmap)
.build();
}
if (value->IsWeakSet()) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Weakset)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Weakset)
.build();
}
if (value->IsNativeError()) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Error)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Error)
.build();
}
if (value->IsProxy()) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Proxy)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Proxy)
.build();
}
if (value->IsPromise()) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Promise)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Promise)
.build();
}
if (value->IsTypedArray()) {
*result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Typedarray)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Typedarray)
.build();
}
if (value->IsArrayBuffer()) {
*result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Arraybuffer)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Arraybuffer)
.build();
}
if (value->IsFunction()) {
*result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Function)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Function)
.build();
}
// Serialize as an Object.
Response response =
_serializeObject(value.As<v8::Object>(), context, max_depth, result);
return response;
return SerializeObject(value.As<v8::Object>(), context, max_depth);
}
} // namespace v8_inspector
......@@ -15,10 +15,9 @@
namespace v8_inspector {
class V8WebDriverSerializer {
public:
static protocol::Response serializeV8Value(
static std::unique_ptr<protocol::Runtime::WebDriverValue> serializeV8Value(
v8::Local<v8::Object> value, v8::Local<v8::Context> context,
int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result);
int max_depth);
};
} // namespace v8_inspector
......
......@@ -439,44 +439,40 @@ class PrimitiveValueMirror final : public ValueMirror {
(*preview)->setSubtype(RemoteObject::SubtypeEnum::Null);
}
protocol::Response buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result)
const override {
std::unique_ptr<protocol::Runtime::WebDriverValue> buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth) const override {
// https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-primitiveProtocolValue-serialization
if (m_value->IsUndefined()) {
*result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Undefined)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Undefined)
.build();
}
if (m_value->IsNull()) {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Null)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Null)
.build();
}
if (m_value->IsString()) {
*result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::String)
.setValue(protocol::StringValue::create(toProtocolString(
context->GetIsolate(), m_value.As<v8::String>())))
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::String)
.setValue(protocol::StringValue::create(toProtocolString(
context->GetIsolate(), m_value.As<v8::String>())))
.build();
}
if (m_value->IsBoolean()) {
*result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Boolean)
.setValue(protocol::FundamentalValue::create(
m_value.As<v8::Boolean>()->Value()))
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Boolean)
.setValue(protocol::FundamentalValue::create(
m_value.As<v8::Boolean>()->Value()))
.build();
}
return Response::ServerError("unexpected primitive type");
DCHECK(false);
// Fallback.
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Object)
.build();
}
private:
......@@ -529,23 +525,21 @@ class NumberMirror final : public ValueMirror {
.build();
}
protocol::Response buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result)
const override {
std::unique_ptr<protocol::Runtime::WebDriverValue> buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth) const override {
// https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-primitiveProtocolValue-serialization
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Number)
.build();
std::unique_ptr<protocol::Runtime::WebDriverValue> result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Number)
.build();
bool unserializable = false;
String16 descriptionValue = description(&unserializable);
if (unserializable) {
(*result)->setValue(protocol::StringValue::create(descriptionValue));
result->setValue(protocol::StringValue::create(descriptionValue));
} else {
(*result)->setValue(toProtocolValue(m_value.As<v8::Number>()->Value()));
result->setValue(toProtocolValue(m_value.As<v8::Number>()->Value()));
}
return Response::Success();
return result;
}
private:
......@@ -608,18 +602,15 @@ class BigIntMirror final : public ValueMirror {
v8::Local<v8::Value> v8Value() const override { return m_value; }
protocol::Response buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result)
const override {
std::unique_ptr<protocol::Runtime::WebDriverValue> buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth) const override {
// https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-primitiveProtocolValue-serialization
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Bigint)
.setValue(protocol::StringValue::create(
descriptionForBigInt(context, m_value)))
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Bigint)
.setValue(protocol::StringValue::create(
descriptionForBigInt(context, m_value)))
.build();
}
private:
......@@ -658,15 +649,12 @@ class SymbolMirror final : public ValueMirror {
v8::Local<v8::Value> v8Value() const override { return m_symbol; }
protocol::Response buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result)
const override {
std::unique_ptr<protocol::Runtime::WebDriverValue> buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth) const override {
// https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-RemoteValue-serialization
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Symbol)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Symbol)
.build();
}
private:
......@@ -713,14 +701,11 @@ class LocationMirror final : public ValueMirror {
}
v8::Local<v8::Value> v8Value() const override { return m_value; }
protocol::Response buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result)
const override {
*result = protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Object)
.build();
return Response::Success();
std::unique_ptr<protocol::Runtime::WebDriverValue> buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth) const override {
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Object)
.build();
}
private:
......@@ -800,16 +785,12 @@ class FunctionMirror final : public ValueMirror {
.build();
}
protocol::Response buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result)
const override {
std::unique_ptr<protocol::Runtime::WebDriverValue> buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth) const override {
// https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-RemoteValue-serialization
*result =
protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Function)
.build();
return Response::Success();
return protocol::Runtime::WebDriverValue::create()
.setType(protocol::Runtime::WebDriverValue::TypeEnum::Function)
.build();
}
private:
......@@ -1097,10 +1078,8 @@ class ObjectMirror final : public ValueMirror {
if (m_hasSubtype) (*result)->setSubtype(m_subtype);
}
protocol::Response buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result)
const override {
std::unique_ptr<protocol::Runtime::WebDriverValue> buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth) const override {
// https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-RemoteValue-serialization
// Check if embedder implemented custom serialization.
......@@ -1109,27 +1088,24 @@ class ObjectMirror final : public ValueMirror {
if (embedder_serialized_result) {
// Embedder-implemented serialization.
*result = protocol::Runtime::WebDriverValue::create()
.setType(toString16(embedder_serialized_result->type))
.build();
std::unique_ptr<protocol::Runtime::WebDriverValue> result =
protocol::Runtime::WebDriverValue::create()
.setType(toString16(embedder_serialized_result->type->string()))
.build();
if (!embedder_serialized_result->value.IsEmpty()) {
v8::Local<v8::Value> v8_value;
if (embedder_serialized_result->value.ToLocal(&v8_value)) {
// Embedder-implemented serialization has value.
std::unique_ptr<protocol::Value> protocol_value;
Response response = toProtocolValue(
context, embedder_serialized_result->value.ToLocalChecked(),
&protocol_value);
if (!response.IsSuccess()) return response;
(*result)->setValue(std::move(protocol_value));
Response response = toProtocolValue(context, v8_value, &protocol_value);
DCHECK(response.IsSuccess());
result->setValue(std::move(protocol_value));
}
return Response::Success();
return result;
}
// No embedder-implemented serialization. Serialize as V8 Object.
Response response = V8WebDriverSerializer::serializeV8Value(
m_value, context, max_depth, result);
return response;
return V8WebDriverSerializer::serializeV8Value(m_value, context, max_depth);
}
private:
......
......@@ -66,9 +66,8 @@ class ValueMirror {
v8::Local<v8::Context> context, int* nameLimit, int* indexLimit,
std::unique_ptr<protocol::Runtime::ObjectPreview>*) const {}
virtual v8::Local<v8::Value> v8Value() const = 0;
virtual protocol::Response buildWebDriverValue(
v8::Local<v8::Context> context, int max_depth,
std::unique_ptr<protocol::Runtime::WebDriverValue>* result) const = 0;
virtual std::unique_ptr<protocol::Runtime::WebDriverValue>
buildWebDriverValue(v8::Local<v8::Context> context, int max_depth) const = 0;
class PropertyAccumulator {
public:
......
......@@ -193,7 +193,7 @@ Runtime.callFunctionOn
}
Running test: Array
testing expression: [1,2]
testing expression: [1,2,undefined]
Runtime.evaluate
{
type : array
......@@ -206,6 +206,9 @@ Runtime.evaluate
type : number
value : 2
}
[2] : {
type : undefined
}
]
}
Runtime.callFunctionOn
......@@ -220,9 +223,12 @@ Runtime.callFunctionOn
type : number
value : 2
}
[2] : {
type : undefined
}
]
}
testing expression: new Array(1,2)
testing expression: new Array(1,2,undefined)
Runtime.evaluate
{
type : array
......@@ -235,6 +241,9 @@ Runtime.evaluate
type : number
value : 2
}
[2] : {
type : undefined
}
]
}
Runtime.callFunctionOn
......@@ -249,6 +258,9 @@ Runtime.callFunctionOn
type : number
value : 2
}
[2] : {
type : undefined
}
]
}
......@@ -399,7 +411,7 @@ Runtime.callFunctionOn
}
Running test: Set
testing expression: new Set([{valueObject1: 1}, 'valueString2', new Array()])
testing expression: new Set([{valueObject1: 1}, 'valueString2', new Array(), undefined])
Runtime.evaluate
{
type : set
......@@ -414,6 +426,9 @@ Runtime.evaluate
[2] : {
type : array
}
[3] : {
type : undefined
}
]
}
Runtime.callFunctionOn
......@@ -430,6 +445,9 @@ Runtime.callFunctionOn
[2] : {
type : array
}
[3] : {
type : undefined
}
]
}
......@@ -489,7 +507,7 @@ Runtime.callFunctionOn
}
Running test: Object
testing expression: {nullKey: null, stringKey: 'foo',boolKey: true,numberKey: 123,bigintKey: 123n,symbolKey: Symbol('foo'),functionKey: () => {},arrayKey:[1]}
testing expression: {nullKey: null, stringKey: 'foo',boolKey: true,numberKey: 123,bigintKey: 123n,symbolKey: Symbol('foo'),functionKey: () => {},arrayKey:[1],undefinedKey:undefined}
Runtime.evaluate
{
type : object
......@@ -546,6 +564,12 @@ Runtime.evaluate
type : array
}
]
[8] : [
[0] : undefinedKey
[1] : {
type : undefined
}
]
]
}
Runtime.callFunctionOn
......@@ -604,6 +628,12 @@ Runtime.callFunctionOn
type : array
}
]
[8] : [
[0] : undefinedKey
[1] : {
type : undefined
}
]
]
}
testing expression: {key_level_1: {key_level_2: {key_level_3: 'value_level_3'}}}
......
// Copyright 2018 the V8 project authors. All rights reserved.
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -28,8 +28,8 @@ InspectorTest.runAsyncTestSuite([
await testExpression("[function qwe(){}, ()=>{}]");
},
async function Array() {
await testExpression("[1,2]");
await testExpression("new Array(1,2)");
await testExpression("[1,2,undefined]");
await testExpression("new Array(1,2,undefined)");
},
async function RegExp() {
await testExpression("[new RegExp('ab+c'), new RegExp('ab+c', 'ig')]");
......@@ -49,7 +49,7 @@ InspectorTest.runAsyncTestSuite([
await testExpression("new WeakMap([[{valueObject1: 1}, 'keyString1'],[{valueObject2: 2}, 'keyString2']])");
},
async function Set() {
await testExpression("new Set([{valueObject1: 1}, 'valueString2', new Array()])");
await testExpression("new Set([{valueObject1: 1}, 'valueString2', new Array(), undefined])");
},
async function Weakset() {
await testExpression("new WeakSet([{valueObject1: 1}, {valueObject2: 2}])");
......@@ -68,7 +68,7 @@ InspectorTest.runAsyncTestSuite([
},
async function Object() {
// Object.
await testExpression("{nullKey: null, stringKey: 'foo',boolKey: true,numberKey: 123,bigintKey: 123n,symbolKey: Symbol('foo'),functionKey: () => {},arrayKey:[1]}");
await testExpression("{nullKey: null, stringKey: 'foo',boolKey: true,numberKey: 123,bigintKey: 123n,symbolKey: Symbol('foo'),functionKey: () => {},arrayKey:[1],undefinedKey:undefined}");
// Object in-depth serialization.
await testExpression("{key_level_1: {key_level_2: {key_level_3: 'value_level_3'}}}");
}]);
......
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