PrimitiveString.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/CharacterTypes.h>
  7. #include <AK/Utf16View.h>
  8. #include <LibJS/Runtime/PrimitiveString.h>
  9. #include <LibJS/Runtime/VM.h>
  10. namespace JS {
  11. PrimitiveString::PrimitiveString(String string)
  12. : m_utf8_string(move(string))
  13. , m_has_utf8_string(true)
  14. {
  15. }
  16. PrimitiveString::PrimitiveString(Utf16String string)
  17. : m_utf16_string(move(string))
  18. , m_has_utf16_string(true)
  19. {
  20. }
  21. PrimitiveString::~PrimitiveString()
  22. {
  23. vm().string_cache().remove(m_utf8_string);
  24. }
  25. String const& PrimitiveString::string() const
  26. {
  27. if (!m_has_utf8_string) {
  28. m_utf8_string = m_utf16_string.to_utf8();
  29. m_has_utf8_string = true;
  30. }
  31. return m_utf8_string;
  32. }
  33. Utf16String const& PrimitiveString::utf16_string() const
  34. {
  35. if (!m_has_utf16_string) {
  36. m_utf16_string = Utf16String(m_utf8_string);
  37. m_has_utf16_string = true;
  38. }
  39. return m_utf16_string;
  40. }
  41. Utf16View PrimitiveString::utf16_string_view() const
  42. {
  43. return utf16_string().view();
  44. }
  45. PrimitiveString* js_string(Heap& heap, Utf16View const& view)
  46. {
  47. return js_string(heap, Utf16String(view));
  48. }
  49. PrimitiveString* js_string(VM& vm, Utf16View const& view)
  50. {
  51. return js_string(vm.heap(), view);
  52. }
  53. PrimitiveString* js_string(Heap& heap, Utf16String string)
  54. {
  55. if (string.is_empty())
  56. return &heap.vm().empty_string();
  57. if (string.length_in_code_units() == 1) {
  58. u16 code_unit = string.code_unit_at(0);
  59. if (is_ascii(code_unit))
  60. return &heap.vm().single_ascii_character_string(static_cast<u8>(code_unit));
  61. }
  62. return heap.allocate_without_global_object<PrimitiveString>(move(string));
  63. }
  64. PrimitiveString* js_string(VM& vm, Utf16String string)
  65. {
  66. return js_string(vm.heap(), move(string));
  67. }
  68. PrimitiveString* js_string(Heap& heap, String string)
  69. {
  70. if (string.is_empty())
  71. return &heap.vm().empty_string();
  72. if (string.length() == 1) {
  73. auto ch = static_cast<u8>(string.characters()[0]);
  74. if (is_ascii(ch))
  75. return &heap.vm().single_ascii_character_string(ch);
  76. }
  77. auto& string_cache = heap.vm().string_cache();
  78. auto it = string_cache.find(string);
  79. if (it == string_cache.end()) {
  80. auto* new_string = heap.allocate_without_global_object<PrimitiveString>(string);
  81. string_cache.set(move(string), new_string);
  82. return new_string;
  83. }
  84. return it->value;
  85. }
  86. PrimitiveString* js_string(VM& vm, String string)
  87. {
  88. return js_string(vm.heap(), move(string));
  89. }
  90. }