diff options
author | Timothy Flynn <trflynn89@pm.me> | 2021-08-01 19:02:19 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-04 11:18:24 +0200 |
commit | b6ff7f4fcc90fbd378cc3886ae686fd54b8e6190 (patch) | |
tree | 9cdea237057a5580bf5f52ee8beb9ec2f06badaa /Userland/Libraries/LibJS/Runtime | |
parent | 4c2cc419f964009e44330b7d1404763209f97575 (diff) | |
download | serenity-b6ff7f4fcc90fbd378cc3886ae686fd54b8e6190.zip |
LibJS: Allow PrimitiveString to be created with a UTF-16 string
PrimitiveString may currently only be created with a UTF-8 string, and
it transcodes on the fly when a UTF-16 string is needed. Allow creating
a PrimitiveString from a UTF-16 string to avoid unnecessary transcoding
when the caller only wants UTF-16.
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp | 59 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/PrimitiveString.h | 14 |
2 files changed, 61 insertions, 12 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp b/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp index bc40b4df19..1d7e74cee2 100644 --- a/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp +++ b/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp @@ -12,7 +12,14 @@ namespace JS { PrimitiveString::PrimitiveString(String string) - : m_string(move(string)) + : m_utf8_string(move(string)) + , m_has_utf8_string(true) +{ +} + +PrimitiveString::PrimitiveString(Vector<u16> string) + : m_utf16_string(move(string)) + , m_has_utf16_string(true) { } @@ -20,10 +27,21 @@ PrimitiveString::~PrimitiveString() { } +String const& PrimitiveString::string() const +{ + if (!m_has_utf8_string) { + m_utf8_string = utf16_string_view().to_utf8(Utf16View::AllowInvalidCodeUnits::Yes); + m_has_utf8_string = true; + } + return m_utf8_string; +} + Vector<u16> const& PrimitiveString::utf16_string() const { - if (m_utf16_string.is_empty() && !m_string.is_empty()) - m_utf16_string = AK::utf8_to_utf16(m_string); + if (!m_has_utf16_string) { + m_utf16_string = AK::utf8_to_utf16(m_utf8_string); + m_has_utf16_string = true; + } return m_utf16_string; } @@ -32,24 +50,45 @@ Utf16View PrimitiveString::utf16_string_view() const return Utf16View { utf16_string() }; } -PrimitiveString* js_string(Heap& heap, Utf16View const& string) +PrimitiveString* js_string(Heap& heap, Utf16View const& view) +{ + if (view.is_empty()) + return &heap.vm().empty_string(); + + if (view.length_in_code_units() == 1) { + u16 code_unit = view.code_unit_at(0); + if (is_ascii(code_unit)) + return &heap.vm().single_ascii_character_string(static_cast<u8>(code_unit)); + } + + Vector<u16> string; + string.ensure_capacity(view.length_in_code_units()); + string.append(view.data(), view.length_in_code_units()); + return js_string(heap, move(string)); +} + +PrimitiveString* js_string(VM& vm, Utf16View const& view) +{ + return js_string(vm.heap(), view); +} + +PrimitiveString* js_string(Heap& heap, Vector<u16> string) { if (string.is_empty()) return &heap.vm().empty_string(); - if (string.length_in_code_units() == 1) { - u16 code_unit = string.code_unit_at(0); + if (string.size() == 1) { + u16 code_unit = string.at(0); if (is_ascii(code_unit)) return &heap.vm().single_ascii_character_string(static_cast<u8>(code_unit)); } - auto utf8_string = string.to_utf8(Utf16View::AllowInvalidCodeUnits::Yes); - return heap.allocate_without_global_object<PrimitiveString>(move(utf8_string)); + return heap.allocate_without_global_object<PrimitiveString>(move(string)); } -PrimitiveString* js_string(VM& vm, Utf16View const& string) +PrimitiveString* js_string(VM& vm, Vector<u16> string) { - return js_string(vm.heap(), string); + return js_string(vm.heap(), move(string)); } PrimitiveString* js_string(Heap& heap, String string) diff --git a/Userland/Libraries/LibJS/Runtime/PrimitiveString.h b/Userland/Libraries/LibJS/Runtime/PrimitiveString.h index 743ab79649..945205d51f 100644 --- a/Userland/Libraries/LibJS/Runtime/PrimitiveString.h +++ b/Userland/Libraries/LibJS/Runtime/PrimitiveString.h @@ -15,9 +15,13 @@ namespace JS { class PrimitiveString final : public Cell { public: explicit PrimitiveString(String); + explicit PrimitiveString(Vector<u16>); virtual ~PrimitiveString(); - String const& string() const { return m_string; } + PrimitiveString(PrimitiveString const&) = delete; + PrimitiveString& operator=(PrimitiveString const&) = delete; + + String const& string() const; Vector<u16> const& utf16_string() const; Utf16View utf16_string_view() const; @@ -25,13 +29,19 @@ public: private: virtual const char* class_name() const override { return "PrimitiveString"; } - String m_string; + mutable String m_utf8_string; + mutable bool m_has_utf8_string { false }; + mutable Vector<u16> m_utf16_string; + mutable bool m_has_utf16_string { false }; }; PrimitiveString* js_string(Heap&, Utf16View const&); PrimitiveString* js_string(VM&, Utf16View const&); +PrimitiveString* js_string(Heap&, Vector<u16>); +PrimitiveString* js_string(VM&, Vector<u16>); + PrimitiveString* js_string(Heap&, String); PrimitiveString* js_string(VM&, String); |