mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
LibJS: Add the WeakMap built-in object
This commit is contained in:
parent
1a8ee5d8d7
commit
39554f3787
Notes:
sideshowbarker
2024-07-18 12:22:34 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/39554f3787e Pull-request: https://github.com/SerenityOS/serenity/pull/8014 Reviewed-by: https://github.com/linusg
9 changed files with 243 additions and 0 deletions
|
@ -101,6 +101,9 @@ set(SOURCES
|
|||
Runtime/TypedArrayPrototype.cpp
|
||||
Runtime/VM.cpp
|
||||
Runtime/Value.cpp
|
||||
Runtime/WeakMap.cpp
|
||||
Runtime/WeakMapConstructor.cpp
|
||||
Runtime/WeakMapPrototype.cpp
|
||||
Runtime/WeakSet.cpp
|
||||
Runtime/WeakSetConstructor.cpp
|
||||
Runtime/WeakSetPrototype.cpp
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
__JS_ENUMERATE(Set, set, SetPrototype, SetConstructor, void) \
|
||||
__JS_ENUMERATE(StringObject, string, StringPrototype, StringConstructor, void) \
|
||||
__JS_ENUMERATE(SymbolObject, symbol, SymbolPrototype, SymbolConstructor, void) \
|
||||
__JS_ENUMERATE(WeakMap, weak_map, WeakMapPrototype, WeakMapConstructor, void) \
|
||||
__JS_ENUMERATE(WeakSet, weak_set, WeakSetPrototype, WeakSetConstructor, void)
|
||||
|
||||
#define JS_ENUMERATE_NATIVE_OBJECTS \
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
#include <LibJS/Runtime/TypedArrayConstructor.h>
|
||||
#include <LibJS/Runtime/TypedArrayPrototype.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
#include <LibJS/Runtime/WeakMapConstructor.h>
|
||||
#include <LibJS/Runtime/WeakMapPrototype.h>
|
||||
#include <LibJS/Runtime/WeakSetConstructor.h>
|
||||
#include <LibJS/Runtime/WeakSetPrototype.h>
|
||||
|
||||
|
@ -154,6 +156,7 @@ void GlobalObject::initialize_global_object()
|
|||
add_constructor(vm.names.Set, m_set_constructor, m_set_prototype);
|
||||
add_constructor(vm.names.String, m_string_constructor, m_string_prototype);
|
||||
add_constructor(vm.names.Symbol, m_symbol_constructor, m_symbol_prototype);
|
||||
add_constructor(vm.names.WeakMap, m_weak_map_constructor, m_weak_map_prototype);
|
||||
add_constructor(vm.names.WeakSet, m_weak_set_constructor, m_weak_set_prototype);
|
||||
|
||||
initialize_constructor(vm.names.TypedArray, m_typed_array_constructor, m_typed_array_prototype);
|
||||
|
|
32
Userland/Libraries/LibJS/Runtime/WeakMap.cpp
Normal file
32
Userland/Libraries/LibJS/Runtime/WeakMap.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/WeakMap.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
WeakMap* WeakMap::create(GlobalObject& global_object)
|
||||
{
|
||||
return global_object.heap().allocate<WeakMap>(global_object, *global_object.weak_map_prototype());
|
||||
}
|
||||
|
||||
WeakMap::WeakMap(Object& prototype)
|
||||
: Object(prototype)
|
||||
, WeakContainer(heap())
|
||||
{
|
||||
}
|
||||
|
||||
WeakMap::~WeakMap()
|
||||
{
|
||||
}
|
||||
|
||||
void WeakMap::remove_sweeped_cells(Badge<Heap>, Vector<Cell*>& cells)
|
||||
{
|
||||
for (auto* cell : cells)
|
||||
m_values.remove(cell);
|
||||
}
|
||||
|
||||
}
|
36
Userland/Libraries/LibJS/Runtime/WeakMap.h
Normal file
36
Userland/Libraries/LibJS/Runtime/WeakMap.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/WeakContainer.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class WeakMap final
|
||||
: public Object
|
||||
, public WeakContainer {
|
||||
JS_OBJECT(WeakMap, Object);
|
||||
|
||||
public:
|
||||
static WeakMap* create(GlobalObject&);
|
||||
|
||||
explicit WeakMap(Object& prototype);
|
||||
virtual ~WeakMap() override;
|
||||
|
||||
HashMap<Cell*, Value> const& values() const { return m_values; };
|
||||
HashMap<Cell*, Value>& values() { return m_values; };
|
||||
|
||||
virtual void remove_sweeped_cells(Badge<Heap>, Vector<Cell*>&) override;
|
||||
|
||||
private:
|
||||
HashMap<Cell*, Value> m_values; // This stores Cell pointers instead of Object pointers to aide with sweeping
|
||||
};
|
||||
|
||||
}
|
74
Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp
Normal file
74
Userland/Libraries/LibJS/Runtime/WeakMapConstructor.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#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)
|
||||
: NativeFunction(vm().names.WeakMap, *global_object.function_prototype())
|
||||
{
|
||||
}
|
||||
|
||||
void WeakMapConstructor::initialize(GlobalObject& global_object)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
NativeFunction::initialize(global_object);
|
||||
define_property(vm.names.prototype, global_object.weak_map_prototype(), 0);
|
||||
define_property(vm.names.length, Value(0), Attribute::Configurable);
|
||||
}
|
||||
|
||||
WeakMapConstructor::~WeakMapConstructor()
|
||||
{
|
||||
}
|
||||
|
||||
Value WeakMapConstructor::call()
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
vm.throw_exception<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.WeakMap);
|
||||
return {};
|
||||
}
|
||||
|
||||
Value WeakMapConstructor::construct(Function&)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
if (vm.argument(0).is_nullish())
|
||||
return WeakMap::create(global_object());
|
||||
|
||||
auto* weak_map = WeakMap::create(global_object());
|
||||
auto adder = weak_map->get(vm.names.set);
|
||||
if (vm.exception())
|
||||
return {};
|
||||
if (!adder.is_function()) {
|
||||
vm.throw_exception<TypeError>(global_object(), ErrorType::NotAFunction, "'set' property of WeakMap");
|
||||
return {};
|
||||
}
|
||||
get_iterator_values(global_object(), vm.argument(0), [&](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);
|
||||
if (vm.exception())
|
||||
return IterationDecision::Break;
|
||||
auto value = iterator_value.as_object().get(1);
|
||||
if (vm.exception())
|
||||
return IterationDecision::Break;
|
||||
(void)vm.call(adder.as_function(), Value(weak_map), key, value);
|
||||
return vm.exception() ? IterationDecision::Break : IterationDecision::Continue;
|
||||
});
|
||||
if (vm.exception())
|
||||
return {};
|
||||
return weak_map;
|
||||
}
|
||||
|
||||
}
|
28
Userland/Libraries/LibJS/Runtime/WeakMapConstructor.h
Normal file
28
Userland/Libraries/LibJS/Runtime/WeakMapConstructor.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class WeakMapConstructor final : public NativeFunction {
|
||||
JS_OBJECT(WeakMapConstructor, NativeFunction);
|
||||
|
||||
public:
|
||||
explicit WeakMapConstructor(GlobalObject&);
|
||||
virtual void initialize(GlobalObject&) override;
|
||||
virtual ~WeakMapConstructor() override;
|
||||
|
||||
virtual Value call() override;
|
||||
virtual Value construct(Function&) override;
|
||||
|
||||
private:
|
||||
virtual bool has_constructor() const override { return true; }
|
||||
};
|
||||
|
||||
}
|
41
Userland/Libraries/LibJS/Runtime/WeakMapPrototype.cpp
Normal file
41
Userland/Libraries/LibJS/Runtime/WeakMapPrototype.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/HashTable.h>
|
||||
#include <LibJS/Runtime/WeakMapPrototype.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
WeakMapPrototype::WeakMapPrototype(GlobalObject& global_object)
|
||||
: Object(*global_object.object_prototype())
|
||||
{
|
||||
}
|
||||
|
||||
void WeakMapPrototype::initialize(GlobalObject& global_object)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
Object::initialize(global_object);
|
||||
|
||||
define_property(vm.well_known_symbol_to_string_tag(), js_string(global_object.heap(), vm.names.WeakMap), Attribute::Configurable);
|
||||
}
|
||||
|
||||
WeakMapPrototype::~WeakMapPrototype()
|
||||
{
|
||||
}
|
||||
|
||||
WeakMap* WeakMapPrototype::typed_this(VM& vm, GlobalObject& global_object)
|
||||
{
|
||||
auto* this_object = vm.this_value(global_object).to_object(global_object);
|
||||
if (!this_object)
|
||||
return {};
|
||||
if (!is<WeakMap>(this_object)) {
|
||||
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "WeakMap");
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<WeakMap*>(this_object);
|
||||
}
|
||||
|
||||
}
|
25
Userland/Libraries/LibJS/Runtime/WeakMapPrototype.h
Normal file
25
Userland/Libraries/LibJS/Runtime/WeakMapPrototype.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/WeakMap.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
class WeakMapPrototype final : public Object {
|
||||
JS_OBJECT(WeakMapPrototype, Object);
|
||||
|
||||
public:
|
||||
WeakMapPrototype(GlobalObject&);
|
||||
virtual void initialize(GlobalObject&) override;
|
||||
virtual ~WeakMapPrototype() override;
|
||||
|
||||
private:
|
||||
static WeakMap* typed_this(VM&, GlobalObject&);
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in a new issue