LibWeb: Add structured_deserialize_internal()

structured_deserialize_internal() is added to support sub
deserialization from serializable interfaces serialization steps which
needs the ability to pass onto the current position in the deserialized
data.
This commit is contained in:
Kenneth Myhra 2024-03-10 20:37:41 +01:00 committed by Andreas Kling
parent 31f345fcb0
commit ca54691ecf
Notes: sideshowbarker 2024-07-17 08:35:21 +09:00
2 changed files with 25 additions and 6 deletions

View File

@ -663,14 +663,17 @@ template WebIDL::ExceptionOr<void> serialize_viewed_array_buffer(JS::VM& vm, Vec
class Deserializer {
public:
Deserializer(JS::VM& vm, JS::Realm& target_realm, ReadonlySpan<u32> serialized, DeserializationMemory& memory)
Deserializer(JS::VM& vm, JS::Realm& target_realm, ReadonlySpan<u32> serialized, DeserializationMemory& memory, Optional<size_t> position = {})
: m_vm(vm)
, m_serialized(serialized)
, m_memory(memory)
, m_position(position.value_or(0))
{
VERIFY(vm.current_realm() == &target_realm);
}
size_t position() const { return m_position; }
// https://html.spec.whatwg.org/multipage/structured-data.html#structureddeserialize
WebIDL::ExceptionOr<JS::Value> deserialize()
{
@ -960,8 +963,8 @@ public:
private:
JS::VM& m_vm;
ReadonlySpan<u32> m_serialized;
size_t m_position { 0 };
JS::MarkedVector<JS::Value> m_memory; // Index -> JS value
size_t m_position { 0 };
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Bindings::PlatformObject>> create_serialized_type(StringView interface_name, JS::Realm& realm)
{
@ -1288,12 +1291,22 @@ WebIDL::ExceptionOr<JS::Value> structured_deserialize(JS::VM& vm, SerializationR
auto& target_settings = Bindings::host_defined_environment_settings_object(target_realm);
target_settings.prepare_to_run_script();
Deserializer deserializer(vm, target_realm, serialized.span(), *memory);
auto result = deserializer.deserialize();
auto result = TRY(structured_deserialize_internal(vm, serialized.span(), target_realm, *memory));
target_settings.clean_up_after_running_script();
return result;
VERIFY(result.value.has_value());
return *result.value;
}
WebIDL::ExceptionOr<DeserializedRecord> structured_deserialize_internal(JS::VM& vm, ReadonlySpan<u32> const& serialized, JS::Realm& target_realm, DeserializationMemory& memory, Optional<size_t> position)
{
Deserializer deserializer(vm, target_realm, serialized, memory, move(position));
auto value = TRY(deserializer.deserialize());
auto deserialized_record = DeserializedRecord {
.value = value,
.position = deserializer.position(),
};
return deserialized_record;
}
}

View File

@ -41,6 +41,11 @@ struct DeserializedTransferRecord {
Vector<JS::Handle<JS::Object>> transferred_values;
};
struct DeserializedRecord {
Optional<JS::Value> value;
size_t position;
};
enum class TransferType : u8 {
MessagePort,
};
@ -50,6 +55,7 @@ WebIDL::ExceptionOr<SerializationRecord> structured_serialize_for_storage(JS::VM
WebIDL::ExceptionOr<SerializationRecord> structured_serialize_internal(JS::VM& vm, JS::Value, bool for_storage, SerializationMemory&);
WebIDL::ExceptionOr<JS::Value> structured_deserialize(JS::VM& vm, SerializationRecord const& serialized, JS::Realm& target_realm, Optional<DeserializationMemory>);
WebIDL::ExceptionOr<DeserializedRecord> structured_deserialize_internal(JS::VM& vm, ReadonlySpan<u32> const& serialized, JS::Realm& target_realm, DeserializationMemory& memory, Optional<size_t> position = {});
void serialize_boolean_primitive(SerializationRecord& serialized, JS::Value& value);
void serialize_number_primitive(SerializationRecord& serialized, JS::Value& value);