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>
# include <LibJS/Runtime/IteratorOperations.h>
# include <LibJS/Runtime/WeakMap.h>
# include <LibJS/Runtime/WeakMapConstructor.h>
namespace JS {
WeakMapConstructor : : WeakMapConstructor ( GlobalObject & global_object )
2021-06-28 03:45:49 +03:00
: NativeFunction ( vm ( ) . names . WeakMap . as_string ( ) , * global_object . function_prototype ( ) )
2021-06-12 05:28:30 +03:00
{
}
void WeakMapConstructor : : initialize ( GlobalObject & global_object )
{
auto & vm = this - > vm ( ) ;
NativeFunction : : initialize ( global_object ) ;
2021-06-19 00:38:41 +01:00
// 24.3.2.1 WeakMap.prototype, https://tc39.es/ecma262/#sec-weakmap.prototype
2021-07-06 02:15:08 +03:00
define_direct_property ( vm . names . prototype , global_object . 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 ) ;
2021-06-12 05:28:30 +03:00
}
WeakMapConstructor : : ~ WeakMapConstructor ( )
{
}
2021-06-19 00:38:41 +01:00
// 24.3.1.1 WeakMap ( [ iterable ] ), https://tc39.es/ecma262/#sec-weakmap-iterable
2021-06-12 05:28:30 +03:00
Value WeakMapConstructor : : call ( )
{
auto & vm = this - > vm ( ) ;
vm . throw_exception < TypeError > ( global_object ( ) , ErrorType : : ConstructorWithoutNew , vm . names . WeakMap ) ;
return { } ;
}
2021-06-12 23:24:20 +03:00
// 24.3.1.1 WeakMap ( [ iterable ] ), https://tc39.es/ecma262/#sec-weakmap-iterable
2021-06-27 21:48:34 +02:00
Value WeakMapConstructor : : construct ( FunctionObject & new_target )
2021-06-12 05:28:30 +03:00
{
auto & vm = this - > vm ( ) ;
2021-06-20 01:09:39 +01:00
auto & global_object = this - > global_object ( ) ;
2021-09-16 00:57:38 +03:00
auto * weak_map = TRY_OR_DISCARD ( ordinary_create_from_constructor < WeakMap > ( global_object , new_target , & GlobalObject : : weak_map_prototype ) ) ;
2021-06-20 01:09:39 +01:00
2021-06-12 05:28:30 +03:00
if ( vm . argument ( 0 ) . is_nullish ( ) )
2021-06-20 01:09:39 +01:00
return weak_map ;
2021-06-12 05:28:30 +03:00
2021-10-02 23:52:27 +01:00
auto adder = TRY_OR_DISCARD ( weak_map - > get ( vm . names . set ) ) ;
2021-06-12 05:28:30 +03:00
if ( ! adder . is_function ( ) ) {
2021-06-20 01:09:39 +01:00
vm . throw_exception < TypeError > ( global_object , ErrorType : : NotAFunction , " 'set' property of WeakMap " ) ;
2021-06-12 05:28:30 +03:00
return { } ;
}
2021-06-20 01:09:39 +01:00
get_iterator_values ( global_object , vm . argument ( 0 ) , [ & ] ( Value iterator_value ) {
2021-06-12 05:28:30 +03:00
if ( vm . exception ( ) )
return IterationDecision : : Break ;
if ( ! iterator_value . is_object ( ) ) {
2021-06-20 01:09:39 +01:00
vm . throw_exception < TypeError > ( global_object , ErrorType : : NotAnObject , String : : formatted ( " Iterator value {} " , iterator_value . to_string_without_side_effects ( ) ) ) ;
2021-06-12 05:28:30 +03:00
return IterationDecision : : Break ;
}
2021-10-02 23:52:27 +01:00
auto key_or_error = iterator_value . as_object ( ) . get ( 0 ) ;
if ( key_or_error . is_error ( ) )
2021-06-12 05:28:30 +03:00
return IterationDecision : : Break ;
2021-10-02 23:52:27 +01:00
auto key = key_or_error . release_value ( ) ;
auto value_or_error = iterator_value . as_object ( ) . get ( 1 ) ;
if ( value_or_error . is_error ( ) )
2021-06-12 05:28:30 +03:00
return IterationDecision : : Break ;
2021-10-02 23:52:27 +01:00
auto value = value_or_error . release_value ( ) ;
2021-09-23 20:56:28 +03:00
auto result = vm . call ( adder . as_function ( ) , Value ( weak_map ) , key , value ) ;
return result . is_error ( ) ? IterationDecision : : Break : IterationDecision : : Continue ;
2021-06-12 05:28:30 +03:00
} ) ;
if ( vm . exception ( ) )
return { } ;
return weak_map ;
}
}