| 
									
										
										
										
											2021-06-12 23:54:40 +03:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <LibJS/Runtime/Map.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace JS { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-13 20:49:50 +00:00
										 |  |  | NonnullGCPtr<Map> Map::create(Realm& realm) | 
					
						
							| 
									
										
										
										
											2021-06-12 23:54:40 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-04-13 00:47:15 +02:00
										 |  |  |     return realm.heap().allocate<Map>(realm, realm.intrinsics().map_prototype()).release_allocated_value_but_fixme_should_propagate_errors(); | 
					
						
							| 
									
										
										
										
											2021-06-12 23:54:40 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Map::Map(Object& prototype) | 
					
						
							| 
									
										
										
										
											2022-12-14 12:17:58 +01:00
										 |  |  |     : Object(ConstructWithPrototypeTag::Tag, prototype) | 
					
						
							| 
									
										
										
										
											2021-06-12 23:54:40 +03:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-09 16:34:52 +03:30
										 |  |  | // 24.1.3.1 Map.prototype.clear ( ), https://tc39.es/ecma262/#sec-map.prototype.clear
 | 
					
						
							|  |  |  | void Map::map_clear() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_keys.clear(); | 
					
						
							|  |  |  |     m_entries.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 24.1.3.3 Map.prototype.delete ( key ), https://tc39.es/ecma262/#sec-map.prototype.delete
 | 
					
						
							|  |  |  | bool Map::map_remove(Value const& key) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Optional<size_t> index; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-10 11:13:53 +01:00
										 |  |  |     for (auto it = m_keys.begin(); !it.is_end(); ++it) { | 
					
						
							| 
									
										
										
										
											2022-02-09 16:34:52 +03:30
										 |  |  |         if (ValueTraits::equals(*it, key)) { | 
					
						
							|  |  |  |             index = it.key(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!index.has_value()) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_keys.remove(*index); | 
					
						
							|  |  |  |     m_entries.remove(key); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 24.1.3.6 Map.prototype.get ( key ), https://tc39.es/ecma262/#sec-map.prototype.get
 | 
					
						
							|  |  |  | Optional<Value> Map::map_get(Value const& key) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (auto it = m_entries.find(key); it != m_entries.end()) | 
					
						
							|  |  |  |         return it->value; | 
					
						
							|  |  |  |     return {}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 24.1.3.7 Map.prototype.has ( key ), https://tc39.es/ecma262/#sec-map.prototype.has
 | 
					
						
							|  |  |  | bool Map::map_has(Value const& key) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_entries.contains(key); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 24.1.3.9 Map.prototype.set ( key, value ), https://tc39.es/ecma262/#sec-map.prototype.set
 | 
					
						
							|  |  |  | void Map::map_set(Value const& key, Value value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto it = m_entries.find(key); | 
					
						
							|  |  |  |     if (it != m_entries.end()) { | 
					
						
							|  |  |  |         it->value = value; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         auto index = m_next_insertion_id++; | 
					
						
							|  |  |  |         m_keys.insert(index, key); | 
					
						
							|  |  |  |         m_entries.set(key, value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | size_t Map::map_size() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_keys.size(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-12 23:54:40 +03:00
										 |  |  | void Map::visit_edges(Cell::Visitor& visitor) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-11 14:05:12 +02:00
										 |  |  |     Base::visit_edges(visitor); | 
					
						
							| 
									
										
										
										
											2021-06-12 23:54:40 +03:00
										 |  |  |     for (auto& value : m_entries) { | 
					
						
							|  |  |  |         visitor.visit(value.key); | 
					
						
							|  |  |  |         visitor.visit(value.value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |