/src/serenity/Userland/Libraries/LibJS/Runtime/Map.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <LibJS/Runtime/Map.h> |
8 | | |
9 | | namespace JS { |
10 | | |
11 | | JS_DEFINE_ALLOCATOR(Map); |
12 | | |
13 | | NonnullGCPtr<Map> Map::create(Realm& realm) |
14 | 0 | { |
15 | 0 | return realm.heap().allocate<Map>(realm, realm.intrinsics().map_prototype()); |
16 | 0 | } |
17 | | |
18 | | Map::Map(Object& prototype) |
19 | 0 | : Object(ConstructWithPrototypeTag::Tag, prototype) |
20 | 0 | { |
21 | 0 | } |
22 | | |
23 | | // 24.1.3.1 Map.prototype.clear ( ), https://tc39.es/ecma262/#sec-map.prototype.clear |
24 | | void Map::map_clear() |
25 | 0 | { |
26 | 0 | m_keys.clear(); |
27 | 0 | m_entries.clear(); |
28 | 0 | } |
29 | | |
30 | | // 24.1.3.3 Map.prototype.delete ( key ), https://tc39.es/ecma262/#sec-map.prototype.delete |
31 | | bool Map::map_remove(Value const& key) |
32 | 0 | { |
33 | 0 | Optional<size_t> index; |
34 | |
|
35 | 0 | for (auto it = m_keys.begin(); !it.is_end(); ++it) { |
36 | 0 | if (ValueTraits::equals(*it, key)) { |
37 | 0 | index = it.key(); |
38 | 0 | break; |
39 | 0 | } |
40 | 0 | } |
41 | |
|
42 | 0 | if (!index.has_value()) |
43 | 0 | return false; |
44 | | |
45 | 0 | m_keys.remove(*index); |
46 | 0 | m_entries.remove(key); |
47 | 0 | return true; |
48 | 0 | } |
49 | | |
50 | | // 24.1.3.6 Map.prototype.get ( key ), https://tc39.es/ecma262/#sec-map.prototype.get |
51 | | Optional<Value> Map::map_get(Value const& key) const |
52 | 0 | { |
53 | 0 | if (auto it = m_entries.find(key); it != m_entries.end()) |
54 | 0 | return it->value; |
55 | 0 | return {}; |
56 | 0 | } |
57 | | |
58 | | // 24.1.3.7 Map.prototype.has ( key ), https://tc39.es/ecma262/#sec-map.prototype.has |
59 | | bool Map::map_has(Value const& key) const |
60 | 0 | { |
61 | 0 | return m_entries.contains(key); |
62 | 0 | } |
63 | | |
64 | | // 24.1.3.9 Map.prototype.set ( key, value ), https://tc39.es/ecma262/#sec-map.prototype.set |
65 | | void Map::map_set(Value const& key, Value value) |
66 | 0 | { |
67 | 0 | auto it = m_entries.find(key); |
68 | 0 | if (it != m_entries.end()) { |
69 | 0 | it->value = value; |
70 | 0 | } else { |
71 | 0 | auto index = m_next_insertion_id++; |
72 | 0 | m_keys.insert(index, key); |
73 | 0 | m_entries.set(key, value); |
74 | 0 | } |
75 | 0 | } |
76 | | |
77 | | size_t Map::map_size() const |
78 | 0 | { |
79 | 0 | return m_keys.size(); |
80 | 0 | } |
81 | | |
82 | | void Map::visit_edges(Cell::Visitor& visitor) |
83 | 0 | { |
84 | 0 | Base::visit_edges(visitor); |
85 | 0 | for (auto& value : m_entries) { |
86 | 0 | visitor.visit(value.key); |
87 | 0 | visitor.visit(value.value); |
88 | 0 | } |
89 | | // NOTE: The entries in m_keys are already visited by the walk over m_entries above. |
90 | 0 | visitor.ignore(m_keys); |
91 | 0 | } |
92 | | |
93 | | } |