Map.cpp 2.0 KB

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