LibWeb+WebWorker: Use IPC mechanics for structured serialization

Our structured serialization implementation had its own bespoke encoder
and decoder to serialize JS values. It also used a u32 buffer under the
hood, which made using its structures a bit awkward. We had previously
worked around its data structures in transferable streams, which nested
transfers of MessagePort instances. We basically had to add hooks into
the MessagePort to route to the correct transfer receiving steps, and
we could not invoke the correct AOs directly as the spec dictates.

We now use IPC mechanics to encode and decode data. This works because,
although we are encoding JS values, we are only ultimately encoding
primitive and basic AK types. The resulting data structures actually
enforce that we implement transferable streams exactly as the spec is
worded (I had planned to do that in a separate commit, but the fallout
of this patch actually required that change).
This commit is contained in:
Timothy Flynn 2025-07-17 09:51:04 -04:00 committed by Tim Flynn
commit 64abc6101d
Notes: github-actions[bot] 2025-07-18 14:10:44 +00:00
44 changed files with 765 additions and 970 deletions

View file

@ -19,9 +19,10 @@ public:
virtual HTML::SerializeType serialize_type() const = 0; virtual HTML::SerializeType serialize_type() const = 0;
// https://html.spec.whatwg.org/multipage/structured-data.html#serialization-steps // https://html.spec.whatwg.org/multipage/structured-data.html#serialization-steps
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord&, bool for_storage, HTML::SerializationMemory&) = 0; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) = 0;
// https://html.spec.whatwg.org/multipage/structured-data.html#deserialization-steps // https://html.spec.whatwg.org/multipage/structured-data.html#deserialization-steps
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const&, size_t& position, HTML::DeserializationMemory&) = 0; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) = 0;
}; };
} }

View file

@ -18,10 +18,10 @@ public:
virtual ~Transferable() = default; virtual ~Transferable() = default;
// NOTE: It is an error to call Base::transfer_steps in your impl // NOTE: It is an error to call Base::transfer_steps in your impl
virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataHolder&) = 0; virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataEncoder&) = 0;
// NOTE: It is an error to call Base::transfer_receiving_steps in your impl // NOTE: It is an error to call Base::transfer_receiving_steps in your impl
virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataHolder&) = 0; virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataDecoder&) = 0;
virtual HTML::TransferType primary_interface() const = 0; virtual HTML::TransferType primary_interface() const = 0;

View file

@ -134,51 +134,47 @@ JS_DEFINE_NATIVE_FUNCTION(CryptoKeyPair::private_key_getter)
return TRY(Bindings::throw_dom_exception_if_needed(vm, [&] { return impl->private_key(); })); return TRY(Bindings::throw_dom_exception_if_needed(vm, [&] { return impl->private_key(); }));
} }
WebIDL::ExceptionOr<void> CryptoKey::serialization_steps(HTML::SerializationRecord& serialized, bool for_storage, HTML::SerializationMemory& memory) WebIDL::ExceptionOr<void> CryptoKey::serialization_steps(HTML::TransferDataEncoder& serialized, bool for_storage, HTML::SerializationMemory& memory)
{ {
auto& vm = this->vm(); auto& vm = this->vm();
// 1. Set serialized.[[Type]] to the [[type]] internal slot of value. // 1. Set serialized.[[Type]] to the [[type]] internal slot of value.
HTML::serialize_primitive_type(serialized, static_cast<u32>(m_type)); serialized.encode(m_type);
// 2. Set serialized.[[Extractable]] to the [[extractable]] internal slot of value. // 2. Set serialized.[[Extractable]] to the [[extractable]] internal slot of value.
HTML::serialize_primitive_type(serialized, m_extractable); serialized.encode(m_extractable);
// 3. Set serialized.[[Algorithm]] to the sub-serialization of the [[algorithm]] internal slot of value. // 3. Set serialized.[[Algorithm]] to the sub-serialization of the [[algorithm]] internal slot of value.
auto serialized_algorithm = TRY(HTML::structured_serialize_internal(vm, m_algorithm, for_storage, memory)); auto serialized_algorithm = TRY(HTML::structured_serialize_internal(vm, m_algorithm, for_storage, memory));
serialized.extend(move(serialized_algorithm)); serialized.append(move(serialized_algorithm));
// 4. Set serialized.[[Usages]] to the sub-serialization of the [[usages]] internal slot of value. // 4. Set serialized.[[Usages]] to the sub-serialization of the [[usages]] internal slot of value.
auto serialized_usages = TRY(HTML::structured_serialize_internal(vm, m_usages, for_storage, memory)); auto serialized_usages = TRY(HTML::structured_serialize_internal(vm, m_usages, for_storage, memory));
serialized.extend(move(serialized_usages)); serialized.append(move(serialized_usages));
// FIXME: 5. Set serialized.[[Handle]] to the [[handle]] internal slot of value. // FIXME: 5. Set serialized.[[Handle]] to the [[handle]] internal slot of value.
return {}; return {};
} }
WebIDL::ExceptionOr<void> CryptoKey::deserialization_steps(ReadonlySpan<u32> const& serialized, size_t& position, HTML::DeserializationMemory& memory) WebIDL::ExceptionOr<void> CryptoKey::deserialization_steps(HTML::TransferDataDecoder& serialized, HTML::DeserializationMemory& memory)
{ {
auto& vm = this->vm(); auto& vm = this->vm();
auto& realm = this->realm(); auto& realm = this->realm();
// 1. Initialize the [[type]] internal slot of value to serialized.[[Type]]. // 1. Initialize the [[type]] internal slot of value to serialized.[[Type]].
m_type = static_cast<Bindings::KeyType>(HTML::deserialize_primitive_type<u32>(serialized, position)); m_type = serialized.decode<Bindings::KeyType>();
// 2. Initialize the [[extractable]] internal slot of value to serialized.[[Extractable]]. // 2. Initialize the [[extractable]] internal slot of value to serialized.[[Extractable]].
m_extractable = HTML::deserialize_primitive_type<bool>(serialized, position); m_extractable = serialized.decode<bool>();
// 3. Initialize the [[algorithm]] internal slot of value to the sub-deserialization of serialized.[[Algorithm]]. // 3. Initialize the [[algorithm]] internal slot of value to the sub-deserialization of serialized.[[Algorithm]].
auto deserialized_record = TRY(HTML::structured_deserialize_internal(vm, serialized, realm, memory, position)); auto deserialized = TRY(HTML::structured_deserialize_internal(vm, serialized, realm, memory));
if (deserialized_record.value.has_value()) m_algorithm = deserialized.as_object();
m_algorithm = deserialized_record.value.release_value().as_object();
position = deserialized_record.position;
// 4. Initialize the [[usages]] internal slot of value to the sub-deserialization of serialized.[[Usages]]. // 4. Initialize the [[usages]] internal slot of value to the sub-deserialization of serialized.[[Usages]].
deserialized_record = TRY(HTML::structured_deserialize_internal(vm, serialized, realm, memory, position)); deserialized = TRY(HTML::structured_deserialize_internal(vm, serialized, realm, memory));
if (deserialized_record.value.has_value()) m_usages = deserialized.as_object();
m_usages = deserialized_record.value.release_value().as_object();
position = deserialized_record.position;
// FIXME: 5. Initialize the [[handle]] internal slot of value to serialized.[[Handle]]. // FIXME: 5. Initialize the [[handle]] internal slot of value to serialized.[[Handle]].

View file

@ -48,8 +48,8 @@ public:
String algorithm_name() const; String algorithm_name() const;
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::CryptoKey; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::CryptoKey; }
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord& record, bool for_storage, HTML::SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const& record, size_t& position, HTML::DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
private: private:
CryptoKey(JS::Realm&, InternalKeyData); CryptoKey(JS::Realm&, InternalKeyData);

View file

@ -151,34 +151,32 @@ void Blob::initialize(JS::Realm& realm)
Base::initialize(realm); Base::initialize(realm);
} }
WebIDL::ExceptionOr<void> Blob::serialization_steps(HTML::SerializationRecord& record, bool, HTML::SerializationMemory&) WebIDL::ExceptionOr<void> Blob::serialization_steps(HTML::TransferDataEncoder& serialized, bool, HTML::SerializationMemory&)
{ {
auto& vm = this->vm();
// FIXME: 1. Set serialized.[[SnapshotState]] to values snapshot state. // FIXME: 1. Set serialized.[[SnapshotState]] to values snapshot state.
// NON-STANDARD: FileAPI spec doesn't specify that type should be serialized, although // NON-STANDARD: FileAPI spec doesn't specify that type should be serialized, although
// to be conformant with other browsers this needs to be serialized. // to be conformant with other browsers this needs to be serialized.
TRY(HTML::serialize_string(vm, record, m_type)); serialized.encode(m_type);
// 2. Set serialized.[[ByteSequence]] to values underlying byte sequence. // 2. Set serialized.[[ByteSequence]] to values underlying byte sequence.
TRY(HTML::serialize_bytes(vm, record, m_byte_buffer.bytes())); serialized.encode(m_byte_buffer);
return {}; return {};
} }
WebIDL::ExceptionOr<void> Blob::deserialization_steps(ReadonlySpan<u32> const& record, size_t& position, HTML::DeserializationMemory&) WebIDL::ExceptionOr<void> Blob::deserialization_steps(HTML::TransferDataDecoder& serialized, HTML::DeserializationMemory&)
{ {
auto& vm = this->vm(); auto& realm = this->realm();
// FIXME: 1. Set values snapshot state to serialized.[[SnapshotState]]. // FIXME: 1. Set values snapshot state to serialized.[[SnapshotState]].
// NON-STANDARD: FileAPI spec doesn't specify that type should be deserialized, although // NON-STANDARD: FileAPI spec doesn't specify that type should be deserialized, although
// to be conformant with other browsers this needs to be deserialized. // to be conformant with other browsers this needs to be deserialized.
m_type = TRY(HTML::deserialize_string(vm, record, position)); m_type = serialized.decode<String>();
// 2. Set values underlying byte sequence to serialized.[[ByteSequence]]. // 2. Set values underlying byte sequence to serialized.[[ByteSequence]].
m_byte_buffer = TRY(HTML::deserialize_bytes(vm, record, position)); m_byte_buffer = TRY(serialized.decode_buffer(realm));
return {}; return {};
} }

View file

@ -58,8 +58,8 @@ public:
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::Blob; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::Blob; }
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord& record, bool for_storage, HTML::SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const& record, size_t& position, HTML::DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
protected: protected:
Blob(JS::Realm&, ByteBuffer, String type); Blob(JS::Realm&, ByteBuffer, String type);

View file

@ -88,46 +88,44 @@ WebIDL::ExceptionOr<GC::Ref<File>> File::construct_impl(JS::Realm& realm, Vector
return create(realm, file_bits, file_name, options); return create(realm, file_bits, file_name, options);
} }
WebIDL::ExceptionOr<void> File::serialization_steps(HTML::SerializationRecord& record, bool, HTML::SerializationMemory&) WebIDL::ExceptionOr<void> File::serialization_steps(HTML::TransferDataEncoder& serialized, bool, HTML::SerializationMemory&)
{ {
auto& vm = this->vm();
// FIXME: 1. Set serialized.[[SnapshotState]] to values snapshot state. // FIXME: 1. Set serialized.[[SnapshotState]] to values snapshot state.
// NON-STANDARD: FileAPI spec doesn't specify that type should be serialized, although // NON-STANDARD: FileAPI spec doesn't specify that type should be serialized, although
// to be conformant with other browsers this needs to be serialized. // to be conformant with other browsers this needs to be serialized.
TRY(HTML::serialize_string(vm, record, m_type)); serialized.encode(m_type);
// 2. Set serialized.[[ByteSequence]] to values underlying byte sequence. // 2. Set serialized.[[ByteSequence]] to values underlying byte sequence.
TRY(HTML::serialize_bytes(vm, record, m_byte_buffer.bytes())); serialized.encode(m_byte_buffer);
// 3. Set serialized.[[Name]] to the value of values name attribute. // 3. Set serialized.[[Name]] to the value of values name attribute.
TRY(HTML::serialize_string(vm, record, m_name)); serialized.encode(m_name);
// 4. Set serialized.[[LastModified]] to the value of values lastModified attribute. // 4. Set serialized.[[LastModified]] to the value of values lastModified attribute.
HTML::serialize_primitive_type(record, m_last_modified); serialized.encode(m_last_modified);
return {}; return {};
} }
WebIDL::ExceptionOr<void> File::deserialization_steps(ReadonlySpan<u32> const& record, size_t& position, HTML::DeserializationMemory&) WebIDL::ExceptionOr<void> File::deserialization_steps(HTML::TransferDataDecoder& serialized, HTML::DeserializationMemory&)
{ {
auto& vm = this->vm(); auto& realm = this->realm();
// FIXME: 1. Set values snapshot state to serialized.[[SnapshotState]]. // FIXME: 1. Set values snapshot state to serialized.[[SnapshotState]].
// NON-STANDARD: FileAPI spec doesn't specify that type should be deserialized, although // NON-STANDARD: FileAPI spec doesn't specify that type should be deserialized, although
// to be conformant with other browsers this needs to be deserialized. // to be conformant with other browsers this needs to be deserialized.
m_type = TRY(HTML::deserialize_string(vm, record, position)); m_type = serialized.decode<String>();
// 2. Set values underlying byte sequence to serialized.[[ByteSequence]]. // 2. Set values underlying byte sequence to serialized.[[ByteSequence]].
m_byte_buffer = TRY(HTML::deserialize_bytes(vm, record, position)); m_byte_buffer = TRY(serialized.decode_buffer(realm));
// 3. Initialize the value of values name attribute to serialized.[[Name]]. // 3. Initialize the value of values name attribute to serialized.[[Name]].
m_name = TRY(HTML::deserialize_string(vm, record, position)); m_name = serialized.decode<String>();
// 4. Initialize the value of values lastModified attribute to serialized.[[LastModified]]. // 4. Initialize the value of values lastModified attribute to serialized.[[LastModified]].
m_last_modified = HTML::deserialize_primitive_type<i64>(record, position); m_last_modified = serialized.decode<i64>();
return {}; return {};
} }

View file

@ -32,8 +32,8 @@ public:
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::File; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::File; }
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord& record, bool for_storage, HTML::SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const&, size_t& position, HTML::DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
private: private:
File(JS::Realm&, ByteBuffer, String file_name, String type, i64 last_modified); File(JS::Realm&, ByteBuffer, String file_name, String type, i64 last_modified);

View file

@ -48,31 +48,33 @@ void FileList::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_files); visitor.visit(m_files);
} }
WebIDL::ExceptionOr<void> FileList::serialization_steps(HTML::SerializationRecord& serialized, bool for_storage, HTML::SerializationMemory& memory) WebIDL::ExceptionOr<void> FileList::serialization_steps(HTML::TransferDataEncoder& serialized, bool for_storage, HTML::SerializationMemory& memory)
{ {
auto& vm = this->vm(); auto& vm = this->vm();
// 1. Set serialized.[[Files]] to an empty list. // 1. Set serialized.[[Files]] to an empty list.
// 2. For each file in value, append the sub-serialization of file to serialized.[[Files]]. // 2. For each file in value, append the sub-serialization of file to serialized.[[Files]].
HTML::serialize_primitive_type(serialized, m_files.size()); serialized.encode(m_files.size());
for (auto& file : m_files)
serialized.extend(TRY(HTML::structured_serialize_internal(vm, file, for_storage, memory))); for (auto file : m_files)
serialized.append(TRY(HTML::structured_serialize_internal(vm, file, for_storage, memory)));
return {}; return {};
} }
WebIDL::ExceptionOr<void> FileList::deserialization_steps(ReadonlySpan<u32> const& serialized, size_t& position, HTML::DeserializationMemory& memory) WebIDL::ExceptionOr<void> FileList::deserialization_steps(HTML::TransferDataDecoder& serialized, HTML::DeserializationMemory& memory)
{ {
auto& vm = this->vm(); auto& vm = this->vm();
auto& realm = *vm.current_realm(); auto& realm = this->realm();
// 1. For each file of serialized.[[Files]], add the sub-deserialization of file to value. // 1. For each file of serialized.[[Files]], add the sub-deserialization of file to value.
auto size = HTML::deserialize_primitive_type<size_t>(serialized, position); auto size = serialized.decode<size_t>();
for (size_t i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
auto deserialized_record = TRY(HTML::structured_deserialize_internal(vm, serialized, realm, memory, position)); auto deserialized = TRY(HTML::structured_deserialize_internal(vm, serialized, realm, memory));
if (deserialized_record.value.has_value() && is<File>(deserialized_record.value.value().as_object()))
m_files.append(dynamic_cast<File&>(deserialized_record.value.release_value().as_object())); if (auto* file = as_if<File>(deserialized.as_object()))
position = deserialized_record.position; m_files.append(*file);
} }
return {}; return {};

View file

@ -46,8 +46,8 @@ public:
virtual Optional<JS::Value> item_value(size_t index) const override; virtual Optional<JS::Value> item_value(size_t index) const override;
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::FileList; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::FileList; }
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord& serialized, bool for_storage, HTML::SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const& serialized, size_t& position, HTML::DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
private: private:
explicit FileList(JS::Realm&); explicit FileList(JS::Realm&);

View file

@ -672,6 +672,8 @@ class Timer;
class TimeRanges; class TimeRanges;
class ToggleEvent; class ToggleEvent;
class TrackEvent; class TrackEvent;
class TransferDataDecoder;
class TransferDataEncoder;
class TraversableNavigable; class TraversableNavigable;
class UserActivation; class UserActivation;
class ValidityState; class ValidityState;
@ -711,7 +713,6 @@ struct SerializedTransferRecord;
struct StructuredSerializeOptions; struct StructuredSerializeOptions;
struct SyntheticRealmSettings; struct SyntheticRealmSettings;
struct ToggleTaskTracker; struct ToggleTaskTracker;
struct TransferDataHolder;
} }

View file

@ -702,82 +702,85 @@ WebIDL::ExceptionOr<String> DOMMatrixReadOnly::to_string() const
} }
// https://drafts.fxtf.org/geometry/#structured-serialization // https://drafts.fxtf.org/geometry/#structured-serialization
WebIDL::ExceptionOr<void> DOMMatrixReadOnly::serialization_steps(HTML::SerializationRecord& serialized, bool, HTML::SerializationMemory&) WebIDL::ExceptionOr<void> DOMMatrixReadOnly::serialization_steps(HTML::TransferDataEncoder& serialized, bool, HTML::SerializationMemory&)
{ {
HTML::serialize_primitive_type(serialized, m_is_2d); serialized.encode(m_is_2d);
// 1. If values is 2D is true: // 1. If values is 2D is true:
if (m_is_2d) { if (m_is_2d) {
// 1. Set serialized.[[M11]] to values m11 element. // 1. Set serialized.[[M11]] to values m11 element.
HTML::serialize_primitive_type(serialized, this->m11()); serialized.encode(m11());
// 2. Set serialized.[[M12]] to values m12 element. // 2. Set serialized.[[M12]] to values m12 element.
HTML::serialize_primitive_type(serialized, this->m12()); serialized.encode(m12());
// 3. Set serialized.[[M21]] to values m21 element. // 3. Set serialized.[[M21]] to values m21 element.
HTML::serialize_primitive_type(serialized, this->m21()); serialized.encode(m21());
// 4. Set serialized.[[M22]] to values m22 element. // 4. Set serialized.[[M22]] to values m22 element.
HTML::serialize_primitive_type(serialized, this->m22()); serialized.encode(m22());
// 5. Set serialized.[[M41]] to values m41 element. // 5. Set serialized.[[M41]] to values m41 element.
HTML::serialize_primitive_type(serialized, this->m41()); serialized.encode(m41());
// 6. Set serialized.[[M42]] to values m42 element. // 6. Set serialized.[[M42]] to values m42 element.
HTML::serialize_primitive_type(serialized, this->m42()); serialized.encode(m42());
// 7. Set serialized.[[Is2D]] to true. // 7. Set serialized.[[Is2D]] to true.
// NOTE: This is set in the beginning of the function. // NOTE: This is set in the beginning of the function.
} }
// 2. Otherwise: // 2. Otherwise:
else { else {
// 1. Set serialized.[[M11]] to values m11 element. // 1. Set serialized.[[M11]] to values m11 element.
HTML::serialize_primitive_type(serialized, this->m11()); serialized.encode(m11());
// 2. Set serialized.[[M12]] to values m12 element. // 2. Set serialized.[[M12]] to values m12 element.
HTML::serialize_primitive_type(serialized, this->m12()); serialized.encode(m12());
// 3. Set serialized.[[M13]] to values m13 element. // 3. Set serialized.[[M13]] to values m13 element.
HTML::serialize_primitive_type(serialized, this->m13()); serialized.encode(m13());
// 4. Set serialized.[[M14]] to values m14 element. // 4. Set serialized.[[M14]] to values m14 element.
HTML::serialize_primitive_type(serialized, this->m14()); serialized.encode(m14());
// 5. Set serialized.[[M21]] to values m21 element. // 5. Set serialized.[[M21]] to values m21 element.
HTML::serialize_primitive_type(serialized, this->m21()); serialized.encode(m21());
// 6. Set serialized.[[M22]] to values m22 element. // 6. Set serialized.[[M22]] to values m22 element.
HTML::serialize_primitive_type(serialized, this->m22()); serialized.encode(m22());
// 7. Set serialized.[[M23]] to values m23 element. // 7. Set serialized.[[M23]] to values m23 element.
HTML::serialize_primitive_type(serialized, this->m23()); serialized.encode(m23());
// 8. Set serialized.[[M24]] to values m24 element. // 8. Set serialized.[[M24]] to values m24 element.
HTML::serialize_primitive_type(serialized, this->m24()); serialized.encode(m24());
// 9. Set serialized.[[M31]] to values m31 element. // 9. Set serialized.[[M31]] to values m31 element.
HTML::serialize_primitive_type(serialized, this->m31()); serialized.encode(m31());
// 10. Set serialized.[[M32]] to values m32 element. // 10. Set serialized.[[M32]] to values m32 element.
HTML::serialize_primitive_type(serialized, this->m32()); serialized.encode(m32());
// 11. Set serialized.[[M33]] to values m33 element. // 11. Set serialized.[[M33]] to values m33 element.
HTML::serialize_primitive_type(serialized, this->m33()); serialized.encode(m33());
// 12. Set serialized.[[M34]] to values m34 element. // 12. Set serialized.[[M34]] to values m34 element.
HTML::serialize_primitive_type(serialized, this->m34()); serialized.encode(m34());
// 13. Set serialized.[[M41]] to values m41 element. // 13. Set serialized.[[M41]] to values m41 element.
HTML::serialize_primitive_type(serialized, this->m41()); serialized.encode(m41());
// 14. Set serialized.[[M42]] to values m42 element. // 14. Set serialized.[[M42]] to values m42 element.
HTML::serialize_primitive_type(serialized, this->m42()); serialized.encode(m42());
// 15. Set serialized.[[M43]] to values m43 element. // 15. Set serialized.[[M43]] to values m43 element.
HTML::serialize_primitive_type(serialized, this->m43()); serialized.encode(m43());
// 16. Set serialized.[[M44]] to values m44 element. // 16. Set serialized.[[M44]] to values m44 element.
HTML::serialize_primitive_type(serialized, this->m44()); serialized.encode(m44());
// 17. Set serialized.[[Is2D]] to false. // 17. Set serialized.[[Is2D]] to false.
// NOTE: This is set in the beginning of the function. // NOTE: This is set in the beginning of the function.
} }
return {}; return {};
} }
// https://drafts.fxtf.org/geometry/#structured-serialization // https://drafts.fxtf.org/geometry/#structured-serialization
WebIDL::ExceptionOr<void> DOMMatrixReadOnly::deserialization_steps(ReadonlySpan<u32> const& record, size_t& position, HTML::DeserializationMemory&) WebIDL::ExceptionOr<void> DOMMatrixReadOnly::deserialization_steps(HTML::TransferDataDecoder& serialized, HTML::DeserializationMemory&)
{ {
bool is_2d = HTML::deserialize_primitive_type<bool>(record, position); bool is_2d = serialized.decode<bool>();
// 1. If serialized.[[Is2D]] is true: // 1. If serialized.[[Is2D]] is true:
if (is_2d) { if (is_2d) {
// 1. Set values m11 element to serialized.[[M11]]. // 1. Set values m11 element to serialized.[[M11]].
double m11 = HTML::deserialize_primitive_type<double>(record, position); auto m11 = serialized.decode<double>();
// 2. Set values m12 element to serialized.[[M12]]. // 2. Set values m12 element to serialized.[[M12]].
double m12 = HTML::deserialize_primitive_type<double>(record, position); auto m12 = serialized.decode<double>();
// 3. Set values m13 element to 0. // 3. Set values m13 element to 0.
// 4. Set values m14 element to 0. // 4. Set values m14 element to 0.
// 5. Set values m21 element to serialized.[[M21]]. // 5. Set values m21 element to serialized.[[M21]].
double m21 = HTML::deserialize_primitive_type<double>(record, position); auto m21 = serialized.decode<double>();
// 6. Set values m22 element to serialized.[[M22]]. // 6. Set values m22 element to serialized.[[M22]].
double m22 = HTML::deserialize_primitive_type<double>(record, position); auto m22 = serialized.decode<double>();
// 7. Set values m23 element to 0. // 7. Set values m23 element to 0.
// 8. Set values m24 element to 0. // 8. Set values m24 element to 0.
// 9. Set values m31 element to 0. // 9. Set values m31 element to 0.
@ -785,9 +788,9 @@ WebIDL::ExceptionOr<void> DOMMatrixReadOnly::deserialization_steps(ReadonlySpan<
// 11. Set values m33 element to 1. // 11. Set values m33 element to 1.
// 12. Set values m34 element to 0. // 12. Set values m34 element to 0.
// 13. Set values m41 element to serialized.[[M41]]. // 13. Set values m41 element to serialized.[[M41]].
double m41 = HTML::deserialize_primitive_type<double>(record, position); auto m41 = serialized.decode<double>();
// 14 Set values m42 element to serialized.[[M42]]. // 14 Set values m42 element to serialized.[[M42]].
double m42 = HTML::deserialize_primitive_type<double>(record, position); auto m42 = serialized.decode<double>();
// 15. Set values m43 element to 0. // 15. Set values m43 element to 0.
// 16. Set values m44 element to 1. // 16. Set values m44 element to 1.
// 17. Set values is 2D to true. // 17. Set values is 2D to true.
@ -797,41 +800,42 @@ WebIDL::ExceptionOr<void> DOMMatrixReadOnly::deserialization_steps(ReadonlySpan<
// 2. Otherwise: // 2. Otherwise:
else { else {
// 1. Set values m11 element to serialized.[[M11]]. // 1. Set values m11 element to serialized.[[M11]].
double m11 = HTML::deserialize_primitive_type<double>(record, position); auto m11 = serialized.decode<double>();
// 2. Set values m12 element to serialized.[[M12]]. // 2. Set values m12 element to serialized.[[M12]].
double m12 = HTML::deserialize_primitive_type<double>(record, position); auto m12 = serialized.decode<double>();
// 3. Set values m13 element to serialized.[[M13]]. // 3. Set values m13 element to serialized.[[M13]].
double m13 = HTML::deserialize_primitive_type<double>(record, position); auto m13 = serialized.decode<double>();
// 4. Set values m14 element to serialized.[[M14]]. // 4. Set values m14 element to serialized.[[M14]].
double m14 = HTML::deserialize_primitive_type<double>(record, position); auto m14 = serialized.decode<double>();
// 5. Set values m21 element to serialized.[[M21]]. // 5. Set values m21 element to serialized.[[M21]].
double m21 = HTML::deserialize_primitive_type<double>(record, position); auto m21 = serialized.decode<double>();
// 6. Set values m22 element to serialized.[[M22]]. // 6. Set values m22 element to serialized.[[M22]].
double m22 = HTML::deserialize_primitive_type<double>(record, position); auto m22 = serialized.decode<double>();
// 7. Set values m23 element to serialized.[[M23]]. // 7. Set values m23 element to serialized.[[M23]].
double m23 = HTML::deserialize_primitive_type<double>(record, position); auto m23 = serialized.decode<double>();
// 8. Set values m24 element to serialized.[[M24]]. // 8. Set values m24 element to serialized.[[M24]].
double m24 = HTML::deserialize_primitive_type<double>(record, position); auto m24 = serialized.decode<double>();
// 9. Set values m31 element to serialized.[[M31]]. // 9. Set values m31 element to serialized.[[M31]].
double m31 = HTML::deserialize_primitive_type<double>(record, position); auto m31 = serialized.decode<double>();
// 10. Set values m32 element to serialized.[[M32]]. // 10. Set values m32 element to serialized.[[M32]].
double m32 = HTML::deserialize_primitive_type<double>(record, position); auto m32 = serialized.decode<double>();
// 11. Set values m33 element to serialized.[[M33]]. // 11. Set values m33 element to serialized.[[M33]].
double m33 = HTML::deserialize_primitive_type<double>(record, position); auto m33 = serialized.decode<double>();
// 12. Set values m34 element to serialized.[[M34]]. // 12. Set values m34 element to serialized.[[M34]].
double m34 = HTML::deserialize_primitive_type<double>(record, position); auto m34 = serialized.decode<double>();
// 13. Set values m41 element to serialized.[[M41]]. // 13. Set values m41 element to serialized.[[M41]].
double m41 = HTML::deserialize_primitive_type<double>(record, position); auto m41 = serialized.decode<double>();
// 14. Set values m42 element to serialized.[[M42]]. // 14. Set values m42 element to serialized.[[M42]].
double m42 = HTML::deserialize_primitive_type<double>(record, position); auto m42 = serialized.decode<double>();
// 15. Set values m43 element to serialized.[[M43]]. // 15. Set values m43 element to serialized.[[M43]].
double m43 = HTML::deserialize_primitive_type<double>(record, position); auto m43 = serialized.decode<double>();
// 16. Set values m44 element to serialized.[[M44]]. // 16. Set values m44 element to serialized.[[M44]].
double m44 = HTML::deserialize_primitive_type<double>(record, position); auto m44 = serialized.decode<double>();
// 17. Set values is 2D to false. // 17. Set values is 2D to false.
initialize_from_create_3d_matrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44); initialize_from_create_3d_matrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
} }
return {}; return {};
} }

View file

@ -116,8 +116,8 @@ public:
WebIDL::ExceptionOr<String> to_string() const; WebIDL::ExceptionOr<String> to_string() const;
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::DOMMatrixReadOnly; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::DOMMatrixReadOnly; }
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord&, bool for_storage, HTML::SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const& record, size_t& position, HTML::DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
protected: protected:
DOMMatrixReadOnly(JS::Realm&, double m11, double m12, double m21, double m22, double m41, double m42); DOMMatrixReadOnly(JS::Realm&, double m11, double m12, double m21, double m22, double m41, double m42);

View file

@ -66,30 +66,37 @@ void DOMPointReadOnly::initialize(JS::Realm& realm)
Base::initialize(realm); Base::initialize(realm);
} }
WebIDL::ExceptionOr<void> DOMPointReadOnly::serialization_steps(HTML::SerializationRecord& serialized, bool, HTML::SerializationMemory&) WebIDL::ExceptionOr<void> DOMPointReadOnly::serialization_steps(HTML::TransferDataEncoder& serialized, bool, HTML::SerializationMemory&)
{ {
// 1. Set serialized.[[X]] to values x coordinate. // 1. Set serialized.[[X]] to values x coordinate.
HTML::serialize_primitive_type(serialized, m_x); serialized.encode(m_x);
// 2. Set serialized.[[Y]] to values y coordinate. // 2. Set serialized.[[Y]] to values y coordinate.
HTML::serialize_primitive_type(serialized, m_y); serialized.encode(m_y);
// 3. Set serialized.[[Z]] to values z coordinate. // 3. Set serialized.[[Z]] to values z coordinate.
HTML::serialize_primitive_type(serialized, m_z); serialized.encode(m_z);
// 4. Set serialized.[[W]] to values w coordinate. // 4. Set serialized.[[W]] to values w coordinate.
HTML::serialize_primitive_type(serialized, m_w); serialized.encode(m_w);
return {}; return {};
} }
WebIDL::ExceptionOr<void> DOMPointReadOnly::deserialization_steps(ReadonlySpan<u32> const& serialized, size_t& position, HTML::DeserializationMemory&) WebIDL::ExceptionOr<void> DOMPointReadOnly::deserialization_steps(HTML::TransferDataDecoder& serialized, HTML::DeserializationMemory&)
{ {
// 1. Set values x coordinate to serialized.[[X]]. // 1. Set values x coordinate to serialized.[[X]].
m_x = HTML::deserialize_primitive_type<double>(serialized, position); m_x = serialized.decode<double>();
// 2. Set values y coordinate to serialized.[[Y]]. // 2. Set values y coordinate to serialized.[[Y]].
m_y = HTML::deserialize_primitive_type<double>(serialized, position); m_y = serialized.decode<double>();
// 3. Set values z coordinate to serialized.[[Z]]. // 3. Set values z coordinate to serialized.[[Z]].
m_z = HTML::deserialize_primitive_type<double>(serialized, position); m_z = serialized.decode<double>();
// 4. Set values w coordinate to serialized.[[W]]. // 4. Set values w coordinate to serialized.[[W]].
m_w = HTML::deserialize_primitive_type<double>(serialized, position); m_w = serialized.decode<double>();
return {}; return {};
} }

View file

@ -45,8 +45,8 @@ public:
WebIDL::ExceptionOr<GC::Ref<DOMPoint>> matrix_transform(DOMMatrixInit&) const; WebIDL::ExceptionOr<GC::Ref<DOMPoint>> matrix_transform(DOMMatrixInit&) const;
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::DOMPointReadOnly; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::DOMPointReadOnly; }
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord&, bool for_storage, HTML::SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const&, size_t& position, HTML::DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
protected: protected:
DOMPointReadOnly(JS::Realm&, double x, double y, double z, double w); DOMPointReadOnly(JS::Realm&, double x, double y, double z, double w);

View file

@ -103,48 +103,51 @@ GC::Ref<DOMRect> DOMQuad::get_bounds() const
} }
// https://drafts.fxtf.org/geometry/#structured-serialization // https://drafts.fxtf.org/geometry/#structured-serialization
WebIDL::ExceptionOr<void> DOMQuad::serialization_steps(HTML::SerializationRecord& serialized, bool for_storage, HTML::SerializationMemory& memory) WebIDL::ExceptionOr<void> DOMQuad::serialization_steps(HTML::TransferDataEncoder& serialized, bool for_storage, HTML::SerializationMemory& memory)
{ {
auto& vm = this->vm(); auto& vm = this->vm();
// 1. Set serialized.[[P1]] to the sub-serialization of values point 1. // 1. Set serialized.[[P1]] to the sub-serialization of values point 1.
serialized.extend(TRY(HTML::structured_serialize_internal(vm, m_p1, for_storage, memory))); serialized.append(TRY(HTML::structured_serialize_internal(vm, m_p1, for_storage, memory)));
// 2. Set serialized.[[P2]] to the sub-serialization of values point 2. // 2. Set serialized.[[P2]] to the sub-serialization of values point 2.
serialized.extend(TRY(HTML::structured_serialize_internal(vm, m_p2, for_storage, memory))); serialized.append(TRY(HTML::structured_serialize_internal(vm, m_p2, for_storage, memory)));
// 3. Set serialized.[[P3]] to the sub-serialization of values point 3. // 3. Set serialized.[[P3]] to the sub-serialization of values point 3.
serialized.extend(TRY(HTML::structured_serialize_internal(vm, m_p3, for_storage, memory))); serialized.append(TRY(HTML::structured_serialize_internal(vm, m_p3, for_storage, memory)));
// 4. Set serialized.[[P4]] to the sub-serialization of values point 4. // 4. Set serialized.[[P4]] to the sub-serialization of values point 4.
serialized.extend(TRY(HTML::structured_serialize_internal(vm, m_p4, for_storage, memory))); serialized.append(TRY(HTML::structured_serialize_internal(vm, m_p4, for_storage, memory)));
return {}; return {};
} }
// https://drafts.fxtf.org/geometry/#structured-serialization // https://drafts.fxtf.org/geometry/#structured-serialization
WebIDL::ExceptionOr<void> DOMQuad::deserialization_steps(ReadonlySpan<u32> const& serialized, size_t& position, HTML::DeserializationMemory& memory) WebIDL::ExceptionOr<void> DOMQuad::deserialization_steps(HTML::TransferDataDecoder& serialized, HTML::DeserializationMemory& memory)
{ {
auto& vm = this->vm();
auto& realm = this->realm(); auto& realm = this->realm();
auto deserialize_dom_point = [&](GC::Ref<DOMPoint>& storage) -> WebIDL::ExceptionOr<void> {
auto deserialized = TRY(HTML::structured_deserialize_internal(vm, serialized, realm, memory));
if (auto* dom_point = as_if<DOMPoint>(deserialized.as_object()))
storage = *dom_point;
return {};
};
// 1. Set values point 1 to the sub-deserialization of serialized.[[P1]]. // 1. Set values point 1 to the sub-deserialization of serialized.[[P1]].
auto deserialized_record = TRY(HTML::structured_deserialize_internal(vm(), serialized, realm, memory, position)); TRY(deserialize_dom_point(m_p1));
if (deserialized_record.value.has_value() && is<DOMPoint>(deserialized_record.value.value().as_object()))
m_p1 = dynamic_cast<DOMPoint&>(deserialized_record.value.release_value().as_object());
position = deserialized_record.position;
// 2. Set values point 2 to the sub-deserialization of serialized.[[P2]]. // 2. Set values point 2 to the sub-deserialization of serialized.[[P2]].
deserialized_record = TRY(HTML::structured_deserialize_internal(vm(), serialized, realm, memory, position)); TRY(deserialize_dom_point(m_p2));
if (deserialized_record.value.has_value() && is<DOMPoint>(deserialized_record.value.value().as_object()))
m_p2 = dynamic_cast<DOMPoint&>(deserialized_record.value.release_value().as_object());
position = deserialized_record.position;
// 3. Set values point 3 to the sub-deserialization of serialized.[[P3]]. // 3. Set values point 3 to the sub-deserialization of serialized.[[P3]].
deserialized_record = TRY(HTML::structured_deserialize_internal(vm(), serialized, realm, memory, position)); TRY(deserialize_dom_point(m_p3));
if (deserialized_record.value.has_value() && is<DOMPoint>(deserialized_record.value.value().as_object()))
m_p3 = dynamic_cast<DOMPoint&>(deserialized_record.value.release_value().as_object());
position = deserialized_record.position;
// 4. Set values point 4 to the sub-deserialization of serialized.[[P4]]. // 4. Set values point 4 to the sub-deserialization of serialized.[[P4]].
deserialized_record = TRY(HTML::structured_deserialize_internal(vm(), serialized, realm, memory, position)); TRY(deserialize_dom_point(m_p4));
if (deserialized_record.value.has_value() && is<DOMPoint>(deserialized_record.value.value().as_object()))
m_p4 = dynamic_cast<DOMPoint&>(deserialized_record.value.release_value().as_object());
position = deserialized_record.position;
return {}; return {};
} }

View file

@ -45,8 +45,8 @@ public:
GC::Ref<DOMRect> get_bounds() const; GC::Ref<DOMRect> get_bounds() const;
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::DOMQuad; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::DOMQuad; }
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord&, bool for_storage, HTML::SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const&, size_t& position, HTML::DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
private: private:
DOMQuad(JS::Realm&, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4); DOMQuad(JS::Realm&, DOMPointInit const& p1, DOMPointInit const& p2, DOMPointInit const& p3, DOMPointInit const& p4);

View file

@ -52,33 +52,39 @@ void DOMRectReadOnly::initialize(JS::Realm& realm)
} }
// https://drafts.fxtf.org/geometry/#structured-serialization // https://drafts.fxtf.org/geometry/#structured-serialization
WebIDL::ExceptionOr<void> DOMRectReadOnly::serialization_steps(HTML::SerializationRecord& serialized, bool, HTML::SerializationMemory&) WebIDL::ExceptionOr<void> DOMRectReadOnly::serialization_steps(HTML::TransferDataEncoder& serialized, bool, HTML::SerializationMemory&)
{ {
// 1. Set serialized.[[X]] to values x coordinate. // 1. Set serialized.[[X]] to values x coordinate.
HTML::serialize_primitive_type(serialized, this->x()); serialized.encode(x());
// 2. Set serialized.[[Y]] to values y coordinate. // 2. Set serialized.[[Y]] to values y coordinate.
HTML::serialize_primitive_type(serialized, this->y()); serialized.encode(y());
// 3. Set serialized.[[Width]] to values width. // 3. Set serialized.[[Width]] to values width.
HTML::serialize_primitive_type(serialized, this->width()); serialized.encode(width());
// 4. Set serialized.[[Height]] to values height. // 4. Set serialized.[[Height]] to values height.
HTML::serialize_primitive_type(serialized, this->height()); serialized.encode(height());
return {}; return {};
} }
// https://drafts.fxtf.org/geometry/#structured-serialization // https://drafts.fxtf.org/geometry/#structured-serialization
WebIDL::ExceptionOr<void> DOMRectReadOnly::deserialization_steps(ReadonlySpan<u32> const& serialized, size_t& position, HTML::DeserializationMemory&) WebIDL::ExceptionOr<void> DOMRectReadOnly::deserialization_steps(HTML::TransferDataDecoder& serialized, HTML::DeserializationMemory&)
{ {
// 1. Set values x coordinate to serialized.[[X]]. // 1. Set values x coordinate to serialized.[[X]].
auto x = HTML::deserialize_primitive_type<double>(serialized, position); auto x = serialized.decode<double>();
// 2. Set values y coordinate to serialized.[[Y]]. // 2. Set values y coordinate to serialized.[[Y]].
auto y = HTML::deserialize_primitive_type<double>(serialized, position); auto y = serialized.decode<double>();
// 3. Set values width to serialized.[[Width]]. // 3. Set values width to serialized.[[Width]].
auto width = HTML::deserialize_primitive_type<double>(serialized, position); auto width = serialized.decode<double>();
// 4. Set values height to serialized.[[Height]]. // 4. Set values height to serialized.[[Height]].
auto height = HTML::deserialize_primitive_type<double>(serialized, position); auto height = serialized.decode<double>();
m_rect = { x, y, width, height }; m_rect = { x, y, width, height };
return {}; return {};
} }

View file

@ -70,8 +70,8 @@ public:
} }
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::DOMRectReadOnly; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::DOMRectReadOnly; }
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord&, bool for_storage, HTML::SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const&, size_t& position, HTML::DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
protected: protected:
DOMRectReadOnly(JS::Realm&, double x, double y, double width, double height); DOMRectReadOnly(JS::Realm&, double x, double y, double width, double height);

View file

@ -33,31 +33,31 @@ void ImageBitmap::visit_edges(Cell::Visitor& visitor)
Base::visit_edges(visitor); Base::visit_edges(visitor);
} }
WebIDL::ExceptionOr<void> ImageBitmap::serialization_steps(HTML::SerializationRecord&, bool, HTML::SerializationMemory&) WebIDL::ExceptionOr<void> ImageBitmap::serialization_steps(HTML::TransferDataEncoder&, bool, HTML::SerializationMemory&)
{ {
// FIXME: Implement this // FIXME: Implement this
dbgln("(STUBBED) ImageBitmap::serialization_steps(HTML::SerializationRecord&, bool, HTML::SerializationMemory&)"); dbgln("(STUBBED) ImageBitmap::serialization_steps(HTML::TransferDataEncoder&, bool, HTML::SerializationMemory&)");
return {}; return {};
} }
WebIDL::ExceptionOr<void> ImageBitmap::deserialization_steps(ReadonlySpan<u32> const&, size_t&, HTML::DeserializationMemory&) WebIDL::ExceptionOr<void> ImageBitmap::deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&)
{ {
// FIXME: Implement this // FIXME: Implement this
dbgln("(STUBBED) ImageBitmap::deserialization_steps(ReadonlySpan<u32> const&, size_t&, HTML::DeserializationMemory&)"); dbgln("(STUBBED) ImageBitmap::deserialization_steps(ReadonlySpan<u32> const&, size_t&, HTML::DeserializationMemory&)");
return {}; return {};
} }
WebIDL::ExceptionOr<void> ImageBitmap::transfer_steps(HTML::TransferDataHolder&) WebIDL::ExceptionOr<void> ImageBitmap::transfer_steps(HTML::TransferDataEncoder&)
{ {
// FIXME: Implement this // FIXME: Implement this
dbgln("(STUBBED) ImageBitmap::transfer_steps(HTML::TransferDataHolder&)"); dbgln("(STUBBED) ImageBitmap::transfer_steps(HTML::TransferDataEncoder&)");
return {}; return {};
} }
WebIDL::ExceptionOr<void> ImageBitmap::transfer_receiving_steps(HTML::TransferDataHolder&) WebIDL::ExceptionOr<void> ImageBitmap::transfer_receiving_steps(HTML::TransferDataDecoder&)
{ {
// FIXME: Implement this // FIXME: Implement this
dbgln("(STUBBED) ImageBitmap::transfer_receiving_steps(HTML::TransferDataHolder&)"); dbgln("(STUBBED) ImageBitmap::transfer_receiving_steps(HTML::TransferDataDecoder&)");
return {}; return {};
} }

View file

@ -35,12 +35,12 @@ public:
// ^Web::Bindings::Serializable // ^Web::Bindings::Serializable
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::ImageBitmap; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::ImageBitmap; }
virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::SerializationRecord&, bool for_storage, HTML::SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const&, size_t& position, HTML::DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
// ^Web::Bindings::Transferable // ^Web::Bindings::Transferable
virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataEncoder&) override;
virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataDecoder&) override;
virtual HTML::TransferType primary_interface() const override; virtual HTML::TransferType primary_interface() const override;
WebIDL::UnsignedLong width() const; WebIDL::UnsignedLong width() const;

View file

@ -180,22 +180,22 @@ const JS::Uint8ClampedArray* ImageData::data() const
} }
// https://html.spec.whatwg.org/multipage/canvas.html#pixel-manipulation:serialization-steps // https://html.spec.whatwg.org/multipage/canvas.html#pixel-manipulation:serialization-steps
WebIDL::ExceptionOr<void> ImageData::serialization_steps(SerializationRecord& serialized, bool for_storage, SerializationMemory& memory) WebIDL::ExceptionOr<void> ImageData::serialization_steps(HTML::TransferDataEncoder& serialized, bool for_storage, HTML::SerializationMemory& memory)
{ {
auto& vm = this->vm(); auto& vm = this->vm();
// 1. Set serialized.[[Data]] to the sub-serialization of the value of value's data attribute. // 1. Set serialized.[[Data]] to the sub-serialization of the value of value's data attribute.
auto serialized_data = TRY(structured_serialize_internal(vm, m_data, for_storage, memory)); auto serialized_data = TRY(structured_serialize_internal(vm, m_data, for_storage, memory));
serialized.extend(move(serialized_data)); serialized.append(move(serialized_data));
// 2. Set serialized.[[Width]] to the value of value's width attribute. // 2. Set serialized.[[Width]] to the value of value's width attribute.
serialize_primitive_type(serialized, m_bitmap->width()); serialized.encode(m_bitmap->width());
// 3. Set serialized.[[Height]] to the value of value's height attribute. // 3. Set serialized.[[Height]] to the value of value's height attribute.
serialize_primitive_type(serialized, m_bitmap->height()); serialized.encode(m_bitmap->height());
// 4. Set serialized.[[ColorSpace]] to the value of value's colorSpace attribute. // 4. Set serialized.[[ColorSpace]] to the value of value's colorSpace attribute.
serialize_enum(serialized, m_color_space); serialized.encode(m_color_space);
// FIXME:: 5. Set serialized.[[PixelFormat]] to the value of value's pixelFormat attribute. // FIXME:: 5. Set serialized.[[PixelFormat]] to the value of value's pixelFormat attribute.
@ -203,26 +203,25 @@ WebIDL::ExceptionOr<void> ImageData::serialization_steps(SerializationRecord& se
} }
// https://html.spec.whatwg.org/multipage/canvas.html#pixel-manipulation:deserialization-steps // https://html.spec.whatwg.org/multipage/canvas.html#pixel-manipulation:deserialization-steps
WebIDL::ExceptionOr<void> ImageData::deserialization_steps(ReadonlySpan<u32> const& serialized, size_t& position, DeserializationMemory& memory) WebIDL::ExceptionOr<void> ImageData::deserialization_steps(HTML::TransferDataDecoder& serialized, HTML::DeserializationMemory& memory)
{ {
auto& vm = this->vm(); auto& vm = this->vm();
auto& realm = this->realm(); auto& realm = this->realm();
// 1. Initialize value's data attribute to the sub-deserialization of serialized.[[Data]]. // 1. Initialize value's data attribute to the sub-deserialization of serialized.[[Data]].
auto [value, position_after_deserialization] = TRY(structured_deserialize_internal(vm, serialized, realm, memory, position)); auto deserialized = TRY(structured_deserialize_internal(vm, serialized, realm, memory));
if (value.has_value() && value.value().is_object() && is<JS::Uint8ClampedArray>(value.value().as_object())) {
m_data = as<JS::Uint8ClampedArray>(value.release_value().as_object()); if (auto* data = as_if<JS::Uint8ClampedArray>(deserialized.as_object()))
} m_data = *data;
position = position_after_deserialization;
// 2. Initialize value's width attribute to serialized.[[Width]]. // 2. Initialize value's width attribute to serialized.[[Width]].
auto const width = deserialize_primitive_type<int>(serialized, position); auto width = serialized.decode<int>();
// 3. Initialize value's height attribute to serialized.[[Height]]. // 3. Initialize value's height attribute to serialized.[[Height]].
auto const height = deserialize_primitive_type<int>(serialized, position); auto height = serialized.decode<int>();
// 4. Initialize value's colorSpace attribute to serialized.[[ColorSpace]]. // 4. Initialize value's colorSpace attribute to serialized.[[ColorSpace]].
m_color_space = deserialize_primitive_type<Bindings::PredefinedColorSpace>(serialized, position); m_color_space = serialized.decode<Bindings::PredefinedColorSpace>();
// FIXME: 5. Initialize value's pixelFormat attribute to serialized.[[PixelFormat]]. // FIXME: 5. Initialize value's pixelFormat attribute to serialized.[[PixelFormat]].

View file

@ -47,8 +47,8 @@ public:
Bindings::PredefinedColorSpace color_space() const { return m_color_space; } Bindings::PredefinedColorSpace color_space() const { return m_color_space; }
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::ImageData; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::ImageData; }
virtual WebIDL::ExceptionOr<void> serialization_steps(SerializationRecord& serialized, bool for_storage, SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual WebIDL::ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const& serialized, size_t& position, DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
private: private:
[[nodiscard]] static WebIDL::ExceptionOr<GC::Ref<ImageData>> initialize(JS::Realm&, u32 rows, u32 pixels_per_row, Optional<ImageDataSettings> const&, GC::Ptr<JS::Uint8ClampedArray> = {}, Optional<Bindings::PredefinedColorSpace> = {}); [[nodiscard]] static WebIDL::ExceptionOr<GC::Ref<ImageData>> initialize(JS::Realm&, u32 rows, u32 pixels_per_row, Optional<ImageDataSettings> const&, GC::Ptr<JS::Uint8ClampedArray> = {}, Optional<Bindings::PredefinedColorSpace> = {});

View file

@ -89,7 +89,7 @@ void MessagePort::set_worker_event_target(GC::Ref<DOM::EventTarget> target)
} }
// https://html.spec.whatwg.org/multipage/web-messaging.html#message-ports:transfer-steps // https://html.spec.whatwg.org/multipage/web-messaging.html#message-ports:transfer-steps
WebIDL::ExceptionOr<void> MessagePort::transfer_steps(HTML::TransferDataHolder& data_holder) WebIDL::ExceptionOr<void> MessagePort::transfer_steps(HTML::TransferDataEncoder& data_holder)
{ {
// 1. Set value's has been shipped flag to true. // 1. Set value's has been shipped flag to true.
m_has_been_shipped = true; m_has_been_shipped = true;
@ -102,23 +102,23 @@ WebIDL::ExceptionOr<void> MessagePort::transfer_steps(HTML::TransferDataHolder&
// 1. Set remotePort's has been shipped flag to true. // 1. Set remotePort's has been shipped flag to true.
m_remote_port->m_has_been_shipped = true; m_remote_port->m_has_been_shipped = true;
// 2. Set dataHolder.[[RemotePort]] to remotePort.
// TODO: Mach IPC
auto fd = MUST(m_transport->release_underlying_transport_for_transfer()); auto fd = MUST(m_transport->release_underlying_transport_for_transfer());
m_transport.clear(); m_transport.clear();
data_holder.fds.append(IPC::File::adopt_fd(fd));
data_holder.data.append(IPC_FILE_TAG);
}
// 2. Set dataHolder.[[RemotePort]] to remotePort.
// TODO: Mach IPC
data_holder.encode(IPC_FILE_TAG);
data_holder.encode(IPC::File::adopt_fd(fd));
}
// 4. Otherwise, set dataHolder.[[RemotePort]] to null. // 4. Otherwise, set dataHolder.[[RemotePort]] to null.
else { else {
data_holder.data.append(0); data_holder.encode<u8>(0);
} }
return {}; return {};
} }
WebIDL::ExceptionOr<void> MessagePort::transfer_receiving_steps(HTML::TransferDataHolder& data_holder) WebIDL::ExceptionOr<void> MessagePort::transfer_receiving_steps(HTML::TransferDataDecoder& data_holder)
{ {
// 1. Set value's has been shipped flag to true. // 1. Set value's has been shipped flag to true.
m_has_been_shipped = true; m_has_been_shipped = true;
@ -129,10 +129,9 @@ WebIDL::ExceptionOr<void> MessagePort::transfer_receiving_steps(HTML::TransferDa
// 3. If dataHolder.[[RemotePort]] is not null, then entangle dataHolder.[[RemotePort]] and value. // 3. If dataHolder.[[RemotePort]] is not null, then entangle dataHolder.[[RemotePort]] and value.
// (This will disentangle dataHolder.[[RemotePort]] from the original port that was transferred.) // (This will disentangle dataHolder.[[RemotePort]] from the original port that was transferred.)
auto fd_tag = data_holder.data.take_first(); if (auto fd_tag = data_holder.decode<u8>(); fd_tag == IPC_FILE_TAG) {
if (fd_tag == IPC_FILE_TAG) {
// TODO: Mach IPC // TODO: Mach IPC
auto fd = data_holder.fds.take_first(); auto fd = data_holder.decode<IPC::File>();
m_transport = make<IPC::Transport>(MUST(Core::LocalSocket::adopt_fd(fd.take_fd()))); m_transport = make<IPC::Transport>(MUST(Core::LocalSocket::adopt_fd(fd.take_fd())));
m_transport->set_up_read_hook([strong_this = GC::make_root(this)]() { m_transport->set_up_read_hook([strong_this = GC::make_root(this)]() {

View file

@ -59,8 +59,8 @@ public:
GC::Ptr<WebIDL::CallbackType> onmessage(); GC::Ptr<WebIDL::CallbackType> onmessage();
// ^Transferable // ^Transferable
virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataEncoder&) override;
virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataDecoder&) override;
virtual HTML::TransferType primary_interface() const override { return m_primary_interface; } virtual HTML::TransferType primary_interface() const override { return m_primary_interface; }
void set_worker_event_target(GC::Ref<DOM::EventTarget>); void set_worker_event_target(GC::Ref<DOM::EventTarget>);

View file

@ -80,17 +80,17 @@ OffscreenCanvas::OffscreenCanvas(JS::Realm& realm, RefPtr<Gfx::Bitmap> bitmap)
OffscreenCanvas::~OffscreenCanvas() = default; OffscreenCanvas::~OffscreenCanvas() = default;
WebIDL::ExceptionOr<void> OffscreenCanvas::transfer_steps(HTML::TransferDataHolder&) WebIDL::ExceptionOr<void> OffscreenCanvas::transfer_steps(HTML::TransferDataEncoder&)
{ {
// FIXME: Implement this // FIXME: Implement this
dbgln("(STUBBED) OffscreenCanvas::transfer_steps(HTML::TransferDataHolder&)"); dbgln("(STUBBED) OffscreenCanvas::transfer_steps(HTML::TransferDataEncoder&)");
return {}; return {};
} }
WebIDL::ExceptionOr<void> OffscreenCanvas::transfer_receiving_steps(HTML::TransferDataHolder&) WebIDL::ExceptionOr<void> OffscreenCanvas::transfer_receiving_steps(HTML::TransferDataDecoder&)
{ {
// FIXME: Implement this // FIXME: Implement this
dbgln("(STUBBED) OffscreenCanvas::transfer_receiving_steps(HTML::TransferDataHolder&)"); dbgln("(STUBBED) OffscreenCanvas::transfer_receiving_steps(HTML::TransferDataDecoder&)");
return {}; return {};
} }

View file

@ -42,8 +42,8 @@ public:
virtual ~OffscreenCanvas() override; virtual ~OffscreenCanvas() override;
// ^Web::Bindings::Transferable // ^Web::Bindings::Transferable
virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataEncoder&) override;
virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataDecoder&) override;
virtual HTML::TransferType primary_interface() const override; virtual HTML::TransferType primary_interface() const override;
WebIDL::UnsignedLong width() const; WebIDL::UnsignedLong width() const;

File diff suppressed because it is too large Load diff

View file

@ -8,30 +8,66 @@
#pragma once #pragma once
#include <AK/Result.h> #include <AK/MemoryStream.h>
#include <AK/Types.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibIPC/Forward.h> #include <LibIPC/Decoder.h>
#include <LibIPC/Encoder.h>
#include <LibIPC/Message.h>
#include <LibJS/Forward.h> #include <LibJS/Forward.h>
#include <LibWeb/Forward.h> #include <LibWeb/Forward.h>
#include <LibWeb/HTML/StructuredSerializeTypes.h> #include <LibWeb/HTML/StructuredSerializeTypes.h>
#include <LibWeb/WebIDL/ExceptionOr.h> #include <LibWeb/WebIDL/ExceptionOr.h>
// Structured serialize is an entirely different format from IPC because:
// - It contains representation of type information
// - It may contain circularities
// - It is restricted to JS values
namespace Web::HTML { namespace Web::HTML {
struct TransferDataHolder { class TransferDataEncoder {
Vector<u32> data; public:
Vector<IPC::File> fds; explicit TransferDataEncoder();
explicit TransferDataEncoder(IPC::MessageBuffer&&);
template<typename T>
void encode(T const& value)
{
MUST(m_encoder.encode(value));
}
void append(SerializationRecord&&);
void extend(Vector<TransferDataEncoder>);
IPC::MessageBuffer const& buffer() const { return m_buffer; }
IPC::MessageBuffer take_buffer() { return move(m_buffer); }
private:
IPC::MessageBuffer m_buffer;
IPC::Encoder m_encoder;
};
class TransferDataDecoder {
public:
explicit TransferDataDecoder(SerializationRecord const&);
explicit TransferDataDecoder(TransferDataEncoder&&);
template<typename T>
T decode()
{
static_assert(!IsSame<T, ByteBuffer>, "Use decode_buffer to handle OOM");
return MUST(m_decoder.decode<T>());
}
WebIDL::ExceptionOr<ByteBuffer> decode_buffer(JS::Realm&);
private:
IPC::MessageBuffer m_buffer;
FixedMemoryStream m_stream;
Queue<IPC::File> m_files;
IPC::Decoder m_decoder;
}; };
struct SerializedTransferRecord { struct SerializedTransferRecord {
SerializationRecord serialized; SerializationRecord serialized;
Vector<TransferDataHolder> transfer_data_holders; Vector<TransferDataEncoder> transfer_data_holders;
}; };
struct DeserializedTransferRecord { struct DeserializedTransferRecord {
@ -39,100 +75,31 @@ struct DeserializedTransferRecord {
Vector<GC::Root<JS::Object>> transferred_values; Vector<GC::Root<JS::Object>> transferred_values;
}; };
struct DeserializedRecord { WebIDL::ExceptionOr<SerializationRecord> structured_serialize(JS::VM&, JS::Value);
Optional<JS::Value> value; WebIDL::ExceptionOr<SerializationRecord> structured_serialize_for_storage(JS::VM&, JS::Value);
size_t position; WebIDL::ExceptionOr<SerializationRecord> structured_serialize_internal(JS::VM&, JS::Value, bool for_storage, SerializationMemory&);
};
WebIDL::ExceptionOr<SerializationRecord> structured_serialize(JS::VM& vm, JS::Value); WebIDL::ExceptionOr<JS::Value> structured_deserialize(JS::VM&, SerializationRecord const&, JS::Realm&, Optional<DeserializationMemory> = {});
WebIDL::ExceptionOr<SerializationRecord> structured_serialize_for_storage(JS::VM& vm, JS::Value); WebIDL::ExceptionOr<JS::Value> structured_deserialize_internal(JS::VM&, TransferDataDecoder&, JS::Realm&, DeserializationMemory&);
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<SerializedTransferRecord> structured_serialize_with_transfer(JS::VM&, JS::Value, Vector<GC::Root<JS::Object>> const& transfer_list);
WebIDL::ExceptionOr<DeserializedRecord> structured_deserialize_internal(JS::VM& vm, ReadonlySpan<u32> const& serialized, JS::Realm& target_realm, DeserializationMemory& memory, Optional<size_t> position = {}); WebIDL::ExceptionOr<DeserializedTransferRecord> structured_deserialize_with_transfer(SerializedTransferRecord&, JS::Realm&);
WebIDL::ExceptionOr<JS::Value> structured_deserialize_with_transfer_internal(TransferDataDecoder&, JS::Realm&);
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);
template<typename T>
requires(IsIntegral<T> || IsFloatingPoint<T>)
void serialize_primitive_type(SerializationRecord& serialized, T value)
{
if constexpr (sizeof(T) < sizeof(u32)) {
// NOTE: If the value is smaller than a u32, we can just store it directly.
serialized.append(static_cast<u32>(value));
return;
}
serialized.append(bit_cast<u32*>(&value), sizeof(T) / 4);
}
template<typename T>
requires(IsEnum<T>)
void serialize_enum(SerializationRecord& serialized, T value)
{
serialize_primitive_type<UnderlyingType<T>>(serialized, to_underlying(value));
}
WebIDL::ExceptionOr<void> serialize_bytes(JS::VM& vm, Vector<u32>& vector, ReadonlyBytes bytes);
WebIDL::ExceptionOr<void> serialize_string(JS::VM& vm, Vector<u32>& vector, StringView);
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, JS::PrimitiveString const& primitive_string);
WebIDL::ExceptionOr<void> serialize_array_buffer(JS::VM& vm, Vector<u32>& vector, JS::ArrayBuffer const& array_buffer, bool for_storage);
template<OneOf<JS::TypedArrayBase, JS::DataView> ViewType>
WebIDL::ExceptionOr<void> serialize_viewed_array_buffer(JS::VM& vm, Vector<u32>& vector, ViewType const& view, bool for_storage, SerializationMemory& memory);
bool deserialize_boolean_primitive(ReadonlySpan<u32> const& serialized, size_t& position);
double deserialize_number_primitive(ReadonlySpan<u32> const& serialized, size_t& position);
GC::Ref<JS::BooleanObject> deserialize_boolean_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
GC::Ref<JS::NumberObject> deserialize_number_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
WebIDL::ExceptionOr<GC::Ref<JS::BigIntObject>> deserialize_big_int_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
WebIDL::ExceptionOr<GC::Ref<JS::StringObject>> deserialize_string_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
GC::Ref<JS::Date> deserialize_date_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
WebIDL::ExceptionOr<GC::Ref<JS::RegExpObject>> deserialize_reg_exp_object(JS::Realm& realm, ReadonlySpan<u32> const& serialized, size_t& position);
template<typename T>
requires(IsIntegral<T> || IsFloatingPoint<T> || IsEnum<T>)
T deserialize_primitive_type(ReadonlySpan<u32> const& serialized, size_t& position)
{
T value;
// NOTE: Make sure we always round up, otherwise Ts that are less than 32 bit will end up with a size of 0.
auto size = 1 + ((sizeof(value) - 1) / 4);
VERIFY(position + size <= serialized.size());
memcpy(&value, serialized.offset_pointer(position), sizeof(value));
position += size;
return value;
}
WebIDL::ExceptionOr<ByteBuffer> deserialize_bytes(JS::VM& vm, ReadonlySpan<u32> vector, size_t& position);
WebIDL::ExceptionOr<String> deserialize_string(JS::VM& vm, ReadonlySpan<u32> vector, size_t& position);
WebIDL::ExceptionOr<GC::Ref<JS::PrimitiveString>> deserialize_string_primitive(JS::VM& vm, ReadonlySpan<u32> vector, size_t& position);
WebIDL::ExceptionOr<GC::Ref<JS::BigInt>> deserialize_big_int_primitive(JS::VM& vm, ReadonlySpan<u32> vector, size_t& position);
WebIDL::ExceptionOr<SerializedTransferRecord> structured_serialize_with_transfer(JS::VM& vm, JS::Value value, Vector<GC::Root<JS::Object>> const& transfer_list);
WebIDL::ExceptionOr<DeserializedTransferRecord> structured_deserialize_with_transfer(SerializedTransferRecord&, JS::Realm& target_realm);
} }
namespace IPC { namespace IPC {
template<> template<>
ErrorOr<void> encode(Encoder&, ::Web::HTML::SerializedTransferRecord const&); ErrorOr<void> encode(Encoder&, Web::HTML::TransferDataEncoder const&);
template<> template<>
ErrorOr<void> encode(Encoder&, ::Web::HTML::TransferDataHolder const&); ErrorOr<Web::HTML::TransferDataEncoder> decode(Decoder&);
template<> template<>
ErrorOr<::Web::HTML::SerializedTransferRecord> decode(Decoder&); ErrorOr<void> encode(Encoder&, Web::HTML::SerializedTransferRecord const&);
template<> template<>
ErrorOr<::Web::HTML::TransferDataHolder> decode(Decoder&); ErrorOr<Web::HTML::SerializedTransferRecord> decode(Decoder&);
} }

View file

@ -9,13 +9,14 @@
#include <AK/HashMap.h> #include <AK/HashMap.h>
#include <AK/Vector.h> #include <AK/Vector.h>
#include <LibGC/Forward.h> #include <LibGC/Forward.h>
#include <LibIPC/Forward.h>
#include <LibJS/Forward.h> #include <LibJS/Forward.h>
namespace Web::HTML { namespace Web::HTML {
using DeserializationMemory = GC::RootVector<JS::Value>; using DeserializationMemory = GC::RootVector<JS::Value>;
using SerializationRecord = Vector<u32>;
using SerializationMemory = HashMap<GC::Root<JS::Value>, u32>; using SerializationMemory = HashMap<GC::Root<JS::Value>, u32>;
using SerializationRecord = IPC::MessageDataType;
enum class SerializeType : u8 { enum class SerializeType : u8 {
Unknown = 0, Unknown = 0,

View file

@ -30,7 +30,7 @@ void WorkerAgentParent::initialize(JS::Realm& realm)
m_message_port = MessagePort::create(realm); m_message_port = MessagePort::create(realm);
m_message_port->entangle_with(*m_outside_port); m_message_port->entangle_with(*m_outside_port);
TransferDataHolder data_holder; TransferDataEncoder data_holder;
MUST(m_message_port->transfer_steps(data_holder)); MUST(m_message_port->transfer_steps(data_holder));
// FIXME: Specification says this supposed to happen in step 11 of onComplete handler defined in https://html.spec.whatwg.org/multipage/workers.html#run-a-worker // FIXME: Specification says this supposed to happen in step 11 of onComplete handler defined in https://html.spec.whatwg.org/multipage/workers.html#run-a-worker

View file

@ -457,7 +457,7 @@ GC::Ref<ReadableStream> ReadableStream::piped_through(GC::Ref<TransformStream> t
} }
// https://streams.spec.whatwg.org/#ref-for-transfer-steps // https://streams.spec.whatwg.org/#ref-for-transfer-steps
WebIDL::ExceptionOr<void> ReadableStream::transfer_steps(HTML::TransferDataHolder& data_holder) WebIDL::ExceptionOr<void> ReadableStream::transfer_steps(HTML::TransferDataEncoder& data_holder)
{ {
auto& realm = this->realm(); auto& realm = this->realm();
auto& vm = realm.vm(); auto& vm = realm.vm();
@ -472,7 +472,7 @@ WebIDL::ExceptionOr<void> ReadableStream::transfer_steps(HTML::TransferDataHolde
auto port1 = HTML::MessagePort::create(realm); auto port1 = HTML::MessagePort::create(realm);
// 3. Let port2 be a new MessagePort in the current Realm. // 3. Let port2 be a new MessagePort in the current Realm.
auto port2 = HTML::MessagePort::create(realm, HTML::TransferType::ReadableStream); auto port2 = HTML::MessagePort::create(realm);
// 4. Entangle port1 and port2. // 4. Entangle port1 and port2.
port1->entangle_with(port2); port1->entangle_with(port2);
@ -491,22 +491,23 @@ WebIDL::ExceptionOr<void> ReadableStream::transfer_steps(HTML::TransferDataHolde
// 9. Set dataHolder.[[port]] to ! StructuredSerializeWithTransfer(port2, « port2 »). // 9. Set dataHolder.[[port]] to ! StructuredSerializeWithTransfer(port2, « port2 »).
auto result = MUST(HTML::structured_serialize_with_transfer(vm, port2, { { GC::Root { port2 } } })); auto result = MUST(HTML::structured_serialize_with_transfer(vm, port2, { { GC::Root { port2 } } }));
data_holder = move(result.transfer_data_holders.first()); data_holder.extend(move(result.transfer_data_holders));
return {}; return {};
} }
// https://streams.spec.whatwg.org/#ref-for-transfer-receiving-steps // https://streams.spec.whatwg.org/#ref-for-transfer-receiving-steps
WebIDL::ExceptionOr<void> ReadableStream::transfer_receiving_steps(HTML::TransferDataHolder& data_holder) WebIDL::ExceptionOr<void> ReadableStream::transfer_receiving_steps(HTML::TransferDataDecoder& data_holder)
{ {
auto& realm = this->realm(); auto& realm = this->realm();
HTML::TemporaryExecutionContext execution_context { realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; HTML::TemporaryExecutionContext execution_context { realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
// 1. Let deserializedRecord be ! StructuredDeserializeWithTransfer(dataHolder.[[port]], the current Realm). // 1. Let deserializedRecord be ! StructuredDeserializeWithTransfer(dataHolder.[[port]], the current Realm).
auto deserialized_record = MUST(HTML::structured_deserialize_with_transfer_internal(data_holder, realm));
// 2. Let port be deserializedRecord.[[Deserialized]]. // 2. Let port be deserializedRecord.[[Deserialized]].
auto port = HTML::MessagePort::create(realm); auto& port = as<HTML::MessagePort>(deserialized_record.as_object());
TRY(port->transfer_receiving_steps(data_holder));
// 3. Perform ! SetUpCrossRealmTransformReadable(value, port). // 3. Perform ! SetUpCrossRealmTransformReadable(value, port).
set_up_cross_realm_transform_readable(realm, *this, port); set_up_cross_realm_transform_readable(realm, *this, port);

View file

@ -117,8 +117,8 @@ public:
GC::Ptr<WebIDL::ArrayBufferView> current_byob_request_view(); GC::Ptr<WebIDL::ArrayBufferView> current_byob_request_view();
// ^Transferable // ^Transferable
virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataEncoder&) override;
virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataDecoder&) override;
virtual HTML::TransferType primary_interface() const override { return HTML::TransferType::ReadableStream; } virtual HTML::TransferType primary_interface() const override { return HTML::TransferType::ReadableStream; }
private: private:

View file

@ -188,18 +188,11 @@ void TransformStream::set_up(GC::Ref<TransformAlgorithm> transform_algorithm, GC
} }
// https://streams.spec.whatwg.org/#ref-for-transfer-steps② // https://streams.spec.whatwg.org/#ref-for-transfer-steps②
WebIDL::ExceptionOr<void> TransformStream::transfer_steps(HTML::TransferDataHolder& data_holder) WebIDL::ExceptionOr<void> TransformStream::transfer_steps(HTML::TransferDataEncoder& data_holder)
{ {
auto& realm = this->realm(); auto& realm = this->realm();
auto& vm = realm.vm(); auto& vm = realm.vm();
auto serialize_stream = [&](auto stream) {
auto result = MUST(HTML::structured_serialize_with_transfer(vm, stream, { { GC::Root { stream } } }));
data_holder.data.extend(move(result.transfer_data_holders.first().data));
data_holder.fds.extend(move(result.transfer_data_holders.first().fds));
};
// 1. Let readable be value.[[readable]]. // 1. Let readable be value.[[readable]].
auto readable = this->readable(); auto readable = this->readable();
@ -215,48 +208,32 @@ WebIDL::ExceptionOr<void> TransformStream::transfer_steps(HTML::TransferDataHold
return WebIDL::DataCloneError::create(realm, "Cannot transfer locked WritableStream"_string); return WebIDL::DataCloneError::create(realm, "Cannot transfer locked WritableStream"_string);
// 5. Set dataHolder.[[readable]] to ! StructuredSerializeWithTransfer(readable, « readable »). // 5. Set dataHolder.[[readable]] to ! StructuredSerializeWithTransfer(readable, « readable »).
serialize_stream(readable); auto readable_result = MUST(HTML::structured_serialize_with_transfer(vm, readable, { { GC::Root { readable } } }));
data_holder.extend(move(readable_result.transfer_data_holders));
// 6. Set dataHolder.[[writable]] to ! StructuredSerializeWithTransfer(writable, « writable »). // 6. Set dataHolder.[[writable]] to ! StructuredSerializeWithTransfer(writable, « writable »).
serialize_stream(writable); auto writable_result = MUST(HTML::structured_serialize_with_transfer(vm, writable, { { GC::Root { writable } } }));
data_holder.extend(move(writable_result.transfer_data_holders));
return {}; return {};
} }
template<typename StreamType>
static WebIDL::ExceptionOr<GC::Ref<StreamType>> deserialize_stream(JS::Realm& realm, HTML::TransferDataHolder& data_holder)
{
auto transfer_type = data_holder.data.take_first();
if constexpr (IsSame<StreamType, ReadableStream>)
VERIFY(transfer_type == to_underlying(HTML::TransferType::ReadableStream));
else if constexpr (IsSame<StreamType, WritableStream>)
VERIFY(transfer_type == to_underlying(HTML::TransferType::WritableStream));
else
static_assert(DependentFalse<StreamType>);
auto stream = realm.create<StreamType>(realm);
TRY(stream->transfer_receiving_steps(data_holder));
return stream;
}
// https://streams.spec.whatwg.org/#ref-for-transfer-receiving-steps② // https://streams.spec.whatwg.org/#ref-for-transfer-receiving-steps②
WebIDL::ExceptionOr<void> TransformStream::transfer_receiving_steps(HTML::TransferDataHolder& data_holder) WebIDL::ExceptionOr<void> TransformStream::transfer_receiving_steps(HTML::TransferDataDecoder& data_holder)
{ {
auto& realm = this->realm(); auto& realm = this->realm();
// 1. Let readableRecord be ! StructuredDeserializeWithTransfer(dataHolder.[[readable]], the current Realm). // 1. Let readableRecord be ! StructuredDeserializeWithTransfer(dataHolder.[[readable]], the current Realm).
auto readable = TRY(deserialize_stream<ReadableStream>(realm, data_holder)); auto readable_record = MUST(HTML::structured_deserialize_with_transfer_internal(data_holder, realm));
// 2. Let writableRecord be ! StructuredDeserializeWithTransfer(dataHolder.[[writable]], the current Realm). // 2. Let writableRecord be ! StructuredDeserializeWithTransfer(dataHolder.[[writable]], the current Realm).
auto writable = TRY(deserialize_stream<WritableStream>(realm, data_holder)); auto writeable_record = MUST(HTML::structured_deserialize_with_transfer_internal(data_holder, realm));
// 3. Set value.[[readable]] to readableRecord.[[Deserialized]]. // 3. Set value.[[readable]] to readableRecord.[[Deserialized]].
set_readable(readable); set_readable(as<ReadableStream>(readable_record.as_object()));
// 4. Set value.[[writable]] to writableRecord.[[Deserialized]]. // 4. Set value.[[writable]] to writableRecord.[[Deserialized]].
set_writable(writable); set_writable(as<WritableStream>(writeable_record.as_object()));
// 5. Set value.[[backpressure]], value.[[backpressureChangePromise]], and value.[[controller]] to undefined. // 5. Set value.[[backpressure]], value.[[backpressureChangePromise]], and value.[[controller]] to undefined.
set_backpressure({}); set_backpressure({});

View file

@ -48,8 +48,8 @@ public:
void enqueue(JS::Value chunk); void enqueue(JS::Value chunk);
// ^Transferable // ^Transferable
virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataEncoder&) override;
virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataDecoder&) override;
virtual HTML::TransferType primary_interface() const override { return HTML::TransferType::TransformStream; } virtual HTML::TransferType primary_interface() const override { return HTML::TransferType::TransformStream; }
private: private:

View file

@ -135,7 +135,7 @@ WebIDL::ExceptionOr<GC::Ref<WritableStreamDefaultWriter>> WritableStream::get_wr
} }
// https://streams.spec.whatwg.org/#ref-for-transfer-steps① // https://streams.spec.whatwg.org/#ref-for-transfer-steps①
WebIDL::ExceptionOr<void> WritableStream::transfer_steps(HTML::TransferDataHolder& data_holder) WebIDL::ExceptionOr<void> WritableStream::transfer_steps(HTML::TransferDataEncoder& data_holder)
{ {
auto& realm = this->realm(); auto& realm = this->realm();
auto& vm = realm.vm(); auto& vm = realm.vm();
@ -150,7 +150,7 @@ WebIDL::ExceptionOr<void> WritableStream::transfer_steps(HTML::TransferDataHolde
auto port1 = HTML::MessagePort::create(realm); auto port1 = HTML::MessagePort::create(realm);
// 3. Let port2 be a new MessagePort in the current Realm. // 3. Let port2 be a new MessagePort in the current Realm.
auto port2 = HTML::MessagePort::create(realm, HTML::TransferType::WritableStream); auto port2 = HTML::MessagePort::create(realm);
// 4. Entangle port1 and port2. // 4. Entangle port1 and port2.
port1->entangle_with(port2); port1->entangle_with(port2);
@ -169,22 +169,23 @@ WebIDL::ExceptionOr<void> WritableStream::transfer_steps(HTML::TransferDataHolde
// 9. Set dataHolder.[[port]] to ! StructuredSerializeWithTransfer(port2, « port2 »). // 9. Set dataHolder.[[port]] to ! StructuredSerializeWithTransfer(port2, « port2 »).
auto result = MUST(HTML::structured_serialize_with_transfer(vm, port2, { { GC::Root { port2 } } })); auto result = MUST(HTML::structured_serialize_with_transfer(vm, port2, { { GC::Root { port2 } } }));
data_holder = move(result.transfer_data_holders.first()); data_holder.extend(move(result.transfer_data_holders));
return {}; return {};
} }
// https://streams.spec.whatwg.org/#ref-for-transfer-receiving-steps① // https://streams.spec.whatwg.org/#ref-for-transfer-receiving-steps①
WebIDL::ExceptionOr<void> WritableStream::transfer_receiving_steps(HTML::TransferDataHolder& data_holder) WebIDL::ExceptionOr<void> WritableStream::transfer_receiving_steps(HTML::TransferDataDecoder& data_holder)
{ {
auto& realm = this->realm(); auto& realm = this->realm();
HTML::TemporaryExecutionContext execution_context { realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; HTML::TemporaryExecutionContext execution_context { realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
// 1. Let deserializedRecord be ! StructuredDeserializeWithTransfer(dataHolder.[[port]], the current Realm). // 1. Let deserializedRecord be ! StructuredDeserializeWithTransfer(dataHolder.[[port]], the current Realm).
auto deserialized_record = MUST(HTML::structured_deserialize_with_transfer_internal(data_holder, realm));
// 2. Let port be deserializedRecord.[[Deserialized]]. // 2. Let port be deserializedRecord.[[Deserialized]].
auto port = HTML::MessagePort::create(realm); auto& port = as<HTML::MessagePort>(deserialized_record.as_object());
TRY(port->transfer_receiving_steps(data_holder));
// 3. Perform ! SetUpCrossRealmTransformWritable(value, port). // 3. Perform ! SetUpCrossRealmTransformWritable(value, port).
set_up_cross_realm_transform_writable(realm, *this, port); set_up_cross_realm_transform_writable(realm, *this, port);

View file

@ -89,8 +89,8 @@ public:
SinglyLinkedList<GC::Ref<WebIDL::Promise>>& write_requests() { return m_write_requests; } SinglyLinkedList<GC::Ref<WebIDL::Promise>>& write_requests() { return m_write_requests; }
// ^Transferable // ^Transferable
virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_steps(HTML::TransferDataEncoder&) override;
virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataHolder&) override; virtual WebIDL::ExceptionOr<void> transfer_receiving_steps(HTML::TransferDataDecoder&) override;
virtual HTML::TransferType primary_interface() const override { return HTML::TransferType::WritableStream; } virtual HTML::TransferType primary_interface() const override { return HTML::TransferType::WritableStream; }
private: private:

View file

@ -48,30 +48,26 @@ void DOMException::initialize(JS::Realm& realm)
Base::initialize(realm); Base::initialize(realm);
} }
ExceptionOr<void> DOMException::serialization_steps(HTML::SerializationRecord& record, bool, HTML::SerializationMemory&) WebIDL::ExceptionOr<void> DOMException::serialization_steps(HTML::TransferDataEncoder& serialized, bool, HTML::SerializationMemory&)
{ {
auto& vm = this->vm();
// 1. Set serialized.[[Name]] to values name. // 1. Set serialized.[[Name]] to values name.
TRY(HTML::serialize_string(vm, record, m_name.to_string())); serialized.encode(m_name.to_string());
// 2. Set serialized.[[Message]] to values message. // 2. Set serialized.[[Message]] to values message.
TRY(HTML::serialize_string(vm, record, m_message.to_string())); serialized.encode(m_message.to_string());
// FIXME: 3. User agents should attach a serialized representation of any interesting accompanying data which are not yet specified, notably the stack property, to serialized. // FIXME: 3. User agents should attach a serialized representation of any interesting accompanying data which are not yet specified, notably the stack property, to serialized.
return {}; return {};
} }
ExceptionOr<void> DOMException::deserialization_steps(ReadonlySpan<u32> const& record, size_t& position, HTML::DeserializationMemory&) WebIDL::ExceptionOr<void> DOMException::deserialization_steps(HTML::TransferDataDecoder& serialized, HTML::DeserializationMemory&)
{ {
auto& vm = this->vm();
// 1. Set values name to serialized.[[Name]]. // 1. Set values name to serialized.[[Name]].
m_name = TRY(HTML::deserialize_string(vm, record, position)); m_name = serialized.decode<String>();
// 2. Set values message to serialized.[[Message]]. // 2. Set values message to serialized.[[Message]].
m_message = TRY(HTML::deserialize_string(vm, record, position)); m_message = serialized.decode<String>();
// FIXME: 3. If any other data is attached to serialized, then deserialize and attach it to value. // FIXME: 3. If any other data is attached to serialized, then deserialize and attach it to value.

View file

@ -113,8 +113,8 @@ public:
virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::DOMException; } virtual HTML::SerializeType serialize_type() const override { return HTML::SerializeType::DOMException; }
virtual ExceptionOr<void> serialization_steps(HTML::SerializationRecord& record, bool for_storage, HTML::SerializationMemory&) override; virtual WebIDL::ExceptionOr<void> serialization_steps(HTML::TransferDataEncoder&, bool for_storage, HTML::SerializationMemory&) override;
virtual ExceptionOr<void> deserialization_steps(ReadonlySpan<u32> const& record, size_t& position, HTML::DeserializationMemory&) override; virtual WebIDL::ExceptionOr<void> deserialization_steps(HTML::TransferDataDecoder&, HTML::DeserializationMemory&) override;
protected: protected:
DOMException(JS::Realm&, FlyString name, String message); DOMException(JS::Realm&, FlyString name, String message);

View file

@ -11,7 +11,7 @@ endpoint WebWorkerServer {
Web::Bindings::WorkerType type, Web::Bindings::WorkerType type,
Web::Bindings::RequestCredentials credentials, Web::Bindings::RequestCredentials credentials,
String name, String name,
Web::HTML::TransferDataHolder message_port, Web::HTML::TransferDataEncoder message_port,
Web::HTML::SerializedEnvironmentSettingsObject outside_settings, Web::HTML::SerializedEnvironmentSettingsObject outside_settings,
Web::Bindings::AgentType agent_type) =| Web::Bindings::AgentType agent_type) =|

View file

@ -63,7 +63,7 @@ Web::Page const& ConnectionFromClient::page() const
return m_page_host->page(); return m_page_host->page();
} }
void ConnectionFromClient::start_worker(URL::URL url, Web::Bindings::WorkerType type, Web::Bindings::RequestCredentials credentials, String name, Web::HTML::TransferDataHolder implicit_port, Web::HTML::SerializedEnvironmentSettingsObject outside_settings, Web::Bindings::AgentType agent_type) void ConnectionFromClient::start_worker(URL::URL url, Web::Bindings::WorkerType type, Web::Bindings::RequestCredentials credentials, String name, Web::HTML::TransferDataEncoder implicit_port, Web::HTML::SerializedEnvironmentSettingsObject outside_settings, Web::Bindings::AgentType agent_type)
{ {
m_worker_host = make_ref_counted<WorkerHost>(move(url), type, move(name)); m_worker_host = make_ref_counted<WorkerHost>(move(url), type, move(name));

View file

@ -41,7 +41,7 @@ private:
Web::Page& page(); Web::Page& page();
Web::Page const& page() const; Web::Page const& page() const;
virtual void start_worker(URL::URL url, Web::Bindings::WorkerType type, Web::Bindings::RequestCredentials credentials, String name, Web::HTML::TransferDataHolder, Web::HTML::SerializedEnvironmentSettingsObject, Web::Bindings::AgentType) override; virtual void start_worker(URL::URL url, Web::Bindings::WorkerType type, Web::Bindings::RequestCredentials credentials, String name, Web::HTML::TransferDataEncoder, Web::HTML::SerializedEnvironmentSettingsObject, Web::Bindings::AgentType) override;
virtual void handle_file_return(i32 error, Optional<IPC::File> file, i32 request_id) override; virtual void handle_file_return(i32 error, Optional<IPC::File> file, i32 request_id) override;
GC::Root<PageHost> m_page_host; GC::Root<PageHost> m_page_host;

View file

@ -36,7 +36,7 @@ WorkerHost::WorkerHost(URL::URL url, Web::Bindings::WorkerType type, String name
WorkerHost::~WorkerHost() = default; WorkerHost::~WorkerHost() = default;
// https://html.spec.whatwg.org/multipage/workers.html#run-a-worker // https://html.spec.whatwg.org/multipage/workers.html#run-a-worker
void WorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataHolder message_port_data, Web::HTML::SerializedEnvironmentSettingsObject const& outside_settings_snapshot, Web::Bindings::RequestCredentials credentials, bool is_shared) void WorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataEncoder message_port_data, Web::HTML::SerializedEnvironmentSettingsObject const& outside_settings_snapshot, Web::Bindings::RequestCredentials credentials, bool is_shared)
{ {
// 3. Let unsafeWorkerCreationTime be the unsafe shared current time. // 3. Let unsafeWorkerCreationTime be the unsafe shared current time.
auto unsafe_worker_creation_time = Web::HighResolutionTime::unsafe_shared_current_time(); auto unsafe_worker_creation_time = Web::HighResolutionTime::unsafe_shared_current_time();
@ -157,6 +157,7 @@ void WorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataHolder mess
auto on_complete_function = [inside_settings, worker_global_scope, message_port_data = move(message_port_data), url = m_url, is_shared](GC::Ptr<Web::HTML::Script> script) mutable { auto on_complete_function = [inside_settings, worker_global_scope, message_port_data = move(message_port_data), url = m_url, is_shared](GC::Ptr<Web::HTML::Script> script) mutable {
auto& realm = inside_settings->realm(); auto& realm = inside_settings->realm();
// 1. If script is null or if script's error to rethrow is non-null, then: // 1. If script is null or if script's error to rethrow is non-null, then:
if (!script || !script->error_to_rethrow().is_null()) { if (!script || !script->error_to_rethrow().is_null()) {
// FIXME: 1. Queue a global task on the DOM manipulation task source given worker's relevant global object to fire an event named error at worker. // FIXME: 1. Queue a global task on the DOM manipulation task source given worker's relevant global object to fire an event named error at worker.
@ -180,7 +181,8 @@ void WorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataHolder mess
worker_global_scope->set_internal_port(inside_port); worker_global_scope->set_internal_port(inside_port);
// 5. Entangle outside port and inside port. // 5. Entangle outside port and inside port.
MUST(inside_port->transfer_receiving_steps(message_port_data)); Web::HTML::TransferDataDecoder decoder { move(message_port_data) };
MUST(inside_port->transfer_receiving_steps(decoder));
// 6. Create a new WorkerLocation object and associate it with worker global scope. // 6. Create a new WorkerLocation object and associate it with worker global scope.
worker_global_scope->set_location(realm.create<Web::HTML::WorkerLocation>(*worker_global_scope)); worker_global_scope->set_location(realm.create<Web::HTML::WorkerLocation>(*worker_global_scope));

View file

@ -21,7 +21,7 @@ public:
explicit WorkerHost(URL::URL url, Web::Bindings::WorkerType type, String name); explicit WorkerHost(URL::URL url, Web::Bindings::WorkerType type, String name);
~WorkerHost(); ~WorkerHost();
void run(GC::Ref<Web::Page>, Web::HTML::TransferDataHolder message_port_data, Web::HTML::SerializedEnvironmentSettingsObject const&, Web::Bindings::RequestCredentials, bool is_shared); void run(GC::Ref<Web::Page>, Web::HTML::TransferDataEncoder message_port_data, Web::HTML::SerializedEnvironmentSettingsObject const&, Web::Bindings::RequestCredentials, bool is_shared);
private: private:
GC::Root<Web::HTML::WorkerDebugConsoleClient> m_console; GC::Root<Web::HTML::WorkerDebugConsoleClient> m_console;