2021-06-12 05:28:30 +03:00
/*
* Copyright ( c ) 2021 , Idan Horowitz < idan . horowitz @ serenityos . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2021-06-20 01:09:39 +01:00
# include <LibJS/Runtime/AbstractOperations.h>
2021-06-12 05:28:30 +03:00
# include <LibJS/Runtime/Error.h>
# include <LibJS/Runtime/GlobalObject.h>
2023-07-19 06:54:48 -04:00
# include <LibJS/Runtime/Iterator.h>
2021-06-12 05:28:30 +03:00
# include <LibJS/Runtime/WeakMap.h>
# include <LibJS/Runtime/WeakMapConstructor.h>
namespace JS {
2022-08-16 00:20:49 +01:00
WeakMapConstructor : : WeakMapConstructor ( Realm & realm )
2023-04-13 00:47:15 +02:00
: NativeFunction ( realm . vm ( ) . names . WeakMap . as_string ( ) , realm . intrinsics ( ) . function_prototype ( ) )
2021-06-12 05:28:30 +03:00
{
}
2023-01-28 12:33:35 -05:00
ThrowCompletionOr < void > WeakMapConstructor : : initialize ( Realm & realm )
2021-06-12 05:28:30 +03:00
{
auto & vm = this - > vm ( ) ;
2023-01-28 12:33:35 -05:00
MUST_OR_THROW_OOM ( NativeFunction : : initialize ( realm ) ) ;
2021-06-19 00:38:41 +01:00
// 24.3.2.1 WeakMap.prototype, https://tc39.es/ecma262/#sec-weakmap.prototype
2022-08-27 00:54:55 +01:00
define_direct_property ( vm . names . prototype , realm . intrinsics ( ) . weak_map_prototype ( ) , 0 ) ;
2021-06-19 00:38:41 +01:00
2021-07-06 02:15:08 +03:00
define_direct_property ( vm . names . length , Value ( 0 ) , Attribute : : Configurable ) ;
2023-01-28 12:33:35 -05:00
return { } ;
2021-06-12 05:28:30 +03:00
}
2021-06-19 00:38:41 +01:00
// 24.3.1.1 WeakMap ( [ iterable ] ), https://tc39.es/ecma262/#sec-weakmap-iterable
2021-10-20 21:16:30 +01:00
ThrowCompletionOr < Value > WeakMapConstructor : : call ( )
2021-06-12 05:28:30 +03:00
{
auto & vm = this - > vm ( ) ;
2023-04-12 23:14:38 +02:00
// 1. If NewTarget is undefined, throw a TypeError exception.
2022-08-16 20:33:17 +01:00
return vm . throw_completion < TypeError > ( ErrorType : : ConstructorWithoutNew , vm . names . WeakMap ) ;
2021-06-12 05:28:30 +03:00
}
2021-06-12 23:24:20 +03:00
// 24.3.1.1 WeakMap ( [ iterable ] ), https://tc39.es/ecma262/#sec-weakmap-iterable
2022-12-14 19:18:10 +00:00
ThrowCompletionOr < NonnullGCPtr < Object > > WeakMapConstructor : : construct ( FunctionObject & new_target )
2021-06-12 05:28:30 +03:00
{
auto & vm = this - > vm ( ) ;
2023-04-12 23:14:38 +02:00
auto iterable = vm . argument ( 0 ) ;
// 2. Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakMap.prototype%", « [[WeakMapData]] »).
// 3. Set map.[[WeakMapData]] to a new empty List.
auto map = TRY ( ordinary_create_from_constructor < WeakMap > ( vm , new_target , & Intrinsics : : weak_map_prototype ) ) ;
2021-06-20 01:09:39 +01:00
2023-04-12 23:14:38 +02:00
// 4. If iterable is either undefined or null, return map.
if ( iterable . is_nullish ( ) )
return map ;
2021-06-20 01:09:39 +01:00
2023-04-12 23:14:38 +02:00
// 5. Let adder be ? Get(map, "set").
auto adder = TRY ( map - > get ( vm . names . set ) ) ;
2021-06-12 05:28:30 +03:00
2023-04-12 23:14:38 +02:00
// 6. If IsCallable(adder) is false, throw a TypeError exception.
2021-10-20 21:16:30 +01:00
if ( ! adder . is_function ( ) )
2022-08-16 20:33:17 +01:00
return vm . throw_completion < TypeError > ( ErrorType : : NotAFunction , " 'set' property of WeakMap " ) ;
2021-10-20 12:10:23 -04:00
2023-04-12 23:14:38 +02:00
// 7. Return ? AddEntriesFromIterable(map, iterable, adder).
( void ) TRY ( get_iterator_values ( vm , iterable , [ & ] ( Value iterator_value ) - > Optional < Completion > {
2021-10-20 12:10:23 -04:00
if ( ! iterator_value . is_object ( ) )
2023-02-12 21:26:14 -05:00
return vm . throw_completion < TypeError > ( ErrorType : : NotAnObject , DeprecatedString : : formatted ( " Iterator value {} " , TRY_OR_THROW_OOM ( vm , iterator_value . to_string_without_side_effects ( ) ) ) ) ;
2021-10-20 12:10:23 -04:00
auto key = TRY ( iterator_value . as_object ( ) . get ( 0 ) ) ;
auto value = TRY ( iterator_value . as_object ( ) . get ( 1 ) ) ;
2023-04-12 23:14:38 +02:00
TRY ( JS : : call ( vm , adder . as_function ( ) , map , key , value ) ) ;
2021-10-20 12:10:23 -04:00
2021-06-12 05:28:30 +03:00
return { } ;
2021-10-20 12:10:23 -04:00
} ) ) ;
2023-04-12 23:14:38 +02:00
return map ;
2021-06-12 05:28:30 +03:00
}
}