Map.cpp 2.0 KB

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