2020-03-28 17:23:54 +01:00
/*
* Copyright ( c ) 2020 , Andreas Kling < kling @ serenityos . org >
2021-04-22 22:51:19 +02:00
* Copyright ( c ) 2020 - 2021 , Linus Groh < linusg @ serenityos . org >
2020-03-28 17:23:54 +01:00
*
2021-04-22 01:24:48 -07:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-03-28 17:23:54 +01:00
*/
# include <AK/Function.h>
2021-06-19 21:45:00 +01:00
# include <LibJS/Runtime/AbstractOperations.h>
2020-03-29 01:08:25 +01:00
# include <LibJS/Runtime/Array.h>
2020-04-09 22:15:26 +02:00
# include <LibJS/Runtime/Error.h>
2020-04-18 13:18:06 +02:00
# include <LibJS/Runtime/GlobalObject.h>
2021-06-15 12:46:14 +03:00
# include <LibJS/Runtime/IteratorOperations.h>
2020-03-28 17:23:54 +01:00
# include <LibJS/Runtime/ObjectConstructor.h>
2021-01-01 17:46:39 +01:00
# include <LibJS/Runtime/ProxyObject.h>
2020-04-02 19:32:21 +02:00
# include <LibJS/Runtime/Shape.h>
2020-03-28 17:23:54 +01:00
namespace JS {
2020-06-20 15:40:48 +02:00
ObjectConstructor : : ObjectConstructor ( GlobalObject & global_object )
2021-06-28 03:45:49 +03:00
: NativeFunction ( vm ( ) . names . Object . as_string ( ) , * global_object . function_prototype ( ) )
2020-03-28 17:23:54 +01:00
{
2020-06-20 15:40:48 +02:00
}
2020-07-22 17:50:18 +02:00
void ObjectConstructor : : initialize ( GlobalObject & global_object )
2020-06-20 15:40:48 +02:00
{
2020-10-13 23:49:19 +02:00
auto & vm = this - > vm ( ) ;
2020-07-22 17:50:18 +02:00
NativeFunction : : initialize ( global_object ) ;
2021-06-13 00:22:35 +01:00
// 20.1.2.19 Object.prototype, https://tc39.es/ecma262/#sec-object.prototype
2020-10-13 23:49:19 +02:00
define_property ( vm . names . prototype , global_object . object_prototype ( ) , 0 ) ;
2021-06-13 00:22:35 +01:00
2020-10-13 23:49:19 +02:00
define_property ( vm . names . length , Value ( 1 ) , Attribute : : Configurable ) ;
2020-03-28 17:23:54 +01:00
2020-04-27 23:05:02 -07:00
u8 attr = Attribute : : Writable | Attribute : : Configurable ;
2020-10-13 23:49:19 +02:00
define_native_function ( vm . names . defineProperty , define_property_ , 3 , attr ) ;
2021-04-10 18:39:11 +02:00
define_native_function ( vm . names . defineProperties , define_properties , 2 , attr ) ;
2020-10-13 23:49:19 +02:00
define_native_function ( vm . names . is , is , 2 , attr ) ;
define_native_function ( vm . names . getOwnPropertyDescriptor , get_own_property_descriptor , 2 , attr ) ;
define_native_function ( vm . names . getOwnPropertyNames , get_own_property_names , 1 , attr ) ;
2021-06-12 17:41:13 +03:00
define_native_function ( vm . names . getOwnPropertySymbols , get_own_property_symbols , 1 , attr ) ;
2020-10-13 23:49:19 +02:00
define_native_function ( vm . names . getPrototypeOf , get_prototype_of , 1 , attr ) ;
define_native_function ( vm . names . setPrototypeOf , set_prototype_of , 2 , attr ) ;
define_native_function ( vm . names . isExtensible , is_extensible , 1 , attr ) ;
2021-04-06 22:45:12 +02:00
define_native_function ( vm . names . isFrozen , is_frozen , 1 , attr ) ;
define_native_function ( vm . names . isSealed , is_sealed , 1 , attr ) ;
2020-10-13 23:49:19 +02:00
define_native_function ( vm . names . preventExtensions , prevent_extensions , 1 , attr ) ;
2021-04-06 22:06:11 +02:00
define_native_function ( vm . names . freeze , freeze , 1 , attr ) ;
2021-06-15 12:46:14 +03:00
define_native_function ( vm . names . fromEntries , from_entries , 1 , attr ) ;
2021-04-06 22:06:11 +02:00
define_native_function ( vm . names . seal , seal , 1 , attr ) ;
2020-10-13 23:49:19 +02:00
define_native_function ( vm . names . keys , keys , 1 , attr ) ;
define_native_function ( vm . names . values , values , 1 , attr ) ;
define_native_function ( vm . names . entries , entries , 1 , attr ) ;
2021-04-10 18:40:12 +02:00
define_native_function ( vm . names . create , create , 2 , attr ) ;
2021-05-18 11:15:49 +02:00
define_native_function ( vm . names . hasOwn , has_own , 2 , attr ) ;
2021-06-12 11:35:53 +01:00
define_native_function ( vm . names . assign , assign , 2 , attr ) ;
2020-03-28 17:23:54 +01:00
}
ObjectConstructor : : ~ ObjectConstructor ( )
{
}
2021-06-13 00:22:35 +01:00
// 20.1.1.1 Object ( [ value ] ), https://tc39.es/ecma262/#sec-object-value
2020-09-27 17:24:14 +02:00
Value ObjectConstructor : : call ( )
2021-06-20 01:09:39 +01:00
{
return construct ( * this ) ;
}
// 20.1.1.1 Object ( [ value ] ), https://tc39.es/ecma262/#sec-object-value
2021-06-27 21:48:34 +02:00
Value ObjectConstructor : : construct ( FunctionObject & new_target )
2020-03-28 17:23:54 +01:00
{
2021-06-16 20:52:30 +01:00
auto & vm = this - > vm ( ) ;
auto & global_object = this - > global_object ( ) ;
2021-06-20 01:09:39 +01:00
if ( & new_target ! = this )
return ordinary_create_from_constructor < Object > ( global_object , new_target , & GlobalObject : : object_prototype ) ;
2021-06-16 20:52:30 +01:00
auto value = vm . argument ( 0 ) ;
2020-11-04 21:13:07 +00:00
if ( value . is_nullish ( ) )
2021-06-16 20:52:30 +01:00
return Object : : create ( global_object , global_object . object_prototype ( ) ) ;
return value . to_object ( global_object ) ;
2020-03-28 17:23:54 +01:00
}
2021-06-13 00:22:35 +01:00
// 20.1.2.10 Object.getOwnPropertyNames ( O ), https://tc39.es/ecma262/#sec-object.getownpropertynames
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : get_own_property_names )
2020-03-29 01:08:25 +01:00
{
2020-09-27 18:36:49 +02:00
auto * object = vm . argument ( 0 ) . to_object ( global_object ) ;
if ( vm . exception ( ) )
2020-03-29 01:08:25 +01:00
return { } ;
2021-04-25 22:40:21 +02:00
return Array : : create_from ( global_object , object - > get_own_properties ( PropertyKind : : Key , false , GetOwnPropertyReturnType : : StringOnly ) ) ;
2020-03-29 01:08:25 +01:00
}
2021-06-13 00:22:35 +01:00
// 20.1.2.11 Object.getOwnPropertySymbols ( O ), https://tc39.es/ecma262/#sec-object.getownpropertysymbols
2021-06-12 17:41:13 +03:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : get_own_property_symbols )
{
auto * object = vm . argument ( 0 ) . to_object ( global_object ) ;
if ( vm . exception ( ) )
return { } ;
return Array : : create_from ( global_object , object - > get_own_properties ( PropertyKind : : Key , false , GetOwnPropertyReturnType : : SymbolOnly ) ) ;
}
2021-06-13 00:22:35 +01:00
// 20.1.2.12 Object.getPrototypeOf ( O ), https://tc39.es/ecma262/#sec-object.getprototypeof
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : get_prototype_of )
2020-03-28 22:48:35 +01:00
{
2020-09-27 18:36:49 +02:00
auto * object = vm . argument ( 0 ) . to_object ( global_object ) ;
if ( vm . exception ( ) )
2020-03-28 22:48:35 +01:00
return { } ;
return object - > prototype ( ) ;
}
2021-06-13 00:22:35 +01:00
// 20.1.2.21 Object.setPrototypeOf ( O, proto ), https://tc39.es/ecma262/#sec-object.setprototypeof
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : set_prototype_of )
2020-03-28 22:48:35 +01:00
{
2021-06-22 18:59:24 +01:00
auto argument = require_object_coercible ( global_object , vm . argument ( 0 ) ) ;
2020-09-27 18:36:49 +02:00
if ( vm . exception ( ) )
2020-03-28 22:48:35 +01:00
return { } ;
2020-09-27 18:36:49 +02:00
auto prototype_value = vm . argument ( 1 ) ;
2021-06-22 18:59:24 +01:00
if ( ! prototype_value . is_object ( ) & & ! prototype_value . is_null ( ) ) {
2020-09-27 18:36:49 +02:00
vm . throw_exception < TypeError > ( global_object , ErrorType : : ObjectPrototypeWrongType ) ;
2020-06-02 12:25:21 +01:00
return { } ;
}
2021-06-22 18:59:24 +01:00
if ( ! argument . is_object ( ) )
return argument ;
auto * prototype = prototype_value . is_null ( ) ? nullptr : & prototype_value . as_object ( ) ;
auto status = argument . as_object ( ) . set_prototype ( prototype ) ;
if ( vm . exception ( ) )
return { } ;
if ( ! status ) {
vm . throw_exception < TypeError > ( global_object , ErrorType : : ObjectSetPrototypeOfReturnedFalse ) ;
2020-06-02 12:32:54 +01:00
return { } ;
}
2021-06-22 18:59:24 +01:00
return argument ;
2020-03-28 22:48:35 +01:00
}
2021-06-13 00:22:35 +01:00
// 20.1.2.14 Object.isExtensible ( O ), https://tc39.es/ecma262/#sec-object.isextensible
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : is_extensible )
2020-06-01 21:13:16 -07:00
{
2020-09-27 18:36:49 +02:00
auto argument = vm . argument ( 0 ) ;
2020-06-01 21:13:16 -07:00
if ( ! argument . is_object ( ) )
return Value ( false ) ;
return Value ( argument . as_object ( ) . is_extensible ( ) ) ;
}
2021-06-13 00:22:35 +01:00
// 20.1.2.15 Object.isFrozen ( O ), https://tc39.es/ecma262/#sec-object.isfrozen
2021-04-06 22:45:12 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : is_frozen )
{
auto argument = vm . argument ( 0 ) ;
if ( ! argument . is_object ( ) )
return Value ( true ) ;
return Value ( argument . as_object ( ) . test_integrity_level ( Object : : IntegrityLevel : : Frozen ) ) ;
}
2021-06-13 00:22:35 +01:00
// 20.1.2.16 Object.isSealed ( O ), https://tc39.es/ecma262/#sec-object.issealed
2021-04-06 22:45:12 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : is_sealed )
{
auto argument = vm . argument ( 0 ) ;
if ( ! argument . is_object ( ) )
return Value ( true ) ;
return Value ( argument . as_object ( ) . test_integrity_level ( Object : : IntegrityLevel : : Sealed ) ) ;
}
2021-06-13 00:22:35 +01:00
// 20.1.2.18 Object.preventExtensions ( O ), https://tc39.es/ecma262/#sec-object.preventextensions
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : prevent_extensions )
2020-06-01 21:13:16 -07:00
{
2020-09-27 18:36:49 +02:00
auto argument = vm . argument ( 0 ) ;
2020-06-01 21:13:16 -07:00
if ( ! argument . is_object ( ) )
return argument ;
2021-04-06 22:06:11 +02:00
auto status = argument . as_object ( ) . prevent_extensions ( ) ;
if ( vm . exception ( ) )
return { } ;
if ( ! status ) {
vm . throw_exception < TypeError > ( global_object , ErrorType : : ObjectPreventExtensionsReturnedFalse ) ;
return { } ;
}
return argument ;
}
2021-06-13 00:22:35 +01:00
// 20.1.2.6 Object.freeze ( O ), https://tc39.es/ecma262/#sec-object.freeze
2021-04-06 22:06:11 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : freeze )
{
auto argument = vm . argument ( 0 ) ;
if ( ! argument . is_object ( ) )
return argument ;
auto status = argument . as_object ( ) . set_integrity_level ( Object : : IntegrityLevel : : Frozen ) ;
if ( vm . exception ( ) )
return { } ;
if ( ! status ) {
vm . throw_exception < TypeError > ( global_object , ErrorType : : ObjectFreezeFailed ) ;
return { } ;
}
return argument ;
}
2021-06-15 12:46:14 +03:00
// 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 { } ;
2021-06-16 20:52:30 +01:00
auto * object = Object : : create ( global_object , global_object . object_prototype ( ) ) ;
2021-06-15 12:46:14 +03:00
get_iterator_values ( global_object , iterable , [ & ] ( Value iterator_value ) {
if ( vm . exception ( ) )
return IterationDecision : : Break ;
if ( ! iterator_value . is_object ( ) ) {
vm . throw_exception < TypeError > ( 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 ;
}
2021-06-13 00:22:35 +01:00
// 20.1.2.20 Object.seal ( O ), https://tc39.es/ecma262/#sec-object.seal
2021-04-06 22:06:11 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : seal )
{
auto argument = vm . argument ( 0 ) ;
if ( ! argument . is_object ( ) )
return argument ;
auto status = argument . as_object ( ) . set_integrity_level ( Object : : IntegrityLevel : : Sealed ) ;
if ( vm . exception ( ) )
return { } ;
if ( ! status ) {
vm . throw_exception < TypeError > ( global_object , ErrorType : : ObjectSealFailed ) ;
2020-06-01 21:13:16 -07:00
return { } ;
}
return argument ;
}
2021-06-13 00:22:35 +01:00
// 20.1.2.8 Object.getOwnPropertyDescriptor ( O, P ), https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : get_own_property_descriptor )
2020-04-09 22:15:26 +02:00
{
2020-09-27 18:36:49 +02:00
auto * object = vm . argument ( 0 ) . to_object ( global_object ) ;
if ( vm . exception ( ) )
2020-04-25 18:43:34 +02:00
return { } ;
2021-06-07 16:54:04 +03:00
auto property_key = vm . argument ( 1 ) . to_property_key ( global_object ) ;
2020-09-27 18:36:49 +02:00
if ( vm . exception ( ) )
2020-05-15 13:39:24 +02:00
return { } ;
2020-06-03 09:40:17 -07:00
return object - > get_own_property_descriptor_object ( property_key ) ;
2020-04-09 22:15:26 +02:00
}
2021-06-13 00:22:35 +01:00
// 20.1.2.4 Object.defineProperty ( O, P, Attributes ), https://tc39.es/ecma262/#sec-object.defineproperty
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : define_property_ )
2020-04-09 22:15:26 +02:00
{
2020-09-27 18:36:49 +02:00
if ( ! vm . argument ( 0 ) . is_object ( ) ) {
vm . throw_exception < TypeError > ( global_object , ErrorType : : NotAnObject , " Object argument " ) ;
2020-08-25 12:52:32 +02:00
return { } ;
}
2021-06-05 15:22:11 +03:00
auto property_key = vm . argument ( 1 ) . to_property_key ( global_object ) ;
if ( vm . exception ( ) )
return { } ;
2020-09-27 18:36:49 +02:00
if ( ! vm . argument ( 2 ) . is_object ( ) ) {
vm . throw_exception < TypeError > ( global_object , ErrorType : : NotAnObject , " Descriptor argument " ) ;
2020-08-25 12:52:32 +02:00
return { } ;
}
2020-09-27 18:36:49 +02:00
auto & object = vm . argument ( 0 ) . as_object ( ) ;
auto & descriptor = vm . argument ( 2 ) . as_object ( ) ;
2020-06-03 14:34:52 -07:00
if ( ! object . define_property ( property_key , descriptor ) ) {
2020-09-27 18:36:49 +02:00
if ( ! vm . exception ( ) ) {
2021-01-01 17:46:39 +01:00
if ( AK : : is < ProxyObject > ( object ) ) {
2020-09-27 18:36:49 +02:00
vm . throw_exception < TypeError > ( global_object , ErrorType : : ObjectDefinePropertyReturnedFalse ) ;
2020-06-03 14:34:52 -07:00
} else {
2020-10-04 13:55:20 +01:00
vm . throw_exception < TypeError > ( global_object , ErrorType : : NonExtensibleDefine , property_key . to_display_string ( ) ) ;
2020-06-03 14:34:52 -07:00
}
}
return { } ;
}
2020-04-09 22:15:26 +02:00
return & object ;
}
2021-06-13 00:22:35 +01:00
// 20.1.2.3 Object.defineProperties ( O, Properties ), https://tc39.es/ecma262/#sec-object.defineproperties
2021-04-10 18:39:11 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : define_properties )
{
if ( ! vm . argument ( 0 ) . is_object ( ) ) {
vm . throw_exception < TypeError > ( global_object , ErrorType : : NotAnObject , " Object argument " ) ;
return { } ;
}
auto & object = vm . argument ( 0 ) . as_object ( ) ;
auto properties = vm . argument ( 1 ) ;
object . define_properties ( properties ) ;
if ( vm . exception ( ) )
return { } ;
return & object ;
}
2021-06-13 00:22:35 +01:00
// 20.1.2.13 Object.is ( value1, value2 ), https://tc39.es/ecma262/#sec-object.is
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : is )
2020-04-26 00:27:54 +01:00
{
2020-09-27 18:36:49 +02:00
return Value ( same_value ( vm . argument ( 0 ) , vm . argument ( 1 ) ) ) ;
2020-04-26 00:27:54 +01:00
}
2021-06-13 00:22:35 +01:00
// 20.1.2.17 Object.keys ( O ), https://tc39.es/ecma262/#sec-object.keys
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : keys )
2020-04-29 18:59:23 -07:00
{
2020-09-27 18:36:49 +02:00
auto * obj_arg = vm . argument ( 0 ) . to_object ( global_object ) ;
if ( vm . exception ( ) )
2020-04-29 18:59:23 -07:00
return { } ;
2021-04-06 21:39:17 +02:00
return Array : : create_from ( global_object , obj_arg - > get_enumerable_own_property_names ( PropertyKind : : Key ) ) ;
2020-04-29 18:59:23 -07:00
}
2021-06-13 00:22:35 +01:00
// 20.1.2.22 Object.values ( O ), https://tc39.es/ecma262/#sec-object.values
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : values )
2020-04-29 18:59:23 -07:00
{
2020-09-27 18:36:49 +02:00
auto * obj_arg = vm . argument ( 0 ) . to_object ( global_object ) ;
if ( vm . exception ( ) )
2020-04-29 18:59:23 -07:00
return { } ;
2021-04-06 21:39:17 +02:00
return Array : : create_from ( global_object , obj_arg - > get_enumerable_own_property_names ( PropertyKind : : Value ) ) ;
2020-04-29 18:59:23 -07:00
}
2021-06-13 00:22:35 +01:00
// 20.1.2.5 Object.entries ( O ), https://tc39.es/ecma262/#sec-object.entries
2020-06-20 13:55:34 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : entries )
2020-04-29 18:59:23 -07:00
{
2020-09-27 18:36:49 +02:00
auto * obj_arg = vm . argument ( 0 ) . to_object ( global_object ) ;
if ( vm . exception ( ) )
2020-04-29 18:59:23 -07:00
return { } ;
2021-04-06 21:39:17 +02:00
return Array : : create_from ( global_object , obj_arg - > get_enumerable_own_property_names ( PropertyKind : : KeyAndValue ) ) ;
2020-04-29 18:59:23 -07:00
}
2021-06-13 00:22:35 +01:00
// 20.1.2.2 Object.create ( O, Properties ), https://tc39.es/ecma262/#sec-object.create
2021-04-10 18:40:12 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : create )
{
auto prototype_value = vm . argument ( 0 ) ;
auto properties = vm . argument ( 1 ) ;
Object * prototype ;
if ( prototype_value . is_null ( ) ) {
prototype = nullptr ;
} else if ( prototype_value . is_object ( ) ) {
prototype = & prototype_value . as_object ( ) ;
} else {
vm . throw_exception < TypeError > ( global_object , ErrorType : : ObjectPrototypeWrongType ) ;
return { } ;
}
2021-06-16 20:52:30 +01:00
auto * object = Object : : create ( global_object , prototype ) ;
2021-04-10 18:40:12 +02:00
if ( ! properties . is_undefined ( ) ) {
object - > define_properties ( properties ) ;
if ( vm . exception ( ) )
return { } ;
}
return object ;
}
2021-06-13 00:22:35 +01:00
// 1 Object.hasOwn ( O, P ), https://tc39.es/proposal-accessible-object-hasownproperty/#sec-object.hasown
2021-05-18 11:15:49 +02:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : has_own )
{
auto * object = vm . argument ( 0 ) . to_object ( global_object ) ;
if ( vm . exception ( ) )
return { } ;
2021-06-05 15:22:11 +03:00
auto property_key = vm . argument ( 1 ) . to_property_key ( global_object ) ;
2021-05-18 11:15:49 +02:00
if ( vm . exception ( ) )
return { } ;
2021-06-05 15:22:11 +03:00
return Value ( object - > has_own_property ( property_key ) ) ;
2021-05-18 11:15:49 +02:00
}
2021-06-13 00:22:35 +01:00
// 20.1.2.1 Object.assign ( target, ...sources ), https://tc39.es/ecma262/#sec-object.assign
2021-06-12 11:35:53 +01:00
JS_DEFINE_NATIVE_FUNCTION ( ObjectConstructor : : assign )
{
auto * to = vm . argument ( 0 ) . to_object ( global_object ) ;
if ( vm . exception ( ) )
return { } ;
if ( vm . argument_count ( ) = = 1 )
return to ;
for ( size_t i = 1 ; i < vm . argument_count ( ) ; + + i ) {
auto next_source = vm . argument ( i ) ;
if ( next_source . is_nullish ( ) )
continue ;
auto from = next_source . to_object ( global_object ) ;
VERIFY ( ! vm . exception ( ) ) ;
auto keys = from - > get_own_properties ( PropertyKind : : Key ) ;
if ( vm . exception ( ) )
return { } ;
for ( auto & key : keys ) {
auto property_name = PropertyName : : from_value ( global_object , key ) ;
auto property_descriptor = from - > get_own_property_descriptor ( property_name ) ;
if ( ! property_descriptor . has_value ( ) | | ! property_descriptor - > attributes . is_enumerable ( ) )
continue ;
auto value = from - > get ( property_name ) ;
if ( vm . exception ( ) )
return { } ;
to - > put ( property_name , value ) ;
if ( vm . exception ( ) )
return { } ;
}
}
return to ;
}
2020-03-28 17:23:54 +01:00
}