diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index 2999509eb9..c677708c4e 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -127,6 +127,7 @@ namespace JS { P(freeze) \ P(from) \ P(fromCharCode) \ + P(fromEntries) \ P(fround) \ P(gc) \ P(get) \ diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 54982e4bd7..99245c513e 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,7 @@ void ObjectConstructor::initialize(GlobalObject& global_object) define_native_function(vm.names.isSealed, is_sealed, 1, attr); define_native_function(vm.names.preventExtensions, prevent_extensions, 1, attr); define_native_function(vm.names.freeze, freeze, 1, attr); + define_native_function(vm.names.fromEntries, from_entries, 1, attr); define_native_function(vm.names.seal, seal, 1, attr); define_native_function(vm.names.keys, keys, 1, attr); define_native_function(vm.names.values, values, 1, attr); @@ -182,6 +184,42 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::freeze) return argument; } +// 20.1.2.7 Object.fromEntries ( iterable ), https://tc39.es/ecma262/#sec-object.fromentries +JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::from_entries) +{ + auto iterable = require_object_coercible(global_object, vm.argument(0)); + if (vm.exception()) + return {}; + + auto* object = Object::create_empty(global_object); + object->set_prototype(global_object.object_prototype()); + + get_iterator_values(global_object, iterable, [&](Value iterator_value) { + if (vm.exception()) + return IterationDecision::Break; + if (!iterator_value.is_object()) { + vm.throw_exception(global_object, ErrorType::NotAnObject, String::formatted("Iterator value {}", iterator_value.to_string_without_side_effects())); + return IterationDecision::Break; + } + auto key = iterator_value.as_object().get(0).value_or(js_undefined()); + if (vm.exception()) + return IterationDecision::Break; + auto value = iterator_value.as_object().get(1).value_or(js_undefined()); + if (vm.exception()) + return IterationDecision::Break; + auto property_key = key.to_property_key(global_object); + if (vm.exception()) + return IterationDecision::Break; + object->define_property(property_key, value); + if (vm.exception()) + return IterationDecision::Break; + return IterationDecision::Continue; + }); + if (vm.exception()) + return {}; + return object; +} + // 20.1.2.20 Object.seal ( O ), https://tc39.es/ecma262/#sec-object.seal JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::seal) { diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h index 27e6456d12..50ea468e6b 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h +++ b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.h @@ -39,6 +39,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(prevent_extensions); JS_DECLARE_NATIVE_FUNCTION(seal); JS_DECLARE_NATIVE_FUNCTION(freeze); + JS_DECLARE_NATIVE_FUNCTION(from_entries); JS_DECLARE_NATIVE_FUNCTION(keys); JS_DECLARE_NATIVE_FUNCTION(values); JS_DECLARE_NATIVE_FUNCTION(entries);