diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index eace11ef0e..c6d98e36c2 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/Userland/Libraries/LibJS/Runtime/Object.cpp @@ -438,7 +438,8 @@ ThrowCompletionOr> Object::enumerable_own_property_names(Pro } // 7.3.26 CopyDataProperties ( target, source, excludedItems ), https://tc39.es/ecma262/#sec-copydataproperties -ThrowCompletionOr Object::copy_data_properties(VM& vm, Value source, HashTable const& seen_names) +// 14.6 CopyDataProperties ( target, source, excludedItems, excludedKeys [ , excludedValues ] ), https://tc39.es/proposal-temporal/#sec-copydataproperties +ThrowCompletionOr Object::copy_data_properties(VM& vm, Value source, HashTable const& excluded_keys, HashTable const& excluded_values) { // 1. If source is either undefined or null, return unused. if (source.is_nullish()) @@ -455,10 +456,10 @@ ThrowCompletionOr Object::copy_data_properties(VM& vm, Value source, HashT auto next_key = MUST(PropertyKey::from_value(vm, next_key_value)); // a. Let excluded be false. - // b. For each element e of excludedItems, do + // b. For each element e of excludedKeys, do // i. If SameValue(e, nextKey) is true, then // 1. Set excluded to true. - if (seen_names.contains(next_key)) + if (excluded_keys.contains(next_key)) continue; // c. If excluded is false, then @@ -471,8 +472,14 @@ ThrowCompletionOr Object::copy_data_properties(VM& vm, Value source, HashT // 1. Let propValue be ? Get(from, nextKey). auto prop_value = TRY(from->get(next_key)); - // 2. Perform ! CreateDataPropertyOrThrow(target, nextKey, propValue). - MUST(create_data_property_or_throw(next_key, prop_value)); + // 2. If excludedValues is present, then + // a. For each element e of excludedValues, do + // i. If SameValue(e, propValue) is true, then + // i. Set excluded to true. + // 3. If excluded is false, Perform ! CreateDataPropertyOrThrow(target, nextKey, propValue). + // NOTE: HashTable traits for JS::Value uses SameValue. + if (!excluded_values.contains(prop_value)) + MUST(create_data_property_or_throw(next_key, prop_value)); } } diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h index 46634999f6..492a556301 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.h +++ b/Userland/Libraries/LibJS/Runtime/Object.h @@ -118,7 +118,7 @@ public: ThrowCompletionOr set_integrity_level(IntegrityLevel); ThrowCompletionOr test_integrity_level(IntegrityLevel) const; ThrowCompletionOr> enumerable_own_property_names(PropertyKind kind) const; - ThrowCompletionOr copy_data_properties(VM&, Value source, HashTable const& seen_names); + ThrowCompletionOr copy_data_properties(VM&, Value source, HashTable const& excluded_keys, HashTable const& excluded_values = {}); PrivateElement* private_element_find(PrivateName const& name); ThrowCompletionOr private_field_add(PrivateName const& name, Value value);