Forráskód Böngészése

LibWeb: Implement StructuredSerialize for BigIntObject and Symbol

Andrew Kaster 1 éve
szülő
commit
b3bd232a5e

+ 2 - 0
Tests/LibWeb/Text/expected/HTML/StructuredClone-object-primitives.txt

@@ -3,4 +3,6 @@ false
 123
 123.456
 This is a String object
+9007199254740991
 1692748800000
+ERROR: DataCloneError: Cannot serialize Symbol

+ 9 - 0
Tests/LibWeb/Text/input/HTML/StructuredClone-object-primitives.html

@@ -6,6 +6,15 @@
         println(structuredClone(new Number(123)));
         println(structuredClone(new Number(123.456)));
         println(structuredClone(new String("This is a String object")));
+        println(structuredClone(BigInt("0x1fffffffffffff")));
         println(structuredClone(Date.UTC(2023, 7, 23)));
+
+        try {
+            structuredClone(Symbol("foo"));
+            println("FAILED")
+        }
+        catch(e) {
+            println("ERROR: " + e.name + ": " + e.message)
+        }
     });
 </script>

+ 18 - 2
Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp

@@ -11,6 +11,7 @@
 #include <AK/Vector.h>
 #include <LibJS/Forward.h>
 #include <LibJS/Runtime/BigInt.h>
+#include <LibJS/Runtime/BigIntObject.h>
 #include <LibJS/Runtime/BooleanObject.h>
 #include <LibJS/Runtime/Date.h>
 #include <LibJS/Runtime/NumberObject.h>
@@ -60,6 +61,8 @@ enum ValueTag {
 
     NumberObject,
 
+    BigIntObject,
+
     StringObject,
 
     DateObject,
@@ -122,7 +125,9 @@ public:
         if (return_primitive_type)
             return m_serialized;
 
-        // FIXME 5. If Type(value) is Symbol, then throw a "DataCloneError" DOMException.
+        // 5. If Type(value) is Symbol, then throw a "DataCloneError" DOMException.
+        if (value.is_symbol())
+            return WebIDL::DataCloneError::create(*m_vm.current_realm(), "Cannot serialize Symbol"sv);
 
         // 6. Let serialized be an uninitialized value.
         //    NOTE: We use the range of the soon-to-be-serialized value in our serialized data buffer
@@ -144,7 +149,12 @@ public:
             m_serialized.append(bit_cast<u32*>(&number), 2);
         }
 
-        // FIXME 9. Otherwise, if value has a [[BigIntData]] internal slot, then set serialized to { [[Type]]: "BigInt", [[BigIntData]]: value.[[BigIntData]] }.
+        // 9. Otherwise, if value has a [[BigIntData]] internal slot, then set serialized to { [[Type]]: "BigInt", [[BigIntData]]: value.[[BigIntData]] }.
+        else if (value.is_object() && is<JS::BigIntObject>(value.as_object())) {
+            m_serialized.append(ValueTag::BigIntObject);
+            auto& bigint_object = static_cast<JS::BigIntObject&>(value.as_object());
+            TRY(serialize_string(m_serialized, TRY_OR_THROW_OOM(m_vm, bigint_object.bigint().to_string())));
+        }
 
         // 10. Otherwise, if value has a [[StringData]] internal slot, then set serialized to { [[Type]]: "String", [[StringData]]: value.[[StringData]] }.
         else if (value.is_object() && is<JS::StringObject>(value.as_object())) {
@@ -270,6 +280,12 @@ public:
                 m_memory.append(JS::NumberObject::create(*realm, value));
                 break;
             }
+            case ValueTag::BigIntObject: {
+                auto* realm = m_vm.current_realm();
+                auto big_int = TRY(deserialize_big_int_primitive(m_vm, m_vector, position));
+                m_memory.append(JS::BigIntObject::create(*realm, big_int));
+                break;
+            }
             case ValueTag::StringObject: {
                 auto* realm = m_vm.current_realm();
                 auto string = TRY(deserialize_string_primitive(m_vm, m_vector, position));