diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp
index c390d3e76e..4cf45babc1 100644
--- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp
+++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp
@@ -26,6 +26,8 @@
namespace Web::HTML {
+static WebIDL::ExceptionOr structured_deserialize_impl(JS::VM& vm, ReadonlySpan serialized, JS::Realm& target_realm, SerializationMemory& memory);
+
// Binary format:
// A list of adjacent shallow values, which may contain references to other
// values (noted by their position in the list, one value following another).
@@ -309,11 +311,13 @@ private:
class Deserializer {
public:
- Deserializer(JS::VM& vm, JS::Realm& target_realm, SerializationRecord const& v)
+ Deserializer(JS::VM& vm, JS::Realm& target_realm, ReadonlySpan v, SerializationMemory& serialization_memory)
: m_vm(vm)
, m_vector(v)
, m_memory(target_realm.heap())
+ , m_serialization_memory(serialization_memory)
{
+ VERIFY(vm.current_realm() == &target_realm);
}
WebIDL::ExceptionOr deserialize()
@@ -417,11 +421,12 @@ public:
private:
JS::VM& m_vm;
- SerializationRecord const& m_vector;
+ ReadonlySpan m_vector;
JS::MarkedVector m_memory; // Index -> JS value
Optional m_error;
+ SerializationMemory& m_serialization_memory;
- static WebIDL::ExceptionOr deserialize_bytes(JS::VM& vm, Vector const& vector, u32& position)
+ static WebIDL::ExceptionOr deserialize_bytes(JS::VM& vm, ReadonlySpan vector, u32& position)
{
u32 size_bits[2];
size_bits[0] = vector[position++];
@@ -441,7 +446,13 @@ private:
return bytes;
}
- static WebIDL::ExceptionOr> deserialize_string_primitive(JS::VM& vm, Vector const& vector, u32& position)
+ static WebIDL::ExceptionOr deserialize_string(JS::VM& vm, ReadonlySpan vector, u32& position)
+ {
+ auto bytes = TRY(deserialize_bytes(vm, vector, position));
+ return TRY_OR_THROW_OOM(vm, String::from_utf8(StringView { bytes }));
+ }
+
+ static WebIDL::ExceptionOr> deserialize_string_primitive(JS::VM& vm, ReadonlySpan vector, u32& position)
{
auto bytes = TRY(deserialize_bytes(vm, vector, position));
@@ -450,7 +461,7 @@ private:
}));
}
- static WebIDL::ExceptionOr> deserialize_big_int_primitive(JS::VM& vm, Vector const& vector, u32& position)
+ static WebIDL::ExceptionOr> deserialize_big_int_primitive(JS::VM& vm, ReadonlySpan vector, u32& position)
{
auto string = TRY(deserialize_string_primitive(vm, vector, position));
auto string_view = TRY(Bindings::throw_dom_exception_if_needed(vm, [&string]() {
@@ -464,36 +475,43 @@ private:
WebIDL::ExceptionOr structured_serialize(JS::VM& vm, JS::Value value)
{
// 1. Return ? StructuredSerializeInternal(value, false).
- return structured_serialize_internal(vm, value, false, {});
+ SerializationMemory memory = {};
+ return structured_serialize_internal(vm, value, false, memory);
}
// https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeforstorage
WebIDL::ExceptionOr structured_serialize_for_storage(JS::VM& vm, JS::Value value)
{
// 1. Return ? StructuredSerializeInternal(value, true).
- return structured_serialize_internal(vm, value, true, {});
+ SerializationMemory memory = {};
+ return structured_serialize_internal(vm, value, true, memory);
}
// https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal
-WebIDL::ExceptionOr structured_serialize_internal(JS::VM& vm, JS::Value value, bool for_storage, Optional memory)
+WebIDL::ExceptionOr structured_serialize_internal(JS::VM& vm, JS::Value value, bool for_storage, SerializationMemory& memory)
{
// 1. If memory was not supplied, let memory be an empty map.
- if (!memory.has_value())
- memory = SerializationMemory {};
+ // IMPLEMENTATION DEFINED: We move this requirement up to the callers to make recursion easier
- Serializer serializer(vm, *memory, for_storage);
+ Serializer serializer(vm, memory, for_storage);
return serializer.serialize(value);
}
+WebIDL::ExceptionOr structured_deserialize_impl(JS::VM& vm, ReadonlySpan serialized, JS::Realm& target_realm, SerializationMemory& memory)
+{
+ // FIXME: Do the spec steps
+ Deserializer deserializer(vm, target_realm, serialized, memory);
+ TRY(deserializer.deserialize());
+ return deserializer.result();
+}
+
// https://html.spec.whatwg.org/multipage/structured-data.html#structureddeserialize
WebIDL::ExceptionOr structured_deserialize(JS::VM& vm, SerializationRecord const& serialized, JS::Realm& target_realm, Optional memory)
{
- // FIXME: Do the spec steps
- (void)memory;
+ if (!memory.has_value())
+ memory = SerializationMemory {};
- Deserializer deserializer(vm, target_realm, serialized);
- TRY(deserializer.deserialize());
- return deserializer.result();
+ return structured_deserialize_impl(vm, serialized.span(), target_realm, *memory);
}
}
diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h
index fa111f2d50..f32cec69c9 100644
--- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h
+++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.h
@@ -29,7 +29,7 @@ using SerializationMemory = HashMap, SerializationRange>;
WebIDL::ExceptionOr structured_serialize(JS::VM& vm, JS::Value);
WebIDL::ExceptionOr structured_serialize_for_storage(JS::VM& vm, JS::Value);
-WebIDL::ExceptionOr structured_serialize_internal(JS::VM& vm, JS::Value, bool for_storage, Optional);
+WebIDL::ExceptionOr structured_serialize_internal(JS::VM& vm, JS::Value, bool for_storage, SerializationMemory&);
WebIDL::ExceptionOr structured_deserialize(JS::VM& vm, SerializationRecord const& serialized, JS::Realm& target_realm, Optional);