mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-03 17:58:49 +00:00
LibWeb: Extract serialization logic for primitives and object primitives
To avoid differing logic for serializing similar types, move the logic into separate helpers.
This commit is contained in:
parent
98e272ce15
commit
c384f22d67
Notes:
sideshowbarker
2024-07-17 23:02:37 +09:00
Author: https://github.com/kennethmyhra
Commit: c384f22d67
Pull-request: https://github.com/SerenityOS/serenity/pull/23438
Reviewed-by: https://github.com/ADKaster ✅
2 changed files with 100 additions and 24 deletions
|
@ -167,18 +167,16 @@ public:
|
||||||
m_serialized.append(ValueTag::NullPrimitive);
|
m_serialized.append(ValueTag::NullPrimitive);
|
||||||
} else if (value.is_boolean()) {
|
} else if (value.is_boolean()) {
|
||||||
m_serialized.append(ValueTag::BooleanPrimitive);
|
m_serialized.append(ValueTag::BooleanPrimitive);
|
||||||
m_serialized.append(static_cast<u32>(value.as_bool()));
|
serialize_boolean_primitive(m_serialized, value);
|
||||||
} else if (value.is_number()) {
|
} else if (value.is_number()) {
|
||||||
m_serialized.append(ValueTag::NumberPrimitive);
|
m_serialized.append(ValueTag::NumberPrimitive);
|
||||||
double number = value.as_double();
|
serialize_number_primitive(m_serialized, value);
|
||||||
m_serialized.append(bit_cast<u32*>(&number), 2);
|
|
||||||
} else if (value.is_bigint()) {
|
} else if (value.is_bigint()) {
|
||||||
m_serialized.append(ValueTag::BigIntPrimitive);
|
m_serialized.append(ValueTag::BigIntPrimitive);
|
||||||
auto& val = value.as_bigint();
|
TRY(serialize_big_int_primitive(m_vm, m_serialized, value));
|
||||||
TRY(serialize_string(m_vm, m_serialized, TRY_OR_THROW_OOM(m_vm, val.to_string())));
|
|
||||||
} else if (value.is_string()) {
|
} else if (value.is_string()) {
|
||||||
m_serialized.append(ValueTag::StringPrimitive);
|
m_serialized.append(ValueTag::StringPrimitive);
|
||||||
TRY(serialize_string(m_vm, m_serialized, value.as_string()));
|
TRY(serialize_string_primitive(m_vm, m_serialized, value));
|
||||||
} else {
|
} else {
|
||||||
return_primitive_type = false;
|
return_primitive_type = false;
|
||||||
}
|
}
|
||||||
|
@ -195,38 +193,31 @@ public:
|
||||||
// 7. If value has a [[BooleanData]] internal slot, then set serialized to { [[Type]]: "Boolean", [[BooleanData]]: value.[[BooleanData]] }.
|
// 7. If value has a [[BooleanData]] internal slot, then set serialized to { [[Type]]: "Boolean", [[BooleanData]]: value.[[BooleanData]] }.
|
||||||
if (value.is_object() && is<JS::BooleanObject>(value.as_object())) {
|
if (value.is_object() && is<JS::BooleanObject>(value.as_object())) {
|
||||||
m_serialized.append(ValueTag::BooleanObject);
|
m_serialized.append(ValueTag::BooleanObject);
|
||||||
auto& boolean_object = static_cast<JS::BooleanObject&>(value.as_object());
|
serialize_boolean_object(m_serialized, value);
|
||||||
m_serialized.append(bit_cast<u32>(static_cast<u32>(boolean_object.boolean())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 8. Otherwise, if value has a [[NumberData]] internal slot, then set serialized to { [[Type]]: "Number", [[NumberData]]: value.[[NumberData]] }.
|
// 8. Otherwise, if value has a [[NumberData]] internal slot, then set serialized to { [[Type]]: "Number", [[NumberData]]: value.[[NumberData]] }.
|
||||||
else if (value.is_object() && is<JS::NumberObject>(value.as_object())) {
|
else if (value.is_object() && is<JS::NumberObject>(value.as_object())) {
|
||||||
m_serialized.append(ValueTag::NumberObject);
|
m_serialized.append(ValueTag::NumberObject);
|
||||||
auto& number_object = static_cast<JS::NumberObject&>(value.as_object());
|
serialize_number_object(m_serialized, value);
|
||||||
double const number = number_object.number();
|
|
||||||
m_serialized.append(bit_cast<u32*>(&number), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. Otherwise, if value has a [[BigIntData]] internal slot, then set serialized to { [[Type]]: "BigInt", [[BigIntData]]: value.[[BigIntData]] }.
|
// 9. Otherwise, if value has a [[BigIntData]] internal slot, then set serialized to { [[Type]]: "BigInt", [[BigIntData]]: value.[[BigIntData]] }.
|
||||||
else if (value.is_object() && is<JS::BigIntObject>(value.as_object())) {
|
else if (value.is_object() && is<JS::BigIntObject>(value.as_object())) {
|
||||||
m_serialized.append(ValueTag::BigIntObject);
|
m_serialized.append(ValueTag::BigIntObject);
|
||||||
auto& bigint_object = static_cast<JS::BigIntObject&>(value.as_object());
|
TRY(serialize_big_int_object(m_vm, m_serialized, value));
|
||||||
TRY(serialize_string(m_vm, m_serialized, TRY_OR_THROW_OOM(m_vm, bigint_object.bigint().to_string())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. Otherwise, if value has a [[StringData]] internal slot, then set serialized to { [[Type]]: "String", [[StringData]]: value.[[StringData]] }.
|
// 10. Otherwise, if value has a [[StringData]] internal slot, then set serialized to { [[Type]]: "String", [[StringData]]: value.[[StringData]] }.
|
||||||
else if (value.is_object() && is<JS::StringObject>(value.as_object())) {
|
else if (value.is_object() && is<JS::StringObject>(value.as_object())) {
|
||||||
m_serialized.append(ValueTag::StringObject);
|
m_serialized.append(ValueTag::StringObject);
|
||||||
auto& string_object = static_cast<JS::StringObject&>(value.as_object());
|
TRY(serialize_string_object(m_vm, m_serialized, value));
|
||||||
TRY(serialize_string(m_vm, m_serialized, string_object.primitive_string()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 11. Otherwise, if value has a [[DateValue]] internal slot, then set serialized to { [[Type]]: "Date", [[DateValue]]: value.[[DateValue]] }.
|
// 11. Otherwise, if value has a [[DateValue]] internal slot, then set serialized to { [[Type]]: "Date", [[DateValue]]: value.[[DateValue]] }.
|
||||||
else if (value.is_object() && is<JS::Date>(value.as_object())) {
|
else if (value.is_object() && is<JS::Date>(value.as_object())) {
|
||||||
m_serialized.append(ValueTag::DateObject);
|
m_serialized.append(ValueTag::DateObject);
|
||||||
auto& date_object = static_cast<JS::Date&>(value.as_object());
|
serialize_date_object(m_serialized, value);
|
||||||
double const date_value = date_object.date_value();
|
|
||||||
m_serialized.append(bit_cast<u32*>(&date_value), 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12. Otherwise, if value has a [[RegExpMatcher]] internal slot, then set serialized to
|
// 12. Otherwise, if value has a [[RegExpMatcher]] internal slot, then set serialized to
|
||||||
|
@ -234,12 +225,7 @@ public:
|
||||||
// [[OriginalFlags]]: value.[[OriginalFlags]] }.
|
// [[OriginalFlags]]: value.[[OriginalFlags]] }.
|
||||||
else if (value.is_object() && is<JS::RegExpObject>(value.as_object())) {
|
else if (value.is_object() && is<JS::RegExpObject>(value.as_object())) {
|
||||||
m_serialized.append(ValueTag::RegExpObject);
|
m_serialized.append(ValueTag::RegExpObject);
|
||||||
auto& regexp_object = static_cast<JS::RegExpObject&>(value.as_object());
|
TRY(serialize_reg_exp_object(m_vm, m_serialized, value));
|
||||||
// Note: A Regex<ECMA262> object is perfectly happy to be reconstructed with just the source+flags
|
|
||||||
// In the future, we could optimize the work being done on the deserialize step by serializing
|
|
||||||
// more of the internal state (the [[RegExpMatcher]] internal slot)
|
|
||||||
TRY(serialize_string(m_vm, m_serialized, TRY_OR_THROW_OOM(m_vm, String::from_byte_string(regexp_object.pattern()))));
|
|
||||||
TRY(serialize_string(m_vm, m_serialized, TRY_OR_THROW_OOM(m_vm, String::from_byte_string(regexp_object.flags()))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 13. Otherwise, if value has an [[ArrayBufferData]] internal slot, then:
|
// 13. Otherwise, if value has an [[ArrayBufferData]] internal slot, then:
|
||||||
|
@ -442,6 +428,85 @@ private:
|
||||||
bool m_for_storage { false };
|
bool m_for_storage { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void serialize_boolean_primitive(SerializationRecord& serialized, JS::Value& value)
|
||||||
|
{
|
||||||
|
VERIFY(value.is_boolean());
|
||||||
|
serialized.append(static_cast<u32>(value.as_bool()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize_number_primitive(SerializationRecord& serialized, JS::Value& value)
|
||||||
|
{
|
||||||
|
VERIFY(value.is_number());
|
||||||
|
double number = value.as_double();
|
||||||
|
serialized.append(bit_cast<u32*>(&number), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<void> serialize_big_int_primitive(JS::VM& vm, SerializationRecord& serialized, JS::Value& value)
|
||||||
|
{
|
||||||
|
VERIFY(value.is_bigint());
|
||||||
|
auto& val = value.as_bigint();
|
||||||
|
TRY(serialize_string(vm, serialized, TRY_OR_THROW_OOM(vm, val.to_string())));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<void> serialize_string_primitive(JS::VM& vm, SerializationRecord& serialized, JS::Value& value)
|
||||||
|
{
|
||||||
|
VERIFY(value.is_string());
|
||||||
|
TRY(serialize_string(vm, serialized, value.as_string()));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize_boolean_object(SerializationRecord& serialized, JS::Value& value)
|
||||||
|
{
|
||||||
|
VERIFY(value.is_object() && is<JS::BooleanObject>(value.as_object()));
|
||||||
|
auto& boolean_object = static_cast<JS::BooleanObject&>(value.as_object());
|
||||||
|
serialized.append(bit_cast<u32>(static_cast<u32>(boolean_object.boolean())));
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize_number_object(SerializationRecord& serialized, JS::Value& value)
|
||||||
|
{
|
||||||
|
VERIFY(value.is_object() && is<JS::NumberObject>(value.as_object()));
|
||||||
|
auto& number_object = static_cast<JS::NumberObject&>(value.as_object());
|
||||||
|
double const number = number_object.number();
|
||||||
|
serialized.append(bit_cast<u32*>(&number), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<void> serialize_big_int_object(JS::VM& vm, SerializationRecord& serialized, JS::Value& value)
|
||||||
|
{
|
||||||
|
VERIFY(value.is_object() && is<JS::BigIntObject>(value.as_object()));
|
||||||
|
auto& bigint_object = static_cast<JS::BigIntObject&>(value.as_object());
|
||||||
|
TRY(serialize_string(vm, serialized, TRY_OR_THROW_OOM(vm, bigint_object.bigint().to_string())));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<void> serialize_string_object(JS::VM& vm, SerializationRecord& serialized, JS::Value& value)
|
||||||
|
{
|
||||||
|
VERIFY(value.is_object() && is<JS::StringObject>(value.as_object()));
|
||||||
|
auto& string_object = static_cast<JS::StringObject&>(value.as_object());
|
||||||
|
TRY(serialize_string(vm, serialized, string_object.primitive_string()));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialize_date_object(SerializationRecord& serialized, JS::Value& value)
|
||||||
|
{
|
||||||
|
VERIFY(value.is_object() && is<JS::Date>(value.as_object()));
|
||||||
|
auto& date_object = static_cast<JS::Date&>(value.as_object());
|
||||||
|
double const date_value = date_object.date_value();
|
||||||
|
serialized.append(bit_cast<u32*>(&date_value), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<void> serialize_reg_exp_object(JS::VM& vm, SerializationRecord& serialized, JS::Value& value)
|
||||||
|
{
|
||||||
|
VERIFY(value.is_object() && is<JS::RegExpObject>(value.as_object()));
|
||||||
|
auto& regexp_object = static_cast<JS::RegExpObject&>(value.as_object());
|
||||||
|
// Note: A Regex<ECMA262> object is perfectly happy to be reconstructed with just the source+flags
|
||||||
|
// In the future, we could optimize the work being done on the deserialize step by serializing
|
||||||
|
// more of the internal state (the [[RegExpMatcher]] internal slot)
|
||||||
|
TRY(serialize_string(vm, serialized, TRY_OR_THROW_OOM(vm, String::from_byte_string(regexp_object.pattern()))));
|
||||||
|
TRY(serialize_string(vm, serialized, TRY_OR_THROW_OOM(vm, String::from_byte_string(regexp_object.flags()))));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
WebIDL::ExceptionOr<void> serialize_bytes(JS::VM& vm, Vector<u32>& vector, ReadonlyBytes bytes)
|
WebIDL::ExceptionOr<void> serialize_bytes(JS::VM& vm, Vector<u32>& vector, ReadonlyBytes bytes)
|
||||||
{
|
{
|
||||||
// Append size of the buffer to the serialized structure.
|
// Append size of the buffer to the serialized structure.
|
||||||
|
|
|
@ -51,6 +51,17 @@ WebIDL::ExceptionOr<SerializationRecord> structured_serialize_internal(JS::VM& v
|
||||||
|
|
||||||
WebIDL::ExceptionOr<JS::Value> structured_deserialize(JS::VM& vm, SerializationRecord const& serialized, JS::Realm& target_realm, Optional<DeserializationMemory>);
|
WebIDL::ExceptionOr<JS::Value> structured_deserialize(JS::VM& vm, SerializationRecord const& serialized, JS::Realm& target_realm, Optional<DeserializationMemory>);
|
||||||
|
|
||||||
|
void serialize_boolean_primitive(SerializationRecord& serialized, JS::Value& value);
|
||||||
|
void serialize_number_primitive(SerializationRecord& serialized, JS::Value& value);
|
||||||
|
WebIDL::ExceptionOr<void> serialize_big_int_primitive(JS::VM& vm, SerializationRecord& serialized, JS::Value& value);
|
||||||
|
WebIDL::ExceptionOr<void> serialize_string_primitive(JS::VM& vm, SerializationRecord& serialized, JS::Value& value);
|
||||||
|
void serialize_boolean_object(SerializationRecord& serialized, JS::Value& value);
|
||||||
|
void serialize_number_object(SerializationRecord& serialized, JS::Value& value);
|
||||||
|
WebIDL::ExceptionOr<void> serialize_big_int_object(JS::VM& vm, SerializationRecord& serialized, JS::Value& value);
|
||||||
|
WebIDL::ExceptionOr<void> serialize_string_object(JS::VM& vm, SerializationRecord& serialized, JS::Value& value);
|
||||||
|
void serialize_date_object(SerializationRecord& serialized, JS::Value& value);
|
||||||
|
WebIDL::ExceptionOr<void> serialize_reg_exp_object(JS::VM& vm, SerializationRecord& serialized, JS::Value& value);
|
||||||
|
|
||||||
WebIDL::ExceptionOr<void> serialize_bytes(JS::VM& vm, Vector<u32>& vector, ReadonlyBytes bytes);
|
WebIDL::ExceptionOr<void> serialize_bytes(JS::VM& vm, Vector<u32>& vector, ReadonlyBytes bytes);
|
||||||
WebIDL::ExceptionOr<void> serialize_string(JS::VM& vm, Vector<u32>& vector, DeprecatedFlyString const& string);
|
WebIDL::ExceptionOr<void> serialize_string(JS::VM& vm, Vector<u32>& vector, DeprecatedFlyString const& string);
|
||||||
WebIDL::ExceptionOr<void> serialize_string(JS::VM& vm, Vector<u32>& vector, String const& string);
|
WebIDL::ExceptionOr<void> serialize_string(JS::VM& vm, Vector<u32>& vector, String const& string);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue