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

@ -702,82 +702,85 @@ WebIDL::ExceptionOr<String> DOMMatrixReadOnly::to_string() const
}
// 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:
if (m_is_2d) {
// 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.
HTML::serialize_primitive_type(serialized, this->m12());
serialized.encode(m12());
// 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.
HTML::serialize_primitive_type(serialized, this->m22());
serialized.encode(m22());
// 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.
HTML::serialize_primitive_type(serialized, this->m42());
serialized.encode(m42());
// 7. Set serialized.[[Is2D]] to true.
// NOTE: This is set in the beginning of the function.
}
// 2. Otherwise:
else {
// 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.
HTML::serialize_primitive_type(serialized, this->m12());
serialized.encode(m12());
// 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.
HTML::serialize_primitive_type(serialized, this->m14());
serialized.encode(m14());
// 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.
HTML::serialize_primitive_type(serialized, this->m22());
serialized.encode(m22());
// 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.
HTML::serialize_primitive_type(serialized, this->m24());
serialized.encode(m24());
// 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.
HTML::serialize_primitive_type(serialized, this->m32());
serialized.encode(m32());
// 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.
HTML::serialize_primitive_type(serialized, this->m34());
serialized.encode(m34());
// 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.
HTML::serialize_primitive_type(serialized, this->m42());
serialized.encode(m42());
// 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.
HTML::serialize_primitive_type(serialized, this->m44());
serialized.encode(m44());
// 17. Set serialized.[[Is2D]] to false.
// NOTE: This is set in the beginning of the function.
}
return {};
}
// 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:
if (is_2d) {
// 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]].
double m12 = HTML::deserialize_primitive_type<double>(record, position);
auto m12 = serialized.decode<double>();
// 3. Set values m13 element to 0.
// 4. Set values m14 element to 0.
// 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]].
double m22 = HTML::deserialize_primitive_type<double>(record, position);
auto m22 = serialized.decode<double>();
// 7. Set values m23 element to 0.
// 8. Set values m24 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.
// 12. Set values m34 element to 0.
// 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]].
double m42 = HTML::deserialize_primitive_type<double>(record, position);
auto m42 = serialized.decode<double>();
// 15. Set values m43 element to 0.
// 16. Set values m44 element to 1.
// 17. Set values is 2D to true.
@ -797,41 +800,42 @@ WebIDL::ExceptionOr<void> DOMMatrixReadOnly::deserialization_steps(ReadonlySpan<
// 2. Otherwise:
else {
// 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]].
double m12 = HTML::deserialize_primitive_type<double>(record, position);
auto m12 = serialized.decode<double>();
// 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]].
double m14 = HTML::deserialize_primitive_type<double>(record, position);
auto m14 = serialized.decode<double>();
// 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]].
double m22 = HTML::deserialize_primitive_type<double>(record, position);
auto m22 = serialized.decode<double>();
// 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]].
double m24 = HTML::deserialize_primitive_type<double>(record, position);
auto m24 = serialized.decode<double>();
// 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]].
double m32 = HTML::deserialize_primitive_type<double>(record, position);
auto m32 = serialized.decode<double>();
// 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]].
double m34 = HTML::deserialize_primitive_type<double>(record, position);
auto m34 = serialized.decode<double>();
// 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]].
double m42 = HTML::deserialize_primitive_type<double>(record, position);
auto m42 = serialized.decode<double>();
// 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]].
double m44 = HTML::deserialize_primitive_type<double>(record, position);
auto m44 = serialized.decode<double>();
// 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);
}
return {};
}