diff --git a/AK/Assertions.cpp b/AK/Assertions.cpp index b4ddb26a77..1d695929b1 100644 --- a/AK/Assertions.cpp +++ b/AK/Assertions.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -49,8 +50,8 @@ void dump_backtrace(unsigned frames_to_skip, unsigned max_depth) auto stacktrace = cpptrace::generate_trace(frames_to_skip, max_depth); auto* var = getenv("LADYBIRD_BACKTRACE_SNIPPETS"); bool print_snippets = var && strnlen(var, 1) > 0; - static auto formatter = cpptrace::formatter {}.snippets(print_snippets); - auto string = formatter.format(stacktrace, true); + static NeverDestroyed formatter { cpptrace::formatter {}.snippets(print_snippets) }; + auto string = formatter->format(stacktrace, true); warnln("{}", StringView { string.c_str(), string.length() }); } #elif defined(AK_HAS_BACKTRACE_HEADER) diff --git a/Libraries/LibCompress/Deflate.cpp b/Libraries/LibCompress/Deflate.cpp index dece3cc77b..797bf9471d 100644 --- a/Libraries/LibCompress/Deflate.cpp +++ b/Libraries/LibCompress/Deflate.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include @@ -16,30 +17,14 @@ namespace Compress { CanonicalCode const& CanonicalCode::fixed_literal_codes() { - static CanonicalCode code; - static bool initialized = false; - - if (initialized) - return code; - - code = MUST(CanonicalCode::from_bytes(fixed_literal_bit_lengths)); - initialized = true; - - return code; + static NeverDestroyed code { MUST(CanonicalCode::from_bytes(fixed_literal_bit_lengths)) }; + return *code; } CanonicalCode const& CanonicalCode::fixed_distance_codes() { - static CanonicalCode code; - static bool initialized = false; - - if (initialized) - return code; - - code = MUST(CanonicalCode::from_bytes(fixed_distance_bit_lengths)); - initialized = true; - - return code; + static NeverDestroyed code { MUST(CanonicalCode::from_bytes(fixed_distance_bit_lengths)) }; + return *code; } ErrorOr CanonicalCode::from_bytes(ReadonlyBytes bytes) diff --git a/Libraries/LibCore/EventLoop.cpp b/Libraries/LibCore/EventLoop.cpp index af901097b6..5f14fdf43d 100644 --- a/Libraries/LibCore/EventLoop.cpp +++ b/Libraries/LibCore/EventLoop.cpp @@ -6,28 +6,58 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include +#include #include #include #include #include #include #include +#ifndef AK_OS_WINDOWS +# include +#endif namespace Core { namespace { -OwnPtr>& event_loop_stack_uninitialized() +#ifndef AK_OS_WINDOWS +static pthread_key_t s_event_loop_stack_key; +static pthread_once_t s_event_loop_stack_key_once = PTHREAD_ONCE_INIT; + +static void destroy_event_loop_stack(void* value) { - thread_local OwnPtr> s_event_loop_stack = nullptr; + delete static_cast*>(value); +} + +static void initialize_event_loop_stack_key() +{ + VERIFY(pthread_key_create(&s_event_loop_stack_key, destroy_event_loop_stack) == 0); +} + +static void ensure_event_loop_stack_key() +{ + VERIFY(pthread_once(&s_event_loop_stack_key_once, initialize_event_loop_stack_key) == 0); +} +#endif + +Vector*& event_loop_stack_uninitialized() +{ + thread_local Vector* s_event_loop_stack = nullptr; return s_event_loop_stack; } Vector& event_loop_stack() { auto& the_stack = event_loop_stack_uninitialized(); - if (the_stack == nullptr) - the_stack = make>(); + if (the_stack == nullptr) { + the_stack = new Vector(); +#ifndef AK_OS_WINDOWS + ensure_event_loop_stack_key(); + VERIFY(pthread_setspecific(s_event_loop_stack_key, the_stack) == 0); +#endif + } return *the_stack; } diff --git a/Libraries/LibCore/EventLoopImplementationUnix.cpp b/Libraries/LibCore/EventLoopImplementationUnix.cpp index 1faef79f0a..bcc917b43f 100644 --- a/Libraries/LibCore/EventLoopImplementationUnix.cpp +++ b/Libraries/LibCore/EventLoopImplementationUnix.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -30,10 +32,35 @@ namespace { struct ThreadData; class TimeoutSet; -HashMap s_thread_data; -Sync::RWLock s_thread_data_lock; -thread_local pthread_t s_thread_id; -thread_local OwnPtr s_this_thread_data; +thread_local ThreadData* s_this_thread_data; +static pthread_key_t s_this_thread_data_key; + +static void destroy_thread_data(void*); + +static auto& thread_data() +{ + static NeverDestroyed> thread_data; + return *thread_data; +} + +static auto& thread_data_lock() +{ + static NeverDestroyed lock; + return *lock; +} + +static auto& thread_data_key_once() +{ + static NeverDestroyed once; + return *once; +} + +static void ensure_thread_data_key() +{ + Sync::call_once(thread_data_key_once(), [] { + VERIFY(pthread_key_create(&s_this_thread_data_key, destroy_thread_data) == 0); + }); +} short notification_type_to_poll_events(NotificationType type) { @@ -224,29 +251,30 @@ public: struct ThreadData { static ThreadData& the() { - if (s_thread_id == 0) - s_thread_id = pthread_self(); + ensure_thread_data_key(); ThreadData* data = nullptr; if (!s_this_thread_data) { data = new ThreadData; - s_this_thread_data = adopt_own(*data); + s_this_thread_data = data; + VERIFY(pthread_setspecific(s_this_thread_data_key, s_this_thread_data) == 0); - Sync::RWLockLocker locker(s_thread_data_lock); - s_thread_data.set(s_thread_id, s_this_thread_data.ptr()); + Sync::RWLockLocker locker(thread_data_lock()); + thread_data().set(s_this_thread_data->thread_id, s_this_thread_data); } else { - data = s_this_thread_data.ptr(); + data = s_this_thread_data; } return *data; } static ThreadData* for_thread(pthread_t thread_id) { - // NOTE: s_thread_data_lock is supposed to be held by the caller. - return s_thread_data.get(thread_id).value_or(nullptr); + // NOTE: thread_data_lock() is supposed to be held by the caller. + return thread_data().get(thread_id).value_or(nullptr); } ThreadData() { + thread_id = pthread_self(); pid = getpid(); auto result = Core::System::pipe2(O_CLOEXEC); @@ -267,8 +295,8 @@ struct ThreadData { close(wake_pipe_fds[0]); close(wake_pipe_fds[1]); - Sync::RWLockLocker locker(s_thread_data_lock); - s_thread_data.remove(s_thread_id); + Sync::RWLockLocker locker(thread_data_lock()); + thread_data().remove(thread_id); } Sync::RecursiveMutex mutex; @@ -285,8 +313,15 @@ struct ThreadData { Array wake_pipe_fds { -1, -1 }; pid_t pid { 0 }; + pthread_t thread_id { 0 }; }; +static void destroy_thread_data(void* value) +{ + s_this_thread_data = nullptr; + delete static_cast(value); +} + } EventLoopImplementationUnix::EventLoopImplementationUnix() @@ -569,7 +604,7 @@ void EventLoopManagerUnix::handle_signal(int signal_number) VERIFY(signal_number != 0); // Use the thread-local directly instead of ThreadData::the() to avoid - // taking a write lock on s_thread_data_lock. Signal handlers must not + // taking a write lock on thread_data_lock(). Signal handlers must not // acquire locks, as we may already be holding one on this thread. if (!s_this_thread_data) return; @@ -628,7 +663,7 @@ intptr_t EventLoopManagerUnix::register_timer(EventReceiver& object, int millise auto& thread_data = ThreadData::the(); Sync::MutexLocker locker(thread_data.mutex); auto timer = new EventLoopTimer; - timer->owner_thread = s_thread_id; + timer->owner_thread = thread_data.thread_id; timer->owner = object; timer->interval = AK::Duration::from_milliseconds(milliseconds); timer->reload(MonotonicTime::now_coarse()); @@ -640,7 +675,7 @@ intptr_t EventLoopManagerUnix::register_timer(EventReceiver& object, int millise void EventLoopManagerUnix::unregister_timer(intptr_t timer_id) { auto* timer = bit_cast(timer_id); - Sync::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(thread_data_lock()); auto* thread_data_ptr = ThreadData::for_thread(timer->owner_thread); if (!thread_data_ptr) return; @@ -665,12 +700,12 @@ void EventLoopManagerUnix::register_notifier(Notifier& notifier) auto events = notification_type_to_poll_events(notifier.type()); thread_data.poll_fds.append({ .fd = notifier.fd(), .events = events, .revents = 0 }); - notifier.set_owner_thread(s_thread_id); + notifier.set_owner_thread(thread_data.thread_id); } void EventLoopManagerUnix::unregister_notifier(Notifier& notifier) { - Sync::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(thread_data_lock()); auto* thread_data = ThreadData::for_thread(notifier.owner_thread()); if (!thread_data) return; diff --git a/Libraries/LibCore/MimeData.cpp b/Libraries/LibCore/MimeData.cpp index 2d36541a75..899cca922c 100644 --- a/Libraries/LibCore/MimeData.cpp +++ b/Libraries/LibCore/MimeData.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -65,91 +66,100 @@ static Array constexpr s_plaintext_suffixes = { // See https://www.iana.org/assignments/media-types/ for a list of registered MIME types. // For example, https://www.iana.org/assignments/media-types/application/gzip -static Array const s_registered_mime_type = { - MimeType { .name = "application/gzip"sv, .common_extensions = { ".gz"sv, ".gzip"sv }, .description = "GZIP compressed data"sv, .magic_bytes = Vector { 0x1F, 0x8B } }, - MimeType { .name = "application/javascript"sv, .common_extensions = { ".js"sv, ".mjs"sv }, .description = "JavaScript source"sv }, - MimeType { .name = "application/json"sv, .common_extensions = { ".json"sv }, .description = "JSON data"sv }, - MimeType { .name = "application/pdf"sv, .common_extensions = { ".pdf"sv }, .description = "PDF document"sv, .magic_bytes = Vector { 0x25, 'P', 'D', 'F', 0x2D } }, - MimeType { .name = "application/rtf"sv, .common_extensions = { ".rtf"sv }, .description = "Rich text file"sv, .magic_bytes = Vector { 0x7B, 0x5C, 0x72, 0x74, 0x66, 0x31 } }, - MimeType { .name = "application/tar"sv, .common_extensions = { ".tar"sv }, .description = "Tape archive"sv, .magic_bytes = Vector { 0x75, 0x73, 0x74, 0x61, 0x72 }, .offset = 0x101 }, - MimeType { .name = "application/vnd.iccprofile"sv, .common_extensions = { ".icc"sv }, .description = "ICC color profile"sv, .magic_bytes = Vector { 'a', 'c', 's', 'p' }, .offset = 36 }, - MimeType { .name = "application/vnd.sqlite3"sv, .common_extensions = { ".sqlite"sv }, .description = "SQLite database"sv, .magic_bytes = Vector { 'S', 'Q', 'L', 'i', 't', 'e', ' ', 'f', 'o', 'r', 'm', 'a', 't', ' ', '3', 0x00 } }, - MimeType { .name = "application/wasm"sv, .common_extensions = { ".wasm"sv }, .description = "WebAssembly bytecode"sv, .magic_bytes = Vector { 0x00, 'a', 's', 'm' } }, - MimeType { .name = "application/x-7z-compressed"sv, .common_extensions = { "7z"sv }, .description = "7-Zip archive"sv, .magic_bytes = Vector { 0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C } }, - MimeType { .name = "application/x-blender"sv, .common_extensions = { ".blend"sv, ".blended"sv }, .description = "Blender project file"sv, .magic_bytes = Vector { 'B', 'L', 'E', 'N', 'D', 'E', 'R' } }, - MimeType { .name = "application/x-bzip2"sv, .common_extensions = { ".bz2"sv }, .description = "BZIP2 compressed data"sv, .magic_bytes = Vector { 'B', 'Z', 'h' } }, - MimeType { .name = "application/x-sheets+json"sv, .common_extensions = { ".sheets"sv }, .description = "Serenity Spreadsheet document"sv }, - MimeType { .name = "application/xhtml+xml"sv, .common_extensions = { ".xhtml"sv, ".xht"sv }, .description = "XHTML document"sv }, - MimeType { .name = "application/zip"sv, .common_extensions = { ".zip"sv }, .description = "ZIP archive"sv, .magic_bytes = Vector { 0x50, 0x4B } }, +static auto make_registered_mime_types() +{ + return Array { + MimeType { .name = "application/gzip"sv, .common_extensions = { ".gz"sv, ".gzip"sv }, .description = "GZIP compressed data"sv, .magic_bytes = Vector { 0x1F, 0x8B } }, + MimeType { .name = "application/javascript"sv, .common_extensions = { ".js"sv, ".mjs"sv }, .description = "JavaScript source"sv }, + MimeType { .name = "application/json"sv, .common_extensions = { ".json"sv }, .description = "JSON data"sv }, + MimeType { .name = "application/pdf"sv, .common_extensions = { ".pdf"sv }, .description = "PDF document"sv, .magic_bytes = Vector { 0x25, 'P', 'D', 'F', 0x2D } }, + MimeType { .name = "application/rtf"sv, .common_extensions = { ".rtf"sv }, .description = "Rich text file"sv, .magic_bytes = Vector { 0x7B, 0x5C, 0x72, 0x74, 0x66, 0x31 } }, + MimeType { .name = "application/tar"sv, .common_extensions = { ".tar"sv }, .description = "Tape archive"sv, .magic_bytes = Vector { 0x75, 0x73, 0x74, 0x61, 0x72 }, .offset = 0x101 }, + MimeType { .name = "application/vnd.iccprofile"sv, .common_extensions = { ".icc"sv }, .description = "ICC color profile"sv, .magic_bytes = Vector { 'a', 'c', 's', 'p' }, .offset = 36 }, + MimeType { .name = "application/vnd.sqlite3"sv, .common_extensions = { ".sqlite"sv }, .description = "SQLite database"sv, .magic_bytes = Vector { 'S', 'Q', 'L', 'i', 't', 'e', ' ', 'f', 'o', 'r', 'm', 'a', 't', ' ', '3', 0x00 } }, + MimeType { .name = "application/wasm"sv, .common_extensions = { ".wasm"sv }, .description = "WebAssembly bytecode"sv, .magic_bytes = Vector { 0x00, 'a', 's', 'm' } }, + MimeType { .name = "application/x-7z-compressed"sv, .common_extensions = { "7z"sv }, .description = "7-Zip archive"sv, .magic_bytes = Vector { 0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C } }, + MimeType { .name = "application/x-blender"sv, .common_extensions = { ".blend"sv, ".blended"sv }, .description = "Blender project file"sv, .magic_bytes = Vector { 'B', 'L', 'E', 'N', 'D', 'E', 'R' } }, + MimeType { .name = "application/x-bzip2"sv, .common_extensions = { ".bz2"sv }, .description = "BZIP2 compressed data"sv, .magic_bytes = Vector { 'B', 'Z', 'h' } }, + MimeType { .name = "application/x-sheets+json"sv, .common_extensions = { ".sheets"sv }, .description = "Serenity Spreadsheet document"sv }, + MimeType { .name = "application/xhtml+xml"sv, .common_extensions = { ".xhtml"sv, ".xht"sv }, .description = "XHTML document"sv }, + MimeType { .name = "application/zip"sv, .common_extensions = { ".zip"sv }, .description = "ZIP archive"sv, .magic_bytes = Vector { 0x50, 0x4B } }, - MimeType { .name = "audio/flac"sv, .common_extensions = { ".flac"sv }, .description = "FLAC audio"sv, .magic_bytes = Vector { 'f', 'L', 'a', 'C' } }, - MimeType { .name = "audio/midi"sv, .common_extensions = { ".mid"sv }, .description = "MIDI notes"sv, .magic_bytes = Vector { 0x4D, 0x54, 0x68, 0x64 } }, - MimeType { .name = "audio/mpeg"sv, .common_extensions = { ".mp3"sv }, .description = "MP3 audio"sv, .magic_bytes = Vector { 0xFF, 0xFB } }, - MimeType { .name = "audio/qoa"sv, .common_extensions = { ".qoa"sv }, .description = "Quite OK Audio"sv, .magic_bytes = Vector { 'q', 'o', 'a', 'f' } }, - MimeType { .name = "audio/wav"sv, .common_extensions = { ".wav"sv }, .description = "WAVE audio"sv, .magic_bytes = Vector { 'W', 'A', 'V', 'E' }, .offset = 8 }, + MimeType { .name = "audio/flac"sv, .common_extensions = { ".flac"sv }, .description = "FLAC audio"sv, .magic_bytes = Vector { 'f', 'L', 'a', 'C' } }, + MimeType { .name = "audio/midi"sv, .common_extensions = { ".mid"sv }, .description = "MIDI notes"sv, .magic_bytes = Vector { 0x4D, 0x54, 0x68, 0x64 } }, + MimeType { .name = "audio/mpeg"sv, .common_extensions = { ".mp3"sv }, .description = "MP3 audio"sv, .magic_bytes = Vector { 0xFF, 0xFB } }, + MimeType { .name = "audio/qoa"sv, .common_extensions = { ".qoa"sv }, .description = "Quite OK Audio"sv, .magic_bytes = Vector { 'q', 'o', 'a', 'f' } }, + MimeType { .name = "audio/wav"sv, .common_extensions = { ".wav"sv }, .description = "WAVE audio"sv, .magic_bytes = Vector { 'W', 'A', 'V', 'E' }, .offset = 8 }, - MimeType { .name = "extra/elf"sv, .common_extensions = { ".elf"sv }, .description = "ELF"sv, .magic_bytes = Vector { 0x7F, 'E', 'L', 'F' } }, - MimeType { .name = "extra/ext"sv, .description = "EXT filesystem"sv, .magic_bytes = Vector { 0x53, 0xEF }, .offset = 0x438 }, - MimeType { .name = "extra/iso-9660"sv, .common_extensions = { ".iso"sv }, .description = "ISO 9660 CD/DVD image"sv, .magic_bytes = Vector { 0x43, 0x44, 0x30, 0x30, 0x31 }, .offset = 0x8001 }, - MimeType { .name = "extra/iso-9660"sv, .common_extensions = { ".iso"sv }, .description = "ISO 9660 CD/DVD image"sv, .magic_bytes = Vector { 0x43, 0x44, 0x30, 0x30, 0x31 }, .offset = 0x8801 }, - MimeType { .name = "extra/iso-9660"sv, .common_extensions = { ".iso"sv }, .description = "ISO 9660 CD/DVD image"sv, .magic_bytes = Vector { 0x43, 0x44, 0x30, 0x30, 0x31 }, .offset = 0x9001 }, - MimeType { .name = "extra/isz"sv, .common_extensions = { ".isz"sv }, .description = "Compressed ISO image"sv, .magic_bytes = Vector { 'I', 's', 'Z', '!' } }, - MimeType { .name = "extra/lua-bytecode"sv, .description = "Lua bytecode"sv, .magic_bytes = Vector { 0x1B, 'L', 'u', 'a' } }, - MimeType { .name = "extra/nes-rom"sv, .common_extensions = { ".nes"sv }, .description = "Nintendo Entertainment System ROM"sv, .magic_bytes = Vector { 'N', 'E', 'S', 0x1A } }, - MimeType { .name = "extra/qcow"sv, .common_extensions = { ".qcow"sv, ".qcow2"sv, ".qcow3"sv }, .description = "QCOW file"sv, .magic_bytes = Vector { 'Q', 'F', 'I' } }, - MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0x01 } }, - MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0x5E } }, - MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0x9C } }, - MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0xDA } }, - MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0x20 } }, - MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0x7D } }, - MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0xBB } }, - MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0xF9 } }, - MimeType { .name = "extra/win-31x-compressed"sv, .description = "Windows 3.1X compressed file"sv, .magic_bytes = Vector { 'K', 'W', 'A', 'J' } }, - MimeType { .name = "extra/win-95-compressed"sv, .description = "Windows 95 compressed file"sv, .magic_bytes = Vector { 'S', 'Z', 'D', 'D' } }, + MimeType { .name = "extra/elf"sv, .common_extensions = { ".elf"sv }, .description = "ELF"sv, .magic_bytes = Vector { 0x7F, 'E', 'L', 'F' } }, + MimeType { .name = "extra/ext"sv, .description = "EXT filesystem"sv, .magic_bytes = Vector { 0x53, 0xEF }, .offset = 0x438 }, + MimeType { .name = "extra/iso-9660"sv, .common_extensions = { ".iso"sv }, .description = "ISO 9660 CD/DVD image"sv, .magic_bytes = Vector { 0x43, 0x44, 0x30, 0x30, 0x31 }, .offset = 0x8001 }, + MimeType { .name = "extra/iso-9660"sv, .common_extensions = { ".iso"sv }, .description = "ISO 9660 CD/DVD image"sv, .magic_bytes = Vector { 0x43, 0x44, 0x30, 0x30, 0x31 }, .offset = 0x8801 }, + MimeType { .name = "extra/iso-9660"sv, .common_extensions = { ".iso"sv }, .description = "ISO 9660 CD/DVD image"sv, .magic_bytes = Vector { 0x43, 0x44, 0x30, 0x30, 0x31 }, .offset = 0x9001 }, + MimeType { .name = "extra/isz"sv, .common_extensions = { ".isz"sv }, .description = "Compressed ISO image"sv, .magic_bytes = Vector { 'I', 's', 'Z', '!' } }, + MimeType { .name = "extra/lua-bytecode"sv, .description = "Lua bytecode"sv, .magic_bytes = Vector { 0x1B, 'L', 'u', 'a' } }, + MimeType { .name = "extra/nes-rom"sv, .common_extensions = { ".nes"sv }, .description = "Nintendo Entertainment System ROM"sv, .magic_bytes = Vector { 'N', 'E', 'S', 0x1A } }, + MimeType { .name = "extra/qcow"sv, .common_extensions = { ".qcow"sv, ".qcow2"sv, ".qcow3"sv }, .description = "QCOW file"sv, .magic_bytes = Vector { 'Q', 'F', 'I' } }, + MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0x01 } }, + MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0x5E } }, + MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0x9C } }, + MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0xDA } }, + MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0x20 } }, + MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0x7D } }, + MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0xBB } }, + MimeType { .name = "extra/raw-zlib"sv, .description = "Raw zlib stream"sv, .magic_bytes = Vector { 0x78, 0xF9 } }, + MimeType { .name = "extra/win-31x-compressed"sv, .description = "Windows 3.1X compressed file"sv, .magic_bytes = Vector { 'K', 'W', 'A', 'J' } }, + MimeType { .name = "extra/win-95-compressed"sv, .description = "Windows 95 compressed file"sv, .magic_bytes = Vector { 'S', 'Z', 'D', 'D' } }, - MimeType { .name = "font/otf"sv, .common_extensions = { "otf"sv }, .description = "OpenType font"sv, .magic_bytes = Vector { 'O', 'T', 'T', 'F' } }, - MimeType { .name = "font/ttf"sv, .common_extensions = { "ttf"sv }, .description = "TrueType font"sv, .magic_bytes = Vector { 0x00, 0x01, 0x00, 0x00, 0x00 } }, - MimeType { .name = "font/woff"sv, .common_extensions = { "woff"sv }, .description = "WOFF font"sv, .magic_bytes = Vector { 'W', 'O', 'F', 'F' } }, - MimeType { .name = "font/woff2"sv, .common_extensions = { "woff2"sv }, .description = "WOFF2 font"sv, .magic_bytes = Vector { 'W', 'O', 'F', '2' } }, + MimeType { .name = "font/otf"sv, .common_extensions = { "otf"sv }, .description = "OpenType font"sv, .magic_bytes = Vector { 'O', 'T', 'T', 'F' } }, + MimeType { .name = "font/ttf"sv, .common_extensions = { "ttf"sv }, .description = "TrueType font"sv, .magic_bytes = Vector { 0x00, 0x01, 0x00, 0x00, 0x00 } }, + MimeType { .name = "font/woff"sv, .common_extensions = { "woff"sv }, .description = "WOFF font"sv, .magic_bytes = Vector { 'W', 'O', 'F', 'F' } }, + MimeType { .name = "font/woff2"sv, .common_extensions = { "woff2"sv }, .description = "WOFF2 font"sv, .magic_bytes = Vector { 'W', 'O', 'F', '2' } }, - MimeType { .name = "image/avif"sv, .common_extensions = { ".avif"sv }, .description = "AVIF image data"sv }, - MimeType { .name = "image/bmp"sv, .common_extensions = { ".bmp"sv }, .description = "BMP image data"sv, .magic_bytes = Vector { 'B', 'M' } }, - MimeType { .name = "image/gif"sv, .common_extensions = { ".gif"sv }, .description = "GIF image data"sv, .magic_bytes = Vector { 'G', 'I', 'F', '8', '7', 'a' } }, - MimeType { .name = "image/gif"sv, .common_extensions = { ".gif"sv }, .description = "GIF image data"sv, .magic_bytes = Vector { 'G', 'I', 'F', '8', '9', 'a' } }, - MimeType { .name = "image/j2c"sv, .common_extensions = { ".j2c"sv, ".j2k"sv }, .description = "JPEG2000 image data codestream"sv, .magic_bytes = Vector { 0xFF, 0x4F, 0xFF, 0x51 } }, - MimeType { .name = "image/jp2"sv, .common_extensions = { ".jp2"sv, ".jpf"sv, ".jpx"sv }, .description = "JPEG2000 image data"sv, .magic_bytes = Vector { 0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A } }, - MimeType { .name = "image/jpeg"sv, .common_extensions = { ".jpg"sv, ".jpeg"sv }, .description = "JPEG image data"sv, .magic_bytes = Vector { 0xFF, 0xD8, 0xFF } }, - MimeType { .name = "image/jxl"sv, .common_extensions = { ".jxl"sv }, .description = "JPEG XL image data"sv, .magic_bytes = Vector { 0xFF, 0x0A } }, - MimeType { .name = "image/png"sv, .common_extensions = { ".png"sv }, .description = "PNG image data"sv, .magic_bytes = Vector { 0x89, 'P', 'N', 'G', 0x0D, 0x0A, 0x1A, 0x0A } }, - MimeType { .name = "image/svg+xml"sv, .common_extensions = { ".svg"sv }, .description = "Scalable Vector Graphics image"sv }, - MimeType { .name = "image/tiff"sv, .common_extensions = { ".tiff"sv }, .description = "TIFF image data"sv, .magic_bytes = Vector { 'I', 'I', '*', 0x00 } }, - MimeType { .name = "image/tiff"sv, .common_extensions = { ".tiff"sv }, .description = "TIFF image data"sv, .magic_bytes = Vector { 'M', 'M', 0x00, '*' } }, - MimeType { .name = "image/webp"sv, .common_extensions = { ".webp"sv }, .description = "WebP image data"sv, .magic_bytes = Vector { 'W', 'E', 'B', 'P' }, .offset = 8 }, - MimeType { .name = "image/x-icon"sv, .common_extensions = { ".ico"sv }, .description = "ICO image data"sv }, - MimeType { .name = "image/x-ilbm"sv, .common_extensions = { ".iff"sv, ".lbm"sv }, .description = "Interleaved bitmap image data"sv, .magic_bytes = Vector { 0x46, 0x4F, 0x52, 0x4F } }, - MimeType { .name = "image/x-jbig2"sv, .common_extensions = { ".jbig2"sv, ".jb2"sv }, .description = "JBIG2 image data"sv, .magic_bytes = Vector { 0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A } }, - MimeType { .name = "image/x-portable-arbitrarymap"sv, .common_extensions = { ".pam"sv }, .description = "PAM image data"sv, .magic_bytes = Vector { 0x50, 0x37, 0x0A } }, - MimeType { .name = "image/x-portable-bitmap"sv, .common_extensions = { ".pbm"sv }, .description = "PBM image data"sv, .magic_bytes = Vector { 0x50, 0x31, 0x0A } }, - MimeType { .name = "image/x-portable-graymap"sv, .common_extensions = { ".pgm"sv }, .description = "PGM image data"sv, .magic_bytes = Vector { 0x50, 0x32, 0x0A } }, - MimeType { .name = "image/x-portable-pixmap"sv, .common_extensions = { ".ppm"sv }, .description = "PPM image data"sv, .magic_bytes = Vector { 0x50, 0x33, 0x0A } }, - MimeType { .name = "image/x-targa"sv, .common_extensions = { ".tga"sv }, .description = "Targa image data"sv }, + MimeType { .name = "image/avif"sv, .common_extensions = { ".avif"sv }, .description = "AVIF image data"sv }, + MimeType { .name = "image/bmp"sv, .common_extensions = { ".bmp"sv }, .description = "BMP image data"sv, .magic_bytes = Vector { 'B', 'M' } }, + MimeType { .name = "image/gif"sv, .common_extensions = { ".gif"sv }, .description = "GIF image data"sv, .magic_bytes = Vector { 'G', 'I', 'F', '8', '7', 'a' } }, + MimeType { .name = "image/gif"sv, .common_extensions = { ".gif"sv }, .description = "GIF image data"sv, .magic_bytes = Vector { 'G', 'I', 'F', '8', '9', 'a' } }, + MimeType { .name = "image/j2c"sv, .common_extensions = { ".j2c"sv, ".j2k"sv }, .description = "JPEG2000 image data codestream"sv, .magic_bytes = Vector { 0xFF, 0x4F, 0xFF, 0x51 } }, + MimeType { .name = "image/jp2"sv, .common_extensions = { ".jp2"sv, ".jpf"sv, ".jpx"sv }, .description = "JPEG2000 image data"sv, .magic_bytes = Vector { 0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A } }, + MimeType { .name = "image/jpeg"sv, .common_extensions = { ".jpg"sv, ".jpeg"sv }, .description = "JPEG image data"sv, .magic_bytes = Vector { 0xFF, 0xD8, 0xFF } }, + MimeType { .name = "image/jxl"sv, .common_extensions = { ".jxl"sv }, .description = "JPEG XL image data"sv, .magic_bytes = Vector { 0xFF, 0x0A } }, + MimeType { .name = "image/png"sv, .common_extensions = { ".png"sv }, .description = "PNG image data"sv, .magic_bytes = Vector { 0x89, 'P', 'N', 'G', 0x0D, 0x0A, 0x1A, 0x0A } }, + MimeType { .name = "image/svg+xml"sv, .common_extensions = { ".svg"sv }, .description = "Scalable Vector Graphics image"sv }, + MimeType { .name = "image/tiff"sv, .common_extensions = { ".tiff"sv }, .description = "TIFF image data"sv, .magic_bytes = Vector { 'I', 'I', '*', 0x00 } }, + MimeType { .name = "image/tiff"sv, .common_extensions = { ".tiff"sv }, .description = "TIFF image data"sv, .magic_bytes = Vector { 'M', 'M', 0x00, '*' } }, + MimeType { .name = "image/webp"sv, .common_extensions = { ".webp"sv }, .description = "WebP image data"sv, .magic_bytes = Vector { 'W', 'E', 'B', 'P' }, .offset = 8 }, + MimeType { .name = "image/x-icon"sv, .common_extensions = { ".ico"sv }, .description = "ICO image data"sv }, + MimeType { .name = "image/x-ilbm"sv, .common_extensions = { ".iff"sv, ".lbm"sv }, .description = "Interleaved bitmap image data"sv, .magic_bytes = Vector { 0x46, 0x4F, 0x52, 0x4F } }, + MimeType { .name = "image/x-jbig2"sv, .common_extensions = { ".jbig2"sv, ".jb2"sv }, .description = "JBIG2 image data"sv, .magic_bytes = Vector { 0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A } }, + MimeType { .name = "image/x-portable-arbitrarymap"sv, .common_extensions = { ".pam"sv }, .description = "PAM image data"sv, .magic_bytes = Vector { 0x50, 0x37, 0x0A } }, + MimeType { .name = "image/x-portable-bitmap"sv, .common_extensions = { ".pbm"sv }, .description = "PBM image data"sv, .magic_bytes = Vector { 0x50, 0x31, 0x0A } }, + MimeType { .name = "image/x-portable-graymap"sv, .common_extensions = { ".pgm"sv }, .description = "PGM image data"sv, .magic_bytes = Vector { 0x50, 0x32, 0x0A } }, + MimeType { .name = "image/x-portable-pixmap"sv, .common_extensions = { ".ppm"sv }, .description = "PPM image data"sv, .magic_bytes = Vector { 0x50, 0x33, 0x0A } }, + MimeType { .name = "image/x-targa"sv, .common_extensions = { ".tga"sv }, .description = "Targa image data"sv }, - MimeType { .name = "text/css"sv, .common_extensions = { ".css"sv }, .description = "Cascading Style Sheet"sv }, - MimeType { .name = "text/csv"sv, .common_extensions = { ".csv"sv }, .description = "CSV text"sv }, - MimeType { .name = "text/html"sv, .common_extensions = { ".html"sv, ".htm"sv, "/"sv }, .description = "HTML document"sv }, // FIXME: The "/" seems dubious - MimeType { .name = "text/xml"sv, .common_extensions = { ".xml"sv }, .description = "XML document"sv }, - MimeType { .name = "text/markdown"sv, .common_extensions = { ".md"sv }, .description = "Markdown document"sv }, - MimeType { .name = "text/plain"sv, .common_extensions = Vector(s_plaintext_suffixes.span()), .description = "plain text"sv }, - MimeType { .name = "text/x-shellscript"sv, .common_extensions = { ".sh"sv }, .description = "POSIX shell script text executable"sv, .magic_bytes = Vector { '#', '!', '/', 'b', 'i', 'n', '/', 's', 'h', '\n' } }, + MimeType { .name = "text/css"sv, .common_extensions = { ".css"sv }, .description = "Cascading Style Sheet"sv }, + MimeType { .name = "text/csv"sv, .common_extensions = { ".csv"sv }, .description = "CSV text"sv }, + MimeType { .name = "text/html"sv, .common_extensions = { ".html"sv, ".htm"sv, "/"sv }, .description = "HTML document"sv }, // FIXME: The "/" seems dubious + MimeType { .name = "text/xml"sv, .common_extensions = { ".xml"sv }, .description = "XML document"sv }, + MimeType { .name = "text/markdown"sv, .common_extensions = { ".md"sv }, .description = "Markdown document"sv }, + MimeType { .name = "text/plain"sv, .common_extensions = Vector(s_plaintext_suffixes.span()), .description = "plain text"sv }, + MimeType { .name = "text/x-shellscript"sv, .common_extensions = { ".sh"sv }, .description = "POSIX shell script text executable"sv, .magic_bytes = Vector { '#', '!', '/', 'b', 'i', 'n', '/', 's', 'h', '\n' } }, - MimeType { .name = "video/matroska"sv, .common_extensions = { ".mkv"sv }, .description = "Matroska container"sv, .magic_bytes = Vector { 0x1A, 0x45, 0xDF, 0xA3 } }, - MimeType { .name = "video/webm"sv, .common_extensions = { ".webm"sv }, .description = "WebM video"sv }, -}; + MimeType { .name = "video/matroska"sv, .common_extensions = { ".mkv"sv }, .description = "Matroska container"sv, .magic_bytes = Vector { 0x1A, 0x45, 0xDF, 0xA3 } }, + MimeType { .name = "video/webm"sv, .common_extensions = { ".webm"sv }, .description = "WebM video"sv }, + }; +} + +static auto const& registered_mime_types() +{ + static NeverDestroyed mime_types { make_registered_mime_types() }; + return *mime_types; +} StringView guess_mime_type_based_on_filename(StringView path) { - for (auto const& mime_type : s_registered_mime_type) { + for (auto const& mime_type : registered_mime_types()) { for (auto const possible_extension : mime_type.common_extensions) { if (path.ends_with(possible_extension)) return mime_type.name; @@ -161,7 +171,7 @@ StringView guess_mime_type_based_on_filename(StringView path) Optional guess_mime_type_based_on_sniffed_bytes(ReadonlyBytes bytes) { - for (auto const& mime_type : s_registered_mime_type) { + for (auto const& mime_type : registered_mime_types()) { if (mime_type.magic_bytes.has_value() && bytes.size() >= mime_type.offset && bytes.slice(mime_type.offset).starts_with(*mime_type.magic_bytes)) { @@ -174,7 +184,7 @@ Optional guess_mime_type_based_on_sniffed_bytes(ReadonlyBytes bytes) Optional get_mime_type_data(StringView mime_name) { - for (auto const& mime_type : s_registered_mime_type) { + for (auto const& mime_type : registered_mime_types()) { if (mime_name == mime_type.name) return mime_type; } diff --git a/Libraries/LibCore/Platform/ProcessStatisticsLinux.cpp b/Libraries/LibCore/Platform/ProcessStatisticsLinux.cpp index 7f2f0131e3..fa0f1db1d3 100644 --- a/Libraries/LibCore/Platform/ProcessStatisticsLinux.cpp +++ b/Libraries/LibCore/Platform/ProcessStatisticsLinux.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -20,12 +21,12 @@ ErrorOr update_process_statistics(ProcessStatistics& statistics) // Read the total time scheduled from /proc/stat, and each process's usage from /proc/pid/stat // Calculate the CPU percentage for each process based on the total time scheduled and the time spent in the process - static auto proc_stat = TRY(Core::File::open("/proc/stat"sv, Core::File::OpenMode::Read)); - TRY(proc_stat->seek(0, SeekMode::SetPosition)); + static NeverDestroyed> proc_stat { TRY(Core::File::open("/proc/stat"sv, Core::File::OpenMode::Read)) }; + TRY((*proc_stat)->seek(0, SeekMode::SetPosition)); char buf[1024] = {}; auto buffer = Bytes { buf, sizeof(buf) }; - auto line = TRY(proc_stat->read_some(buffer)); + auto line = TRY((*proc_stat)->read_some(buffer)); int user_time = 0; int system_time = 0; diff --git a/Libraries/LibCore/ReportTime.cpp b/Libraries/LibCore/ReportTime.cpp index 61334642cf..ddfcc8c703 100644 --- a/Libraries/LibCore/ReportTime.cpp +++ b/Libraries/LibCore/ReportTime.cpp @@ -8,15 +8,20 @@ #include #include +#include #include namespace Core { -static HashMap g_timing_info_table; +static auto& timing_info_table() +{ + static NeverDestroyed> timing_info_table; + return *timing_info_table; +} void log_timing_info(ByteString const& name, AK::Duration const& elapsed_time, u64 print_every_n_calls) { - auto& timing_info = g_timing_info_table.ensure(name); + auto& timing_info = timing_info_table().ensure(name); timing_info.call_count++; timing_info.cumulative_time_nanoseconds += elapsed_time.to_nanoseconds(); diff --git a/Libraries/LibCore/ResourceImplementation.cpp b/Libraries/LibCore/ResourceImplementation.cpp index 2834124ace..99ae9be885 100644 --- a/Libraries/LibCore/ResourceImplementation.cpp +++ b/Libraries/LibCore/ResourceImplementation.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -11,18 +12,23 @@ namespace Core { -static OwnPtr s_the; +static auto& installed_resource_implementation() +{ + static NeverDestroyed> implementation; + return *implementation; +} void ResourceImplementation::install(OwnPtr the) { - s_the = move(the); + installed_resource_implementation() = move(the); } ResourceImplementation& ResourceImplementation::the() { - if (!s_the) + auto& implementation = installed_resource_implementation(); + if (!implementation) install(make("/res"_string)); - return *s_the; + return *implementation; } NonnullRefPtr ResourceImplementation::make_resource(String full_path, NonnullOwnPtr file, time_t modified_time) diff --git a/Libraries/LibCore/SystemServerTakeover.cpp b/Libraries/LibCore/SystemServerTakeover.cpp index 0f980c47d7..09047f66ff 100644 --- a/Libraries/LibCore/SystemServerTakeover.cpp +++ b/Libraries/LibCore/SystemServerTakeover.cpp @@ -6,15 +6,21 @@ */ #include "SystemServerTakeover.h" +#include #include #include #include namespace Core { -HashMap s_overtaken_sockets {}; bool s_overtaken_sockets_parsed { false }; +static auto& overtaken_sockets() +{ + static NeverDestroyed> sockets; + return *sockets; +} + static void parse_sockets_from_system_server() { VERIFY(!s_overtaken_sockets_parsed); @@ -29,7 +35,7 @@ static void parse_sockets_from_system_server() for (auto socket : sockets->split_view(';')) { auto params = socket.split_view(':'); VERIFY(params.size() == 2); - s_overtaken_sockets.set(params[0].to_byte_string(), params[1].to_number().value()); + overtaken_sockets().set(params[0].to_byte_string(), params[1].to_number().value()); } s_overtaken_sockets_parsed = true; @@ -46,11 +52,11 @@ ErrorOr> take_over_socket_from_system_server(By int fd; if (socket_path.is_empty()) { // We want the first (and only) socket. - VERIFY(s_overtaken_sockets.size() == 1); - fd = s_overtaken_sockets.begin()->value; + VERIFY(overtaken_sockets().size() == 1); + fd = overtaken_sockets().begin()->value; } else { - auto it = s_overtaken_sockets.find(socket_path); - if (it == s_overtaken_sockets.end()) + auto it = overtaken_sockets().find(socket_path); + if (it == overtaken_sockets().end()) return Error::from_string_literal("Non-existent socket requested"); fd = it->value; } diff --git a/Libraries/LibCore/ThreadEventQueue.cpp b/Libraries/LibCore/ThreadEventQueue.cpp index 67a830c5ba..3738643547 100644 --- a/Libraries/LibCore/ThreadEventQueue.cpp +++ b/Libraries/LibCore/ThreadEventQueue.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -46,11 +47,16 @@ struct ThreadEventQueue::Private { }; static pthread_key_t s_current_thread_event_queue_key; -static Sync::OnceFlag s_current_thread_event_queue_key_once {}; + +static auto& current_thread_event_queue_key_once() +{ + static NeverDestroyed once; + return *once; +} ThreadEventQueue* ThreadEventQueue::current_or_null() { - Sync::call_once(s_current_thread_event_queue_key_once, [] { + Sync::call_once(current_thread_event_queue_key_once(), [] { pthread_key_create(&s_current_thread_event_queue_key, [](void* value) { if (value) delete static_cast(value); diff --git a/Libraries/LibDNS/Resolver.h b/Libraries/LibDNS/Resolver.h index 4547d587a7..f38cbf338d 100644 --- a/Libraries/LibDNS/Resolver.h +++ b/Libraries/LibDNS/Resolver.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -41,22 +42,28 @@ namespace DNS { // FIXME: Load these keys from a file (likely something trusted by the system, e.g. "whatever systemd does"). // https://data.iana.org/root-anchors/root-anchors.xml -static Vector s_root_zone_dnskeys = { - { - .flags = 257, - .protocol = 3, - .algorithm = Messages::DNSSEC::Algorithm::RSASHA256, - .public_key = decode_base64("AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU="sv).release_value(), - .calculated_key_tag = 20326, - }, - { - .flags = 256, - .protocol = 3, - .algorithm = Messages::DNSSEC::Algorithm::RSASHA256, - .public_key = decode_base64("AwEAAa96jeuknZlaeSrvyAJj6ZHv28hhOKkx3rLGXVaC6rXTsDc449/cidltpkyGwCJNnOAlFNKF2jBosZBU5eeHspaQWOmOElZsjICMQMC3aeHbGiShvZsx4wMYSjH8e7Vrhbu6irwCzVBApESjbUdpWWmEnhathWu1jo+siFUiRAAxm9qyJNg/wOZqqzL/dL/q8PkcRU5oUKEpUge71M3ej2/7CPqpdVwuMoTvoB+ZOT4YeGyxMvHmbrxlFzGOHOijtzN+u1TQNatX2XBuzZNQ1K+s2CXkPIZo7s6JgZyvaBevYtxPvYLw4z9mR7K2vaF18UYH9Z9GNUUeayffKC73PYc="sv).release_value(), - .calculated_key_tag = 38696, - }, -}; +static Vector const& root_zone_dnskeys() +{ + static NeverDestroyed> root_zone_dnskeys { + Vector { + { + .flags = 257, + .protocol = 3, + .algorithm = Messages::DNSSEC::Algorithm::RSASHA256, + .public_key = decode_base64("AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU="sv).release_value(), + .calculated_key_tag = 20326, + }, + { + .flags = 256, + .protocol = 3, + .algorithm = Messages::DNSSEC::Algorithm::RSASHA256, + .public_key = decode_base64("AwEAAa96jeuknZlaeSrvyAJj6ZHv28hhOKkx3rLGXVaC6rXTsDc449/cidltpkyGwCJNnOAlFNKF2jBosZBU5eeHspaQWOmOElZsjICMQMC3aeHbGiShvZsx4wMYSjH8e7Vrhbu6irwCzVBApESjbUdpWWmEnhathWu1jo+siFUiRAAxm9qyJNg/wOZqqzL/dL/q8PkcRU5oUKEpUge71M3ej2/7CPqpdVwuMoTvoB+ZOT4YeGyxMvHmbrxlFzGOHOijtzN+u1TQNatX2XBuzZNQ1K+s2CXkPIZo7s6JgZyvaBevYtxPvYLw4z9mR7K2vaF18UYH9Z9GNUUeayffKC73PYc="sv).release_value(), + .calculated_key_tag = 38696, + }, + } + }; + return *root_zone_dnskeys; +} class Resolver; @@ -1134,7 +1141,7 @@ private: }; if (is_root_zone) { - resolve_using_keys(s_root_zone_dnskeys); + resolve_using_keys(root_zone_dnskeys()); return; } diff --git a/Libraries/LibDevTools/Actors/DeviceActor.cpp b/Libraries/LibDevTools/Actors/DeviceActor.cpp index ef88351982..14432f044e 100644 --- a/Libraries/LibDevTools/Actors/DeviceActor.cpp +++ b/Libraries/LibDevTools/Actors/DeviceActor.cpp @@ -29,10 +29,10 @@ void DeviceActor::handle_message(Message const& message) if (message.type == "getDescription"sv) { auto build_id = Core::Version::read_long_version_string(); - static auto browser_name = String::from_utf8_without_validation({ BROWSER_NAME, __builtin_strlen(BROWSER_NAME) }); - static auto browser_version = String::from_utf8_without_validation({ BROWSER_VERSION, __builtin_strlen(BROWSER_VERSION) }); - static auto platform_name = String::from_utf8_without_validation({ OS_STRING, __builtin_strlen(OS_STRING) }); - static auto arch = String::from_utf8_without_validation({ CPU_STRING, __builtin_strlen(CPU_STRING) }); + static auto& browser_name = *new String(String::from_utf8_without_validation({ BROWSER_NAME, __builtin_strlen(BROWSER_NAME) })); + static auto& browser_version = *new String(String::from_utf8_without_validation({ BROWSER_VERSION, __builtin_strlen(BROWSER_VERSION) })); + static auto& platform_name = *new String(String::from_utf8_without_validation({ OS_STRING, __builtin_strlen(OS_STRING) })); + static auto& arch = *new String(String::from_utf8_without_validation({ CPU_STRING, __builtin_strlen(CPU_STRING) })); // https://github.com/mozilla/gecko-dev/blob/master/devtools/shared/system.js JsonObject value; diff --git a/Libraries/LibGC/Heap.cpp b/Libraries/LibGC/Heap.cpp index dd49443054..cf17eff14b 100644 --- a/Libraries/LibGC/Heap.cpp +++ b/Libraries/LibGC/Heap.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -139,7 +140,13 @@ struct IncrementalSweepStats { Vector batches; Core::ElapsedTimer timer { Core::TimerType::Precise }; }; -IncrementalSweepStats g_incremental_sweep_stats; + +IncrementalSweepStats& incremental_sweep_stats() +{ + static NeverDestroyed stats; + return *stats; +} + bool g_next_incremental_sweep_should_report { false }; // Set by collect_garbage() while a reported collection is in flight. Used by @@ -196,9 +203,9 @@ void print_gc_report(i64 total_us, size_t live_block_count) void record_incremental_sweep_batch(size_t blocks_swept, i64 elapsed_us, bool forced) { - if (!g_incremental_sweep_stats.should_report || blocks_swept == 0) + if (!incremental_sweep_stats().should_report || blocks_swept == 0) return; - g_incremental_sweep_stats.batches.append({ + incremental_sweep_stats().batches.append({ .blocks_swept = blocks_swept, .elapsed_us = elapsed_us, .forced = forced, @@ -207,30 +214,30 @@ void record_incremental_sweep_batch(size_t blocks_swept, i64 elapsed_us, bool fo void print_incremental_sweep_report(size_t live_cell_bytes, size_t live_external_bytes, size_t next_gc_bytes_threshold) { - if (!g_incremental_sweep_stats.should_report) + if (!incremental_sweep_stats().should_report) return; size_t swept_blocks = 0; i64 batch_time_us = 0; i64 shortest_batch_us = NumericLimits::max(); i64 longest_batch_us = 0; - for (auto const& batch : g_incremental_sweep_stats.batches) { + for (auto const& batch : incremental_sweep_stats().batches) { swept_blocks += batch.blocks_swept; batch_time_us += batch.elapsed_us; shortest_batch_us = min(shortest_batch_us, batch.elapsed_us); longest_batch_us = max(longest_batch_us, batch.elapsed_us); } - if (g_incremental_sweep_stats.batches.is_empty()) + if (incremental_sweep_stats().batches.is_empty()) shortest_batch_us = 0; dbgln("Incremental sweep report"); dbgln("================================================================="); dbgln("Totals:"); - dbgln(" Wall time: {} us", g_incremental_sweep_stats.timer.elapsed_time().to_microseconds()); + dbgln(" Wall time: {} us", incremental_sweep_stats().timer.elapsed_time().to_microseconds()); dbgln(" Batch time: {} us", batch_time_us); - dbgln(" Batches: {}", g_incremental_sweep_stats.batches.size()); - dbgln(" Swept blocks: {} / {} ({})", swept_blocks, g_incremental_sweep_stats.total_blocks, human_readable_size(swept_blocks * HeapBlock::BLOCK_SIZE)); + dbgln(" Batches: {}", incremental_sweep_stats().batches.size()); + dbgln(" Swept blocks: {} / {} ({})", swept_blocks, incremental_sweep_stats().total_blocks, human_readable_size(swept_blocks * HeapBlock::BLOCK_SIZE)); dbgln(" Live cells: {}", human_readable_size(live_cell_bytes)); dbgln(" Live external: {}", human_readable_size(live_external_bytes)); dbgln(" Next threshold: {}", human_readable_size(next_gc_bytes_threshold)); @@ -238,8 +245,8 @@ void print_incremental_sweep_report(size_t live_cell_bytes, size_t live_external dbgln("Batch timings:"); dbgln(" Shortest batch: {} us", shortest_batch_us); dbgln(" Longest batch: {} us", longest_batch_us); - for (size_t i = 0; i < g_incremental_sweep_stats.batches.size(); ++i) { - auto const& batch = g_incremental_sweep_stats.batches[i]; + for (size_t i = 0; i < incremental_sweep_stats().batches.size(); ++i) { + auto const& batch = incremental_sweep_stats().batches[i]; dbgln(" #{:>3}: {:>5} blocks in {:>8} us{}", i + 1, batch.blocks_swept, batch.elapsed_us, batch.forced ? " (forced)"sv : ""sv); } dbgln("================================================================="); @@ -1279,13 +1286,13 @@ void Heap::start_incremental_sweep() m_incremental_sweep_active = true; m_sweep_live_cell_bytes = 0; m_sweep_live_external_bytes = 0; - g_incremental_sweep_stats.should_report = false; - g_incremental_sweep_stats.total_blocks = 0; - g_incremental_sweep_stats.batches.clear(); - g_incremental_sweep_stats.should_report = g_next_incremental_sweep_should_report; + incremental_sweep_stats().should_report = false; + incremental_sweep_stats().total_blocks = 0; + incremental_sweep_stats().batches.clear(); + incremental_sweep_stats().should_report = g_next_incremental_sweep_should_report; g_next_incremental_sweep_should_report = false; - if (g_incremental_sweep_stats.should_report) - g_incremental_sweep_stats.timer.start(); + if (incremental_sweep_stats().should_report) + incremental_sweep_stats().timer.start(); // Populate each allocator's pending sweep list with its current blocks. // Blocks allocated during incremental sweep won't be on these lists @@ -1300,7 +1307,7 @@ void Heap::start_incremental_sweep() if (allocator.has_blocks_pending_sweep()) m_allocators_to_sweep.append(allocator); } - g_incremental_sweep_stats.total_blocks = total_blocks; + incremental_sweep_stats().total_blocks = total_blocks; dbgln_if(INCREMENTAL_SWEEP_DEBUG, "[sweep] {} blocks to sweep", total_blocks); diff --git a/Libraries/LibGfx/Font/FontDatabase.cpp b/Libraries/LibGfx/Font/FontDatabase.cpp index c506cdee48..ef952adac2 100644 --- a/Libraries/LibGfx/Font/FontDatabase.cpp +++ b/Libraries/LibGfx/Font/FontDatabase.cpp @@ -26,8 +26,8 @@ SystemFontProvider::~SystemFontProvider() = default; FontDatabase& FontDatabase::the() { - static FontDatabase s_the; - return s_the; + static FontDatabase& database = *new FontDatabase; + return database; } SystemFontProvider& FontDatabase::install_system_font_provider(NonnullOwnPtr provider) diff --git a/Libraries/LibGfx/Font/GlobalFontConfig.cpp b/Libraries/LibGfx/Font/GlobalFontConfig.cpp index 85c27dbe51..fa8f904070 100644 --- a/Libraries/LibGfx/Font/GlobalFontConfig.cpp +++ b/Libraries/LibGfx/Font/GlobalFontConfig.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -26,8 +27,8 @@ GlobalFontConfig::~GlobalFontConfig() GlobalFontConfig& GlobalFontConfig::the() { - static GlobalFontConfig s_the; - return s_the; + static NeverDestroyed s_the; + return *s_the; } FcConfig* GlobalFontConfig::get() diff --git a/Libraries/LibGfx/Font/GlobalFontConfig.h b/Libraries/LibGfx/Font/GlobalFontConfig.h index 4b69207156..648f71af6d 100644 --- a/Libraries/LibGfx/Font/GlobalFontConfig.h +++ b/Libraries/LibGfx/Font/GlobalFontConfig.h @@ -8,6 +8,13 @@ #include +namespace AK { + +template +class NeverDestroyed; + +} + namespace Gfx { class GlobalFontConfig { @@ -16,6 +23,8 @@ public: FcConfig* get(); private: + friend class AK::NeverDestroyed; + GlobalFontConfig(); ~GlobalFontConfig(); diff --git a/Libraries/LibGfx/Font/TypefaceSkia.cpp b/Libraries/LibGfx/Font/TypefaceSkia.cpp index 494b8f894c..d21b247ac8 100644 --- a/Libraries/LibGfx/Font/TypefaceSkia.cpp +++ b/Libraries/LibGfx/Font/TypefaceSkia.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -35,7 +36,11 @@ namespace Gfx { -static sk_sp s_font_manager; +static auto& skia_font_manager() +{ + static NeverDestroyed> font_manager; + return *font_manager; +} struct TypefaceSkia::Impl { Impl(sk_sp skia_typeface, std::unique_ptr stream = {}, Optional system_ui_font_kind = {} @@ -74,24 +79,25 @@ struct TypefaceSkia::Impl { static SkFontMgr& font_manager() { - if (!s_font_manager) { + auto& font_manager = skia_font_manager(); + if (!font_manager) { #ifdef AK_OS_MACOS if (Gfx::FontDatabase::the().system_font_provider_name() != "FontConfig"sv) { - s_font_manager = SkFontMgr_New_CoreText(nullptr); + font_manager = SkFontMgr_New_CoreText(nullptr); } #endif #if defined(AK_OS_ANDROID) - s_font_manager = SkFontMgr_New_Android(nullptr); + font_manager = SkFontMgr_New_Android(nullptr); #elif defined(AK_OS_WINDOWS) - s_font_manager = SkFontMgr_New_DirectWrite(); + font_manager = SkFontMgr_New_DirectWrite(); #else - if (!s_font_manager) { - s_font_manager = SkFontMgr_New_FontConfig(nullptr, SkFontScanner_Make_FreeType()); + if (!font_manager) { + font_manager = SkFontMgr_New_FontConfig(nullptr, SkFontScanner_Make_FreeType()); } #endif } - VERIFY(s_font_manager); - return *s_font_manager; + VERIFY(font_manager); + return *font_manager; } static std::unique_ptr copy_stream_to_memory_stream(SkStreamAsset& stream) diff --git a/Libraries/LibGfx/SkiaBackendContext.cpp b/Libraries/LibGfx/SkiaBackendContext.cpp index f672542876..8e75f8aefa 100644 --- a/Libraries/LibGfx/SkiaBackendContext.cpp +++ b/Libraries/LibGfx/SkiaBackendContext.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -37,7 +38,11 @@ static constexpr auto skia_deferred_cleanup_resource_age = std::chrono::seconds( static constexpr auto skia_resource_cache_high_watermark = 384 * MiB; static constexpr auto skia_resource_cache_critical_watermark = 512 * MiB; -static RefPtr s_main_thread_context; +static auto& main_thread_context() +{ + static NeverDestroyed> context; + return *context; +} #if defined(AK_OS_MACOS) || USE_VULKAN static void invoke_async_flush_callback(void* context) @@ -110,9 +115,9 @@ void SkiaBackendContext::perform_post_flush_cleanup() void SkiaBackendContext::initialize_gpu_backend() { - VERIFY(!s_main_thread_context); + VERIFY(!main_thread_context()); - s_main_thread_context = create_independent_gpu_backend(); + main_thread_context() = create_independent_gpu_backend(); } RefPtr SkiaBackendContext::create_independent_gpu_backend() @@ -137,7 +142,7 @@ RefPtr SkiaBackendContext::create_independent_gpu_backend() RefPtr SkiaBackendContext::the_main_thread_context() { - return s_main_thread_context; + return main_thread_context(); } #ifdef USE_VULKAN diff --git a/Libraries/LibGfx/SystemTheme.cpp b/Libraries/LibGfx/SystemTheme.cpp index b874aa7a3e..67973918e5 100644 --- a/Libraries/LibGfx/SystemTheme.cpp +++ b/Libraries/LibGfx/SystemTheme.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -14,17 +15,21 @@ namespace Gfx { -static Core::AnonymousBuffer theme_buffer; +static auto& theme_buffer() +{ + static NeverDestroyed buffer; + return *buffer; +} Core::AnonymousBuffer& current_system_theme_buffer() { - VERIFY(theme_buffer.is_valid()); - return theme_buffer; + VERIFY(theme_buffer().is_valid()); + return theme_buffer(); } void set_system_theme(Core::AnonymousBuffer buffer) { - theme_buffer = move(buffer); + theme_buffer() = move(buffer); } ErrorOr load_system_theme(Core::ConfigFile const& file, Optional const& color_scheme) @@ -39,7 +44,7 @@ ErrorOr load_system_theme(Core::ConfigFile const& file, O if (color_scheme.value() != "Custom"sv) memcpy(data->path[(int)PathRole::ColorScheme], color_scheme.value().characters(), color_scheme.value().length()); else - memcpy(buffer.data(), theme_buffer.data(), sizeof(SystemTheme)); + memcpy(buffer.data(), theme_buffer().data(), sizeof(SystemTheme)); } auto get_color = [&](auto& name) -> Optional { diff --git a/Libraries/LibHTTP/Method.cpp b/Libraries/LibHTTP/Method.cpp index 0182edc137..5a3ad932f8 100644 --- a/Libraries/LibHTTP/Method.cpp +++ b/Libraries/LibHTTP/Method.cpp @@ -37,9 +37,9 @@ ByteString normalize_method(StringView method) { // To normalize a method, if it is a byte-case-insensitive match for `DELETE`, `GET`, `HEAD`, `OPTIONS`, `POST`, // or `PUT`, byte-uppercase it. - static auto NORMALIZED_METHODS = to_array({ "DELETE"sv, "GET"sv, "HEAD"sv, "OPTIONS"sv, "POST"sv, "PUT"sv }); + static constexpr auto normalized_methods = to_array({ "DELETE"sv, "GET"sv, "HEAD"sv, "OPTIONS"sv, "POST"sv, "PUT"sv }); - for (auto const& normalized_method : NORMALIZED_METHODS) { + for (auto const& normalized_method : normalized_methods) { if (normalized_method.equals_ignoring_ascii_case(method)) return normalized_method; } diff --git a/Libraries/LibIDL/ExposedTo.cpp b/Libraries/LibIDL/ExposedTo.cpp index 517e8bd211..3092aa1c82 100644 --- a/Libraries/LibIDL/ExposedTo.cpp +++ b/Libraries/LibIDL/ExposedTo.cpp @@ -5,10 +5,15 @@ */ #include +#include #include #include -static ByteString s_error_string; +static auto& error_string() +{ + static NeverDestroyed string; + return *string; +} namespace IDL { @@ -54,19 +59,19 @@ ErrorOr parse_exposure_set(StringView interface_name, StringView expo if (auto parsed_exposed = exposed_from_string(candidate); parsed_exposed.has_value()) { whom |= parsed_exposed.value(); } else { - s_error_string = ByteString::formatted("Unknown Exposed attribute candidate {} in {} in {}", candidate, exposed_trimmed, interface_name); - return Error::from_string_view(s_error_string.view()); + error_string() = ByteString::formatted("Unknown Exposed attribute candidate {} in {} in {}", candidate, exposed_trimmed, interface_name); + return Error::from_string_view(error_string().view()); } } if (whom == ExposedTo::Nobody) { - s_error_string = ByteString::formatted("Unknown Exposed attribute {} in {}", exposed_trimmed, interface_name); - return Error::from_string_view(s_error_string.view()); + error_string() = ByteString::formatted("Unknown Exposed attribute {} in {}", exposed_trimmed, interface_name); + return Error::from_string_view(error_string().view()); } return whom; } - s_error_string = ByteString::formatted("Unknown Exposed attribute {} in {}", exposed_trimmed, interface_name); - return Error::from_string_view(s_error_string.view()); + error_string() = ByteString::formatted("Unknown Exposed attribute {} in {}", exposed_trimmed, interface_name); + return Error::from_string_view(error_string().view()); } } diff --git a/Libraries/LibJS/Bytecode/Executable.cpp b/Libraries/LibJS/Bytecode/Executable.cpp index 01f11d07da..91a396765e 100644 --- a/Libraries/LibJS/Bytecode/Executable.cpp +++ b/Libraries/LibJS/Bytecode/Executable.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -636,8 +637,8 @@ size_t Executable::external_memory_size() const static Vector& static_property_lookup_caches() { - static Vector caches; - return caches; + static NeverDestroyed> caches; + return *caches; } StaticPropertyLookupCache::StaticPropertyLookupCache() @@ -732,8 +733,8 @@ SourceRange const& Executable::get_source_range(u32 program_counter) return m_source_range_cache.ensure(program_counter, [&] { if (auto source_range = source_range_at(program_counter); source_range.has_value()) return *source_range; - static SourceRange dummy { SourceCode::create({}, Utf16String {}), {} }; - return dummy; + static NeverDestroyed dummy { SourceRange { SourceCode::create({}, Utf16String {}), {} } }; + return *dummy; }); } diff --git a/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Libraries/LibJS/Runtime/AbstractOperations.cpp index 1e7fed1c17..28936a8c92 100644 --- a/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -155,7 +155,7 @@ ThrowCompletionOr length_of_array_like(VM& vm, Object const& object) return object.indexed_array_like_size(); // 1. Return ℝ(? ToLength(? Get(obj, "length"))). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; return TRY(object.get(vm.names.length, cache)).to_length(vm); } @@ -202,7 +202,7 @@ ThrowCompletionOr> create_list_from_array_like(VM& vm, Val ThrowCompletionOr species_constructor(VM& vm, Object const& object, FunctionObject& default_constructor) { // 1. Let C be ? Get(O, "constructor"). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto constructor = TRY(object.get(vm.names.constructor, cache)); // 2. If C is undefined, return defaultConstructor. @@ -214,7 +214,7 @@ ThrowCompletionOr species_constructor(VM& vm, Object const& obj return vm.throw_completion(ErrorType::NotAConstructor, constructor); // 4. Let S be ? Get(C, @@species). - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; auto species = TRY(constructor.as_object().get(vm.well_known_symbol_species(), cache2)); // 5. If S is either undefined or null, return defaultConstructor. @@ -414,7 +414,7 @@ ThrowCompletionOr get_prototype_from_constructor(VM& vm, FunctionObject // 1. Assert: intrinsicDefaultProto is this specification's name of an intrinsic object. The corresponding object must be an intrinsic that is intended to be used as the [[Prototype]] value of an object. // 2. Let proto be ? Get(constructor, "prototype"). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto prototype = TRY(constructor.get(vm.names.prototype, cache)); // 3. If Type(proto) is not Object, then diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 5e2e325157..e7ba59cf06 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -29,7 +30,11 @@ namespace JS { GC_DEFINE_ALLOCATOR(ArrayPrototype); -static HashTable> s_array_join_seen_objects; +static auto& array_join_seen_objects() +{ + static NeverDestroyed>> seen_objects; + return *seen_objects; +} ArrayPrototype::ArrayPrototype(Realm& realm) : Array(realm, realm.intrinsics().object_prototype()) @@ -119,7 +124,7 @@ static ThrowCompletionOr array_species_create(VM& vm, Object& original_ if (!is_array) return TRY(Array::create(realm, length)).ptr(); - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto constructor = TRY(original_array.get(vm.names.constructor, cache)); if (constructor.is_constructor()) { auto& constructor_function = constructor.as_function(); @@ -132,7 +137,7 @@ static ThrowCompletionOr array_species_create(VM& vm, Object& original_ } if (constructor.is_object()) { - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; constructor = TRY(constructor.as_object().get(vm.well_known_symbol_species(), cache2)); if (constructor.is_null()) constructor = js_undefined(); @@ -918,11 +923,11 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::join) // This is not part of the spec, but all major engines do some kind of circular reference checks. // FWIW: engine262, a "100% spec compliant" ECMA-262 impl, aborts with "too much recursion". // Same applies to Array.prototype.toLocaleString(). - if (s_array_join_seen_objects.contains(this_object)) + if (array_join_seen_objects().contains(this_object)) return PrimitiveString::create(vm, String {}); - s_array_join_seen_objects.set(this_object); + array_join_seen_objects().set(this_object); ArmedScopeGuard unsee_object_guard = [&] { - s_array_join_seen_objects.remove(this_object); + array_join_seen_objects().remove(this_object); }; auto length = TRY(length_of_array_like(vm, this_object)); @@ -1803,11 +1808,11 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::to_locale_string) // 1. Let array be ? ToObject(this value). auto this_object = TRY(vm.this_value().to_object(vm)); - if (s_array_join_seen_objects.contains(this_object)) + if (array_join_seen_objects().contains(this_object)) return PrimitiveString::create(vm, String {}); - s_array_join_seen_objects.set(this_object); + array_join_seen_objects().set(this_object); ArmedScopeGuard unsee_object_guard = [&] { - s_array_join_seen_objects.remove(this_object); + array_join_seen_objects().remove(this_object); }; // 2. Let len be ? ToLength(? Get(array, "length")). diff --git a/Libraries/LibJS/Runtime/Date.cpp b/Libraries/LibJS/Runtime/Date.cpp index ed2187ff66..ab38337274 100644 --- a/Libraries/LibJS/Runtime/Date.cpp +++ b/Libraries/LibJS/Runtime/Date.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -365,15 +366,15 @@ Crypto::SignedBigInteger get_utc_epoch_nanoseconds(Temporal::ISODateTime const& i64 clip_bigint_to_sane_time(Crypto::SignedBigInteger const& value) { - static Crypto::SignedBigInteger const min_bigint { NumericLimits::min() }; - static Crypto::SignedBigInteger const max_bigint { NumericLimits::max() }; + static NeverDestroyed min_bigint { NumericLimits::min() }; + static NeverDestroyed max_bigint { NumericLimits::max() }; // The provided epoch (nano)seconds value is potentially out of range for AK::Duration and subsequently // get_time_zone_offset(). We can safely assume that the TZDB has no useful information that far // into the past and future anyway, so clamp it to the i64 range. - if (value < min_bigint) + if (value < *min_bigint) return NumericLimits::min(); - if (value > max_bigint) + if (value > *max_bigint) return NumericLimits::max(); return value.to_i64(); diff --git a/Libraries/LibJS/Runtime/ErrorData.cpp b/Libraries/LibJS/Runtime/ErrorData.cpp index 96cd17c783..286971d7c3 100644 --- a/Libraries/LibJS/Runtime/ErrorData.cpp +++ b/Libraries/LibJS/Runtime/ErrorData.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -15,12 +16,16 @@ namespace JS { -static SourceRange dummy_source_range { SourceCode::create({}, Utf16String {}), {} }; +static auto& dummy_source_range() +{ + static NeverDestroyed source_range { SourceRange { SourceCode::create({}, Utf16String {}), {} } }; + return *source_range; +} SourceRange const& TracebackFrame::source_range() const { if (!cached_source_range.has_value()) - return dummy_source_range; + return dummy_source_range(); return *cached_source_range; } diff --git a/Libraries/LibJS/Runtime/ErrorTypes.cpp b/Libraries/LibJS/Runtime/ErrorTypes.cpp index e6bf862c63..0ad1bb7b42 100644 --- a/Libraries/LibJS/Runtime/ErrorTypes.cpp +++ b/Libraries/LibJS/Runtime/ErrorTypes.cpp @@ -9,7 +9,7 @@ namespace JS { #define __ENUMERATE_JS_ERROR(name, message) \ - const ErrorType ErrorType::name = ErrorType(message##sv); + ErrorType const& ErrorType::name = *new ErrorType(message##sv); JS_ENUMERATE_ERROR_TYPES(__ENUMERATE_JS_ERROR) #undef __ENUMERATE_JS_ERROR diff --git a/Libraries/LibJS/Runtime/ErrorTypes.h b/Libraries/LibJS/Runtime/ErrorTypes.h index 356c778449..e0686b9fdb 100644 --- a/Libraries/LibJS/Runtime/ErrorTypes.h +++ b/Libraries/LibJS/Runtime/ErrorTypes.h @@ -314,7 +314,7 @@ namespace JS { class JS_API ErrorType { public: #define __ENUMERATE_JS_ERROR(name, message) \ - static const ErrorType name; + static ErrorType const& name; JS_ENUMERATE_ERROR_TYPES(__ENUMERATE_JS_ERROR) #undef __ENUMERATE_JS_ERROR diff --git a/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp b/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp index 496ffb6557..a20bcbe471 100644 --- a/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp +++ b/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -134,7 +135,7 @@ bool is_well_formed_currency_code(StringView currency) Vector const& available_named_time_zone_identifiers() { // It is recommended that the result of AvailableNamedTimeZoneIdentifiers remains the same for the lifetime of the surrounding agent. - static auto named_time_zone_identifiers = []() { + static NeverDestroyed> named_time_zone_identifiers { []() { // 1. Let identifiers be a List containing the String value of each Zone or Link name in the IANA Time Zone Database. auto const& identifiers = Unicode::available_time_zones(); @@ -184,9 +185,9 @@ Vector const& available_named_time_zone_identifiers() // 8. Return result. return result; - }(); + }() }; - return named_time_zone_identifiers; + return *named_time_zone_identifiers; } // 6.5.2 GetAvailableNamedTimeZoneIdentifier ( timeZoneIdentifier ), https://tc39.es/ecma402/#sec-getavailablenamedtimezoneidentifier diff --git a/Libraries/LibJS/Runtime/Intl/Collator.cpp b/Libraries/LibJS/Runtime/Intl/Collator.cpp index 53655ebc7f..04905180e7 100644 --- a/Libraries/LibJS/Runtime/Intl/Collator.cpp +++ b/Libraries/LibJS/Runtime/Intl/Collator.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include namespace JS::Intl { @@ -36,13 +37,16 @@ ReadonlySpan Collator::resolution_option_descriptors // The value of the [[ResolutionOptionDescriptors]] internal slot is « { [[Key]]: "co", [[Property]]: "collation" }, { [[Key]]: "kn", [[Property]]: "numeric", [[Type]]: boolean }, { [[Key]]: "kf", [[Property]]: "caseFirst", [[Values]]: « "upper", "lower", "false" » } ». static constexpr AK::Array case_first_values { "upper"sv, "lower"sv, "false"sv }; - static auto descriptors = to_array({ - { .key = "co"sv, .property = vm.names.collation }, - { .key = "kn"sv, .property = vm.names.numeric, .type = OptionType::Boolean }, - { .key = "kf"sv, .property = vm.names.caseFirst, .values = case_first_values }, - }); + auto make_descriptors = [&] { + return to_array({ + { .key = "co"sv, .property = vm.names.collation }, + { .key = "kn"sv, .property = vm.names.numeric, .type = OptionType::Boolean }, + { .key = "kf"sv, .property = vm.names.caseFirst, .values = case_first_values }, + }); + }; + static NeverDestroyed descriptors { make_descriptors() }; - return descriptors; + return *descriptors; } } diff --git a/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp b/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp index bda71378fc..d719f85645 100644 --- a/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp +++ b/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -48,14 +49,17 @@ ReadonlySpan DateTimeFormat::resolution_option_descr // The value of the [[ResolutionOptionDescriptors]] internal slot is « { [[Key]]: "ca", [[Property]]: "calendar" }, { [[Key]]: "nu", [[Property]]: "numberingSystem" }, { [[Key]]: "hour12", [[Property]]: "hour12", [[Type]]: boolean }, { [[Key]]: "hc", [[Property]]: "hourCycle", [[Values]]: « "h11", "h12", "h23", "h24" » } ». static constexpr AK::Array hour_cycle_values { "h11"sv, "h12"sv, "h23"sv, "h24"sv }; - static auto descriptors = to_array({ - { .key = "ca"sv, .property = vm.names.calendar }, - { .key = "nu"sv, .property = vm.names.numberingSystem }, - { .key = "hour12"sv, .property = vm.names.hour12, .type = OptionType::Boolean }, - { .key = "hc"sv, .property = vm.names.hourCycle, .values = hour_cycle_values }, - }); + auto make_descriptors = [&] { + return to_array({ + { .key = "ca"sv, .property = vm.names.calendar }, + { .key = "nu"sv, .property = vm.names.numberingSystem }, + { .key = "hour12"sv, .property = vm.names.hour12, .type = OptionType::Boolean }, + { .key = "hc"sv, .property = vm.names.hourCycle, .values = hour_cycle_values }, + }); + }; + static NeverDestroyed descriptors { make_descriptors() }; - return descriptors; + return *descriptors; } static Optional get_or_create_formatter(StringView locale, StringView time_zone, OwnPtr& formatter, Optional const& format) diff --git a/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp b/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp index acfa3a2df9..9859ffd1e1 100644 --- a/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp +++ b/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -38,11 +39,14 @@ ReadonlySpan DurationFormat::relevant_extension_keys() const ReadonlySpan DurationFormat::resolution_option_descriptors(VM& vm) const { // The value of the [[ResolutionOptionDescriptors]] internal slot is « { [[Key]]: "nu", [[Property]]: "numberingSystem" } ». - static auto descriptors = to_array({ - { .key = "nu"sv, .property = vm.names.numberingSystem }, - }); + auto make_descriptors = [&] { + return to_array({ + { .key = "nu"sv, .property = vm.names.numberingSystem }, + }); + }; + static NeverDestroyed descriptors { make_descriptors() }; - return descriptors; + return *descriptors; } DurationFormat::Style DurationFormat::style_from_string(StringView style) diff --git a/Libraries/LibJS/Runtime/Intl/Intl.cpp b/Libraries/LibJS/Runtime/Intl/Intl.cpp index c33a2e4c7c..e8b3c073f5 100644 --- a/Libraries/LibJS/Runtime/Intl/Intl.cpp +++ b/Libraries/LibJS/Runtime/Intl/Intl.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -137,14 +138,14 @@ JS_DEFINE_NATIVE_FUNCTION(Intl::supported_values_of) // 6. Else if key is "timeZone", then else if (key == "timeZone"sv) { // a. Let list be ! AvailablePrimaryTimeZoneIdentifiers( ). - static auto const time_zones = available_primary_time_zone_identifiers(); - list = time_zones.span(); + static NeverDestroyed> time_zones { available_primary_time_zone_identifiers() }; + list = time_zones->span(); } // 7. Else if key is "unit", then else if (key == "unit"sv) { // a. Let list be ! AvailableCanonicalUnits( ). - static auto const units = sanctioned_single_unit_identifiers(); - list = units.span(); + static NeverDestroyed> units { sanctioned_single_unit_identifiers() }; + list = units->span(); } // 8. Else, else { diff --git a/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp b/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp index 16af55adec..fc8c4b850b 100644 --- a/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp +++ b/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -49,11 +50,14 @@ ReadonlySpan NumberFormat::relevant_extension_keys() const ReadonlySpan NumberFormat::resolution_option_descriptors(VM& vm) const { // The value of the [[ResolutionOptionDescriptors]] internal slot is « { [[Key]]: "nu", [[Property]]: "numberingSystem" } ». - static auto descriptors = to_array({ - { .key = "nu"sv, .property = vm.names.numberingSystem }, - }); + auto make_descriptors = [&] { + return to_array({ + { .key = "nu"sv, .property = vm.names.numberingSystem }, + }); + }; + static NeverDestroyed descriptors { make_descriptors() }; - return descriptors; + return *descriptors; } StringView NumberFormatBase::computed_rounding_priority_string() const diff --git a/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp b/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp index 58cf374e76..9cd8e19891 100644 --- a/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp +++ b/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -31,11 +32,14 @@ ReadonlySpan RelativeTimeFormat::relevant_extension_keys() const ReadonlySpan RelativeTimeFormat::resolution_option_descriptors(VM& vm) const { // The value of the [[ResolutionOptionDescriptors]] internal slot is « { [[Key]]: "nu", [[Property]]: "numberingSystem" } ». - static auto descriptors = to_array({ - { .key = "nu"sv, .property = vm.names.numberingSystem }, - }); + auto make_descriptors = [&] { + return to_array({ + { .key = "nu"sv, .property = vm.names.numberingSystem }, + }); + }; + static NeverDestroyed descriptors { make_descriptors() }; - return descriptors; + return *descriptors; } // 18.5.1 SingularRelativeTimeUnit ( unit ), https://tc39.es/ecma402/#sec-singularrelativetimeunit diff --git a/Libraries/LibJS/Runtime/Iterator.cpp b/Libraries/LibJS/Runtime/Iterator.cpp index 9a1ab8cc3e..4cc54ffc02 100644 --- a/Libraries/LibJS/Runtime/Iterator.cpp +++ b/Libraries/LibJS/Runtime/Iterator.cpp @@ -51,7 +51,7 @@ void IteratorRecord::visit_edges(Cell::Visitor& visitor) ThrowCompletionOr> get_iterator_direct(VM& vm, Object& object) { // 1. Let nextMethod be ? Get(obj, "next"). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto next_method = TRY(object.get(vm.names.next, cache)); // 2. Let iteratorRecord be Record { [[Iterator]]: obj, [[NextMethod]]: nextMethod, [[Done]]: false }. @@ -70,7 +70,7 @@ ThrowCompletionOr get_iterator_from_method_impl(VM& vm, Valu return vm.throw_completion(ErrorType::NotIterable, object); // 3. Let nextMethod be ? Get(iterator, "next"). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto next_method = TRY(iterator.get(vm, vm.names.next, cache)); // 4. Let iteratorRecord be the Iterator Record { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }. @@ -99,7 +99,7 @@ ThrowCompletionOr get_iterator_impl(VM& vm, Value object, It // b. If method is undefined, then if (!method) { // i. Let syncMethod be ? GetMethod(obj, @@iterator). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto sync_method = TRY(object.get_method(vm, vm.well_known_symbol_iterator(), cache)); // ii. If syncMethod is undefined, throw a TypeError exception. @@ -116,7 +116,7 @@ ThrowCompletionOr get_iterator_impl(VM& vm, Value object, It // 2. Else, else { // a. Let method be ? GetMethod(obj, @@iterator). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; method = TRY(object.get_method(vm, vm.well_known_symbol_iterator(), cache)); } @@ -152,7 +152,7 @@ ThrowCompletionOr> get_iterator_flattenable(VM& vm, Valu } // 2. Let method be ? GetMethod(obj, %Symbol.iterator%). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto method = TRY(object.get_method(vm, vm.well_known_symbol_iterator(), cache)); Value iterator; @@ -221,7 +221,7 @@ ThrowCompletionOr> iterator_next(VM& vm, IteratorRecordImpl& ite ThrowCompletionOr iterator_complete(VM& vm, Object& iterator_result) { // 1. Return ToBoolean(? Get(iterResult, "done")). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; return TRY(iterator_result.get(vm.names.done, cache)).to_boolean(); } @@ -229,7 +229,7 @@ ThrowCompletionOr iterator_complete(VM& vm, Object& iterator_result) ThrowCompletionOr iterator_value(VM& vm, Object& iterator_result) { // 1. Return ? Get(iterResult, "value"). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; return TRY(iterator_result.get(vm.names.value, cache)); } @@ -251,7 +251,7 @@ ThrowCompletionOr iterator_step(VM& vm, IteratorRecordImp auto result = TRY(iterator_next(vm, iterator_record)); // 2. Let done be Completion(IteratorComplete(result)). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto done = result->get(vm.names.done, cache); // 3. If done is a throw completion, then @@ -276,7 +276,7 @@ ThrowCompletionOr iterator_step(VM& vm, IteratorRecordImp } // 6. Return result. - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; return ThrowCompletionOr { IterationResult { done_value, result->get(vm.names.value, cache2) } }; } diff --git a/Libraries/LibJS/Runtime/IteratorConstructor.cpp b/Libraries/LibJS/Runtime/IteratorConstructor.cpp index 8699f69710..8964196969 100644 --- a/Libraries/LibJS/Runtime/IteratorConstructor.cpp +++ b/Libraries/LibJS/Runtime/IteratorConstructor.cpp @@ -170,7 +170,7 @@ GC_DEFINE_ALLOCATOR(ConcatIterator); // 27.1.3.2.1 Iterator.concat ( ...items ), https://tc39.es/ecma262/#sec-iterator.concat JS_DEFINE_NATIVE_FUNCTION(IteratorConstructor::concat) { - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto& realm = *vm.current_realm(); // 1. Let iterables be a new empty List. diff --git a/Libraries/LibJS/Runtime/NumberPrototype.cpp b/Libraries/LibJS/Runtime/NumberPrototype.cpp index 847859aafa..d085f3bcbb 100644 --- a/Libraries/LibJS/Runtime/NumberPrototype.cpp +++ b/Libraries/LibJS/Runtime/NumberPrototype.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -98,9 +99,9 @@ static SignificandAndExponent compute_significand_and_exponent_with_precision(do { using Extractor = AK::FloatExtractor; - static auto ONE_BIGINT = 1_bigint; - static auto TWO_BIGINT = 2_bigint; - static auto TEN_BIGINT = 10_bigint; + static NeverDestroyed ONE_BIGINT { 1_bigint }; + static NeverDestroyed TWO_BIGINT { 2_bigint }; + static NeverDestroyed TEN_BIGINT { 10_bigint }; auto result = AK::convert_to_decimal_exponential_form(number); auto exponent = result.exponent + count_digits(result.fraction) - 1; @@ -134,7 +135,7 @@ static SignificandAndExponent compute_significand_and_exponent_with_precision(do // involves only unsigned integers. auto compute_significand = [&](i32 exponent) { auto numerator = binary_significand; - auto denominator = ONE_BIGINT; + auto denominator = *ONE_BIGINT; // 2 ^ binary_exponent if (binary_exponent > 0) @@ -144,9 +145,9 @@ static SignificandAndExponent compute_significand_and_exponent_with_precision(do // 10 ^ (precision - exponent - 1) if (auto scale = precision - exponent - 1; scale > 0) - numerator = numerator.multiplied_by(TEN_BIGINT.pow(scale)); + numerator = numerator.multiplied_by(TEN_BIGINT->pow(scale)); else if (scale < 0) - denominator = denominator.multiplied_by(TEN_BIGINT.pow(-scale)); + denominator = denominator.multiplied_by(TEN_BIGINT->pow(-scale)); auto [quotient, remainder] = numerator.divided_by(denominator); @@ -191,18 +192,18 @@ static SignificandAndExponent compute_significand_and_exponent_with_precision(do // // Similar to `compute_significand` above, we take care to clear any negative exponents to ensure that the math // involves only unsigned integers. - if (significand == TEN_BIGINT.pow(precision - 1)) { + if (significand == TEN_BIGINT->pow(precision - 1)) { auto alternate = compute_significand(exponent - 1); if (alternate.count_digits_in_base(10) == static_cast(precision)) { - auto lhs = significand.multiplied_by(TEN_BIGINT).plus(alternate); - auto rhs = TWO_BIGINT.multiplied_by(binary_significand); + auto lhs = significand.multiplied_by(*TEN_BIGINT).plus(alternate); + auto rhs = TWO_BIGINT->multiplied_by(binary_significand); // 10 ^ (exponent - precision) if (auto scale = exponent - precision; scale > 0) - lhs = lhs.multiplied_by(TEN_BIGINT.pow(scale)); + lhs = lhs.multiplied_by(TEN_BIGINT->pow(scale)); else if (scale < 0) - rhs = rhs.multiplied_by(TEN_BIGINT.pow(-scale)); + rhs = rhs.multiplied_by(TEN_BIGINT->pow(-scale)); // 2 ^ binary_exponent if (binary_exponent > 0) @@ -224,8 +225,8 @@ static Crypto::UnsignedBigInteger compute_to_fixed_scaled_integer(double number, { using Extractor = AK::FloatExtractor; - static auto ONE_BIGINT = 1_bigint; - static auto FIVE_BIGINT = 5_bigint; + static NeverDestroyed ONE_BIGINT { 1_bigint }; + static NeverDestroyed FIVE_BIGINT { 5_bigint }; // Decompose the number into its exact binary representation. An IEEE-754 double is exactly equal to: // @@ -244,12 +245,12 @@ static Crypto::UnsignedBigInteger compute_to_fixed_scaled_integer(double number, binary_exponent = extractor.exponent - Extractor::exponent_bias - Extractor::mantissa_bits; } - auto numerator = binary_significand.multiplied_by(FIVE_BIGINT.pow(fraction_digits)); + auto numerator = binary_significand.multiplied_by(FIVE_BIGINT->pow(fraction_digits)); auto binary_scale = binary_exponent + static_cast(fraction_digits); if (binary_scale >= 0) return MUST(numerator.shift_left(static_cast(binary_scale))); - auto denominator = MUST(ONE_BIGINT.shift_left(static_cast(-binary_scale))); + auto denominator = MUST(ONE_BIGINT->shift_left(static_cast(-binary_scale))); auto [quotient, remainder] = numerator.divided_by(denominator); // Pick the larger integer if x * 10^f is exactly between two candidates. diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp index fc84c6610d..b72c364cff 100644 --- a/Libraries/LibJS/Runtime/Object.cpp +++ b/Libraries/LibJS/Runtime/Object.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -34,7 +35,11 @@ namespace JS { GC_DEFINE_ALLOCATOR(Object); -static GC::WeakHashMap, HashMap> s_intrinsics; +static auto& intrinsic_accessor_map() +{ + static NeverDestroyed, HashMap>> intrinsics; + return *intrinsics; +} // Heap-allocated named property storage layout: // [u32 capacity] [u32 padding] [Value 0] [Value 1] ... @@ -165,7 +170,7 @@ Object::~Object() { free_indexed_elements(); if (has_intrinsic_accessors()) - s_intrinsics.remove(this); + intrinsic_accessor_map().remove(this); if (!named_storage_is_inline()) free_heap_named_storage(m_named_properties); } @@ -1281,7 +1286,7 @@ static Optional find_intrinsic_accessor(Object const* if (!property_key.is_string()) return {}; - auto intrinsics = s_intrinsics.get(object); + auto intrinsics = intrinsic_accessor_map().get(object); if (!intrinsics.has_value()) return {}; @@ -1347,7 +1352,7 @@ Optional Object::storage_set(PropertyKey const& property_key, ValueAndAttri } if (has_intrinsic_accessors() && property_key.is_string()) { - if (auto intrinsics = s_intrinsics.get(this); intrinsics.has_value()) + if (auto intrinsics = intrinsic_accessor_map().get(this); intrinsics.has_value()) intrinsics->remove(property_key.as_string()); } @@ -1387,7 +1392,7 @@ void Object::storage_delete(PropertyKey const& property_key) return indexed_delete(property_key.as_number()); if (has_intrinsic_accessors() && property_key.is_string()) { - if (auto intrinsics = s_intrinsics.get(this); intrinsics.has_value()) + if (auto intrinsics = intrinsic_accessor_map().get(this); intrinsics.has_value()) intrinsics->remove(property_key.as_string()); } @@ -1456,7 +1461,7 @@ void Object::define_intrinsic_accessor(PropertyKey const& property_key, Property (void)storage_set(property_key, { {}, attributes }); set_has_intrinsic_accessors(); - auto& intrinsics = s_intrinsics.ensure(this); + auto& intrinsics = intrinsic_accessor_map().ensure(this); intrinsics.set(property_key.as_string(), move(accessor)); } @@ -1697,11 +1702,11 @@ ThrowCompletionOr Object::ordinary_to_primitive(Value::PreferredType pref // a. Let method be ? Get(O, name). Value method; if (method_name == vm.names.toString) { - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; method = TRY(get(method_name, cache)); } else { ASSERT(method_name == vm.names.valueOf); - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; method = TRY(get(method_name, cache)); } diff --git a/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Libraries/LibJS/Runtime/ObjectPrototype.cpp index 3f0d5580d6..0ae7f9a905 100644 --- a/Libraries/LibJS/Runtime/ObjectPrototype.cpp +++ b/Libraries/LibJS/Runtime/ObjectPrototype.cpp @@ -182,7 +182,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::to_string) builtin_tag = "Object"sv; // 15. Let tag be ? Get(O, @@toStringTag). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto to_string_tag = TRY(object->get(vm.well_known_symbol_to_string_tag(), cache)); // Optimization: Instead of creating another PrimitiveString from builtin_tag, we separate tag and to_string_tag and add an additional branch to step 16. diff --git a/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Libraries/LibJS/Runtime/RegExpPrototype.cpp index 8efc8cd522..5883ad6cf5 100644 --- a/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -62,7 +63,7 @@ void RegExpPrototype::initialize(Realm& realm) static ThrowCompletionOr increment_last_index(VM& vm, Object& regexp_object, Utf16View const& string, bool unicode) { // Let thisIndex be ℝ(? ToLength(? Get(rx, "lastIndex"))). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto last_index_value = TRY(regexp_object.get(vm.names.lastIndex, cache)); auto last_index = TRY(last_index_value.to_length(vm)); @@ -70,13 +71,17 @@ static ThrowCompletionOr increment_last_index(VM& vm, Object& regexp_objec last_index = advance_string_index(string, last_index, unicode); // Perform ? Set(rx, "lastIndex", 𝔽(nextIndex), true). - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; TRY(regexp_object.set(vm.names.lastIndex, Value(last_index), cache2)); return {}; } // FIXME: Add an eviction policy to bound the size of this cache. -static HashMap> s_regex_cache; +static auto& regex_cache() +{ + static NeverDestroyed>> cache; + return *cache; +} static regex::ECMAScriptRegex const* get_or_compile_regex(RegExpObject& regexp_object) { @@ -95,7 +100,7 @@ static regex::ECMAScriptRegex const* get_or_compile_regex(RegExpObject& regexp_o key_builder.append_code_point(static_cast(flag_bits)); auto cache_key = key_builder.to_string_without_validation(); - if (auto it = s_regex_cache.find(cache_key); it != s_regex_cache.end()) { + if (auto it = regex_cache().find(cache_key); it != regex_cache().end()) { auto* ptr = it->value.ptr(); regexp_object.set_cached_regex(ptr); return ptr; @@ -125,7 +130,7 @@ static regex::ECMAScriptRegex const* get_or_compile_regex(RegExpObject& regexp_o auto owned = make(compiled.release_value()); auto* ptr = owned.ptr(); - s_regex_cache.set(cache_key, move(owned)); + regex_cache().set(cache_key, move(owned)); regexp_object.set_cached_regex(ptr); return ptr; } @@ -189,7 +194,7 @@ static ThrowCompletionOr regexp_builtin_exec(VM& vm, RegExpObject& regexp { auto& realm = *vm.current_realm(); - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto last_index_value = TRY(regexp_object.get(vm.names.lastIndex, cache)); auto last_index = TRY(last_index_value.to_length(vm)); @@ -205,7 +210,7 @@ static ThrowCompletionOr regexp_builtin_exec(VM& vm, RegExpObject& regexp if (last_index > string->length_in_utf16_code_units()) { if (sticky || global) { - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; TRY(regexp_object.set(vm.names.lastIndex, Value(0), cache2)); } return js_null(); @@ -231,7 +236,7 @@ static ThrowCompletionOr regexp_builtin_exec(VM& vm, RegExpObject& regexp if (!matched) { if (sticky || global) { - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; TRY(regexp_object.set(vm.names.lastIndex, Value(0), cache2)); } return js_null(); @@ -244,7 +249,7 @@ static ThrowCompletionOr regexp_builtin_exec(VM& vm, RegExpObject& regexp // In Unicode mode, match_index and end_index are already in code unit indices from the VM. // Update lastIndex. if (global || sticky) { - static Bytecode::StaticPropertyLookupCache cache3; + static auto& cache3 = *new Bytecode::StaticPropertyLookupCache; TRY(regexp_object.set(vm.names.lastIndex, Value(end_index), cache3)); } @@ -315,7 +320,7 @@ static ThrowCompletionOr regexp_builtin_exec(VM& vm, RegExpObject& regexp MUST(groups.as_object().create_data_property_or_throw(group_name, value)); } - static Bytecode::StaticPropertyLookupCache cache4; + static auto& cache4 = *new Bytecode::StaticPropertyLookupCache; MUST(array->set(vm.names.groups, groups, cache4)); } @@ -391,7 +396,7 @@ static ThrowCompletionOr regexp_builtin_exec(VM& vm, RegExpObject& regexp ThrowCompletionOr regexp_exec(VM& vm, Object& regexp_object, GC::Ref string) { // 1. Let exec be ? Get(R, "exec"). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto exec = TRY(regexp_object.get(vm.names.exec, cache)); auto* typed_regexp_object = as_if(regexp_object); @@ -514,7 +519,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::flags) // 19. If sticky is true, append the code unit 0x0079 (LATIN SMALL LETTER Y) as the last code unit of result. #define __JS_ENUMERATE(FlagName, flagName, flag_name, flag_char) \ { \ - static Bytecode::StaticPropertyLookupCache cache; \ + static auto& cache = *new Bytecode::StaticPropertyLookupCache; \ auto flag_##flag_name = TRY(regexp_object->get(vm.names.flagName, cache)); \ if (flag_##flag_name.to_boolean()) \ builder.append(#flag_char##sv); \ @@ -539,7 +544,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match) auto string = TRY(vm.argument(0).to_primitive_string(vm)); // 4. Let flags be ? ToString(? Get(rx, "flags")). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto flags_value = TRY(regexp_object->get(vm.names.flags, cache)); auto flags = TRY(flags_value.to_string(vm)); @@ -554,7 +559,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match) bool full_unicode = flags.contains('u') || flags.contains('v'); // b. Perform ? Set(rx, "lastIndex", +0𝔽, true). - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; TRY(regexp_object->set(vm.names.lastIndex, Value(0), cache2)); // c. Let A be ! ArrayCreate(0). @@ -617,7 +622,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all) auto* constructor = TRY(species_constructor(vm, regexp_object, realm.intrinsics().regexp_constructor())); // 5. Let flags be ? ToString(? Get(R, "flags")). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto flags_value = TRY(regexp_object->get(vm.names.flags, cache)); auto flags = TRY(flags_value.to_string(vm)); @@ -635,12 +640,12 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all) auto matcher = TRY(construct(vm, *constructor, regexp_object, PrimitiveString::create(vm, move(flags)))); // 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")). - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; auto last_index_value = TRY(regexp_object->get(vm.names.lastIndex, cache2)); auto last_index = TRY(last_index_value.to_length(vm)); // 8. Perform ? Set(matcher, "lastIndex", lastIndex, true). - static Bytecode::StaticPropertyLookupCache cache3; + static auto& cache3 = *new Bytecode::StaticPropertyLookupCache; TRY(matcher->set(vm.names.lastIndex, Value(last_index), cache3)); // 13. Return CreateRegExpStringIterator(matcher, S, global, fullUnicode). @@ -675,7 +680,7 @@ ThrowCompletionOr RegExpPrototype::symbol_replace_impl(VM& vm, Object& re auto& realm = *vm.current_realm(); bool exec_is_builtin = false; if (typed_regexp) { - static Bytecode::StaticPropertyLookupCache exec_cache; + static auto& exec_cache = *new Bytecode::StaticPropertyLookupCache; auto exec_val = TRY(regexp_object.get(vm.names.exec, exec_cache)); if (auto exec_fn = exec_val.as_if()) exec_is_builtin = exec_fn->builtin() == Bytecode::Builtin::RegExpPrototypeExec; @@ -715,11 +720,11 @@ ThrowCompletionOr RegExpPrototype::symbol_replace_impl(VM& vm, Object& re // fast path (e.g. redefining exec). Do the Get and re-check exec. bool fast_path_valid = true; if (is_global) { - static Bytecode::StaticPropertyLookupCache unicode_cache; + static auto& unicode_cache = *new Bytecode::StaticPropertyLookupCache; auto unicode_val = TRY(regexp_object.get(vm.names.unicode, unicode_cache)); full_unicode = unicode_val.to_boolean(); // Re-verify exec is still the builtin after potential side effects. - static Bytecode::StaticPropertyLookupCache exec_recheck; + static auto& exec_recheck = *new Bytecode::StaticPropertyLookupCache; auto exec_val2 = TRY(regexp_object.get(vm.names.exec, exec_recheck)); auto exec_fn2 = exec_val2.as_if(); if (!exec_fn2 || exec_fn2->builtin() != Bytecode::Builtin::RegExpPrototypeExec) @@ -733,7 +738,7 @@ ThrowCompletionOr RegExpPrototype::symbol_replace_impl(VM& vm, Object& re size_t last_index = 0; if (is_global || is_sticky) { - static Bytecode::StaticPropertyLookupCache li_cache; + static auto& li_cache = *new Bytecode::StaticPropertyLookupCache; auto li_value = TRY(typed_regexp->get(vm.names.lastIndex, li_cache)); last_index = TRY(li_value.to_length(vm)); } @@ -780,7 +785,7 @@ ThrowCompletionOr RegExpPrototype::symbol_replace_impl(VM& vm, Object& re while (true) { if (last_index > length_s) { if (is_sticky || is_global) { - static Bytecode::StaticPropertyLookupCache li_cache2; + static auto& li_cache2 = *new Bytecode::StaticPropertyLookupCache; TRY(typed_regexp->set(vm.names.lastIndex, Value(0), li_cache2)); } break; @@ -797,7 +802,7 @@ ThrowCompletionOr RegExpPrototype::symbol_replace_impl(VM& vm, Object& re if (!matched) { if (is_sticky || is_global) { - static Bytecode::StaticPropertyLookupCache li_cache2; + static auto& li_cache2 = *new Bytecode::StaticPropertyLookupCache; TRY(typed_regexp->set(vm.names.lastIndex, Value(0), li_cache2)); } break; @@ -814,7 +819,7 @@ ThrowCompletionOr RegExpPrototype::symbol_replace_impl(VM& vm, Object& re // For global, lastIndex is always reset to 0 after the loop, // so skip intermediate updates. if (is_sticky && !is_global) { - static Bytecode::StaticPropertyLookupCache li_cache3; + static auto& li_cache3 = *new Bytecode::StaticPropertyLookupCache; TRY(typed_regexp->set(vm.names.lastIndex, Value(match_end), li_cache3)); } @@ -888,7 +893,7 @@ ThrowCompletionOr RegExpPrototype::symbol_replace_impl(VM& vm, Object& re } // 7. Let flags be ? ToString(? Get(rx, "flags")). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto flags_value = TRY(regexp_object.get(vm.names.flags, cache)); auto flags = TRY(flags_value.to_string(vm)); @@ -898,7 +903,7 @@ ThrowCompletionOr RegExpPrototype::symbol_replace_impl(VM& vm, Object& re // 9. If global is true, then if (global) { // a. Perform ? Set(rx, "lastIndex", +0𝔽, true). - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; TRY(regexp_object.set(vm.names.lastIndex, Value(0), cache2)); } @@ -962,7 +967,7 @@ ThrowCompletionOr RegExpPrototype::symbol_replace_impl(VM& vm, Object& re auto matched_length = matched->length_in_utf16_code_units(); // e. Let position be ? ToIntegerOrInfinity(? Get(result, "index")). - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; auto position_value = TRY(result->get(vm.names.index, cache2)); double position = TRY(position_value.to_integer_or_infinity(vm)); @@ -992,7 +997,7 @@ ThrowCompletionOr RegExpPrototype::symbol_replace_impl(VM& vm, Object& re } // j. Let namedCaptures be ? Get(result, "groups"). - static Bytecode::StaticPropertyLookupCache cache3; + static auto& cache3 = *new Bytecode::StaticPropertyLookupCache; auto named_captures = TRY(result->get(vm.names.groups, cache3)); String replacement; @@ -1066,13 +1071,13 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_search) auto string = TRY(vm.argument(0).to_primitive_string(vm)); // 4. Let previousLastIndex be ? Get(rx, "lastIndex"). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto previous_last_index = TRY(regexp_object->get(vm.names.lastIndex, cache)); // 5. If SameValue(previousLastIndex, +0𝔽) is false, then if (!same_value(previous_last_index, Value(0))) { // a. Perform ? Set(rx, "lastIndex", +0𝔽, true). - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; TRY(regexp_object->set(vm.names.lastIndex, Value(0), cache2)); } @@ -1080,13 +1085,13 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_search) auto result = TRY(regexp_exec(vm, regexp_object, string)); // 7. Let currentLastIndex be ? Get(rx, "lastIndex"). - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; auto current_last_index = TRY(regexp_object->get(vm.names.lastIndex, cache2)); // 8. If SameValue(currentLastIndex, previousLastIndex) is false, then if (!same_value(current_last_index, previous_last_index)) { // a. Perform ? Set(rx, "lastIndex", previousLastIndex, true). - static Bytecode::StaticPropertyLookupCache cache3; + static auto& cache3 = *new Bytecode::StaticPropertyLookupCache; TRY(regexp_object->set(vm.names.lastIndex, previous_last_index, cache3)); } @@ -1095,7 +1100,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_search) return Value(-1); // 10. Return ? Get(result, "index"). - static Bytecode::StaticPropertyLookupCache cache3; + static auto& cache3 = *new Bytecode::StaticPropertyLookupCache; return TRY(result.get(vm, vm.names.index, cache3)); } @@ -1149,7 +1154,7 @@ ThrowCompletionOr RegExpPrototype::symbol_split_impl(VM& vm, Object& rege auto* typed_regexp = as_if(regexp_object); bool exec_is_builtin = false; if (typed_regexp) { - static Bytecode::StaticPropertyLookupCache exec_cache; + static auto& exec_cache = *new Bytecode::StaticPropertyLookupCache; auto exec_val = TRY(regexp_object.get(vm.names.exec, exec_cache)); if (auto exec_fn = exec_val.as_if()) exec_is_builtin = exec_fn->builtin() == Bytecode::Builtin::RegExpPrototypeExec; @@ -1285,7 +1290,7 @@ ThrowCompletionOr RegExpPrototype::symbol_split_impl(VM& vm, Object& rege auto* constructor = TRY(species_constructor(vm, regexp_object, realm.intrinsics().regexp_constructor())); // 5. Let flags be ? ToString(? Get(rx, "flags")). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto flags_value = TRY(regexp_object.get(vm.names.flags, cache)); auto flags = TRY(flags_value.to_string(vm)); @@ -1342,7 +1347,7 @@ ThrowCompletionOr RegExpPrototype::symbol_split_impl(VM& vm, Object& rege // 19. Repeat, while q < size, while (next_search_from < string->length_in_utf16_code_units()) { // a. Perform ? Set(splitter, "lastIndex", 𝔽(q), SplitBehavior::KeepEmpty). - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; TRY(splitter->set(vm.names.lastIndex, Value(next_search_from), cache2)); // b. Let z be ? RegExpExec(splitter, S). @@ -1357,7 +1362,7 @@ ThrowCompletionOr RegExpPrototype::symbol_split_impl(VM& vm, Object& rege // d. Else, // i. Let e be ℝ(? ToLength(? Get(splitter, "lastIndex"))). - static Bytecode::StaticPropertyLookupCache cache3; + static auto& cache3 = *new Bytecode::StaticPropertyLookupCache; auto last_index_value = TRY(splitter->get(vm.names.lastIndex, cache3)); auto last_index = TRY(last_index_value.to_length(vm)); @@ -1441,7 +1446,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::test) auto& realm = *vm.current_realm(); bool exec_is_builtin = false; if (typed_regexp) { - static Bytecode::StaticPropertyLookupCache exec_cache; + static auto& exec_cache = *new Bytecode::StaticPropertyLookupCache; auto exec_val = TRY(regexp_object->get(vm.names.exec, exec_cache)); if (auto exec_fn = exec_val.as_if()) exec_is_builtin = exec_fn->builtin() == Bytecode::Builtin::RegExpPrototypeExec; @@ -1513,12 +1518,12 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::to_string) auto regexp_object = TRY(this_object(vm)); // 3. Let pattern be ? ToString(? Get(R, "source")). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto source_attr = TRY(regexp_object->get(vm.names.source, cache)); auto pattern = TRY(source_attr.to_string(vm)); // 4. Let flags be ? ToString(? Get(R, "flags")). - static Bytecode::StaticPropertyLookupCache cache2; + static auto& cache2 = *new Bytecode::StaticPropertyLookupCache; auto flags_attr = TRY(regexp_object->get(vm.names.flags, cache2)); auto flags = TRY(flags_attr.to_string(vm)); diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp index 7ee8807c22..4d0f73530a 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -631,7 +631,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match) auto regexp = vm.argument(0); if (regexp.is_object()) { // a. Let matcher be ? GetMethod(regexp, @@match). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto matcher = TRY(regexp.get_method(vm, vm.well_known_symbol_match(), cache)); // b. If matcher is not undefined, then @@ -679,7 +679,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all) } // c. Let matcher be ? GetMethod(regexp, @@matchAll). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto matcher = TRY(regexp.get_method(vm, vm.well_known_symbol_match_all(), cache)); // d. If matcher is not undefined, then @@ -850,7 +850,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace) // 2. If searchValue is an Object, then if (search_value.is_object()) { // a. Let replacer be ? GetMethod(searchValue, @@replace). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto replacer = TRY(search_value.get_method(vm, vm.well_known_symbol_replace(), cache)); // b. If replacer is not undefined, then @@ -952,7 +952,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all) } // c. Let replacer be ? GetMethod(searchValue, @@replace). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto replacer = TRY(search_value.get_method(vm, vm.well_known_symbol_replace(), cache)); // d. If replacer is not undefined, then @@ -1059,7 +1059,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::search) // 2. If regexp is an Object, then if (regexp.is_object()) { // a. Let searcher be ? GetMethod(regexp, @@search). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto searcher = TRY(regexp.get_method(vm, vm.well_known_symbol_search(), cache)); // b. If searcher is not undefined, then @@ -1144,7 +1144,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split) // 3. If separator is an Object, then if (separator_argument.is_object()) { // a. Let splitter be ? GetMethod(separator, @@split). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto splitter = TRY(separator_argument.get_method(vm, vm.well_known_symbol_split(), cache)); // b. If splitter is not undefined, then if (splitter) { diff --git a/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp b/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp index 11b9ca621b..75bd374f45 100644 --- a/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp +++ b/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp @@ -7,6 +7,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -382,7 +383,7 @@ ThrowCompletionOr get_temporal_unit_valued_option(VM& vm, Object cons // 2. Append "auto" to allowedStrings. // 3. NOTE: For each singular Temporal unit name that is contained within allowedStrings, the corresponding plural // name is also contained within it. - static auto allowed_strings = [&]() { + static NeverDestroyed> allowed_strings { [&]() { Vector allowed_strings; allowed_strings.ensure_capacity((temporal_units.size() * 2) + 1); @@ -393,7 +394,7 @@ ThrowCompletionOr get_temporal_unit_valued_option(VM& vm, Object cons allowed_strings.unchecked_append("auto"sv); return allowed_strings; - }(); + }() }; // 4. If default is UNSET, then // a. Let defaultValue be undefined. @@ -406,7 +407,7 @@ ThrowCompletionOr get_temporal_unit_valued_option(VM& vm, Object cons [](Unit unit) -> OptionDefault { return temporal_unit_to_string(unit); }); // 6. Let value be ? GetOption(options, key, STRING, allowedStrings, defaultValue). - auto value = TRY(get_option(vm, options, key, OptionType::String, allowed_strings, default_value)); + auto value = TRY(get_option(vm, options, key, OptionType::String, *allowed_strings, default_value)); // 7. If value is undefined, return UNSET. if (value.is_undefined()) diff --git a/Libraries/LibJS/Runtime/Temporal/Calendar.cpp b/Libraries/LibJS/Runtime/Temporal/Calendar.cpp index 93f6de829c..5c89a6657e 100644 --- a/Libraries/LibJS/Runtime/Temporal/Calendar.cpp +++ b/Libraries/LibJS/Runtime/Temporal/Calendar.cpp @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -292,7 +293,7 @@ Vector const& available_calendars() // in canonical form (12.1) identifying the calendars for which the implementation provides the functionality of // Intl.DateTimeFormat objects, including their aliases (e.g., both "islamicc" and "islamic-civil"). The List must // consist of the "Calendar Type" value of every row of Table 1, except the header row. - static auto calendars = []() { + static NeverDestroyed> calendars { []() { auto calendars = Unicode::available_calendars(); for (auto calendar : CLDR_CALENDAR_TYPES) { @@ -302,9 +303,9 @@ Vector const& available_calendars() quick_sort(calendars); return calendars; - }(); + }() }; - return calendars; + return *calendars; } // 12.2.1 ParseMonthCode ( argument ), https://tc39.es/proposal-temporal/#sec-temporal-parsemonthcode diff --git a/Libraries/LibJS/Runtime/Temporal/Duration.cpp b/Libraries/LibJS/Runtime/Temporal/Duration.cpp index e8a481939b..b6bf3a51e7 100644 --- a/Libraries/LibJS/Runtime/Temporal/Duration.cpp +++ b/Libraries/LibJS/Runtime/Temporal/Duration.cpp @@ -72,7 +72,7 @@ Duration::Duration(double years, double months, double weeks, double days, doubl } // maxTimeDuration = 2**53 × 10**9 - 1 = 9,007,199,254,740,991,999,999,999 -TimeDuration const MAX_TIME_DURATION = "9007199254740991999999999"_sbigint; +TimeDuration const& MAX_TIME_DURATION = *new TimeDuration("9007199254740991999999999"_sbigint); // 7.5.4 ZeroDateDuration ( ), https://tc39.es/proposal-temporal/#sec-temporal-zerodateduration DateDuration zero_date_duration(VM& vm) diff --git a/Libraries/LibJS/Runtime/Temporal/Duration.h b/Libraries/LibJS/Runtime/Temporal/Duration.h index 5217c7bca6..98f068b9ac 100644 --- a/Libraries/LibJS/Runtime/Temporal/Duration.h +++ b/Libraries/LibJS/Runtime/Temporal/Duration.h @@ -89,7 +89,7 @@ struct PartialDuration { Optional nanoseconds; }; -extern TimeDuration const MAX_TIME_DURATION; +extern TimeDuration const& MAX_TIME_DURATION; // 7.5.3 Internal Duration Records, https://tc39.es/proposal-temporal/#sec-temporal-internal-duration-records struct InternalDuration { diff --git a/Libraries/LibJS/Runtime/Temporal/Instant.cpp b/Libraries/LibJS/Runtime/Temporal/Instant.cpp index 152cdc81f5..730828334f 100644 --- a/Libraries/LibJS/Runtime/Temporal/Instant.cpp +++ b/Libraries/LibJS/Runtime/Temporal/Instant.cpp @@ -40,27 +40,27 @@ void Instant::visit_edges(Cell::Visitor& visitor) } // nsMaxInstant = 10**8 × nsPerDay = 8.64 × 10**21 -Crypto::SignedBigInteger const NANOSECONDS_MAX_INSTANT = "8640000000000000000000"_sbigint; +Crypto::SignedBigInteger const& NANOSECONDS_MAX_INSTANT = *new Crypto::SignedBigInteger("8640000000000000000000"_sbigint); // nsMinInstant = -nsMaxInstant = -8.64 × 10**21 -Crypto::SignedBigInteger const NANOSECONDS_MIN_INSTANT = "-8640000000000000000000"_sbigint; +Crypto::SignedBigInteger const& NANOSECONDS_MIN_INSTANT = *new Crypto::SignedBigInteger("-8640000000000000000000"_sbigint); // nsPerDay = 10**6 × ℝ(msPerDay) = 8.64 × 10**13 -Crypto::UnsignedBigInteger const NANOSECONDS_PER_DAY = 86400000000000_bigint; +Crypto::UnsignedBigInteger const& NANOSECONDS_PER_DAY = *new Crypto::UnsignedBigInteger(86400000000000_bigint); // Non-standard: -Crypto::UnsignedBigInteger const NANOSECONDS_PER_HOUR = 3600000000000_bigint; -Crypto::UnsignedBigInteger const NANOSECONDS_PER_MINUTE = 60000000000_bigint; -Crypto::UnsignedBigInteger const NANOSECONDS_PER_SECOND = 1000000000_bigint; -Crypto::UnsignedBigInteger const NANOSECONDS_PER_MILLISECOND = 1000000_bigint; -Crypto::UnsignedBigInteger const NANOSECONDS_PER_MICROSECOND = 1000_bigint; -Crypto::UnsignedBigInteger const NANOSECONDS_PER_NANOSECOND = 1_bigint; +Crypto::UnsignedBigInteger const& NANOSECONDS_PER_HOUR = *new Crypto::UnsignedBigInteger(3600000000000_bigint); +Crypto::UnsignedBigInteger const& NANOSECONDS_PER_MINUTE = *new Crypto::UnsignedBigInteger(60000000000_bigint); +Crypto::UnsignedBigInteger const& NANOSECONDS_PER_SECOND = *new Crypto::UnsignedBigInteger(1000000000_bigint); +Crypto::UnsignedBigInteger const& NANOSECONDS_PER_MILLISECOND = *new Crypto::UnsignedBigInteger(1000000_bigint); +Crypto::UnsignedBigInteger const& NANOSECONDS_PER_MICROSECOND = *new Crypto::UnsignedBigInteger(1000_bigint); +Crypto::UnsignedBigInteger const& NANOSECONDS_PER_NANOSECOND = *new Crypto::UnsignedBigInteger(1_bigint); -Crypto::UnsignedBigInteger const MICROSECONDS_PER_MILLISECOND = 1000_bigint; -Crypto::UnsignedBigInteger const MILLISECONDS_PER_SECOND = 1000_bigint; -Crypto::UnsignedBigInteger const SECONDS_PER_MINUTE = 60_bigint; -Crypto::UnsignedBigInteger const MINUTES_PER_HOUR = 60_bigint; -Crypto::UnsignedBigInteger const HOURS_PER_DAY = 24_bigint; +Crypto::UnsignedBigInteger const& MICROSECONDS_PER_MILLISECOND = *new Crypto::UnsignedBigInteger(1000_bigint); +Crypto::UnsignedBigInteger const& MILLISECONDS_PER_SECOND = *new Crypto::UnsignedBigInteger(1000_bigint); +Crypto::UnsignedBigInteger const& SECONDS_PER_MINUTE = *new Crypto::UnsignedBigInteger(60_bigint); +Crypto::UnsignedBigInteger const& MINUTES_PER_HOUR = *new Crypto::UnsignedBigInteger(60_bigint); +Crypto::UnsignedBigInteger const& HOURS_PER_DAY = *new Crypto::UnsignedBigInteger(24_bigint); // 8.5.1 IsValidEpochNanoseconds ( epochNanoseconds ), https://tc39.es/proposal-temporal/#sec-temporal-isvalidepochnanoseconds bool is_valid_epoch_nanoseconds(Crypto::SignedBigInteger const& epoch_nanoseconds) diff --git a/Libraries/LibJS/Runtime/Temporal/Instant.h b/Libraries/LibJS/Runtime/Temporal/Instant.h index 8fcf1e9e6a..48863676c8 100644 --- a/Libraries/LibJS/Runtime/Temporal/Instant.h +++ b/Libraries/LibJS/Runtime/Temporal/Instant.h @@ -34,27 +34,27 @@ private: }; // https://tc39.es/proposal-temporal/#eqn-nsMaxInstant -extern Crypto::SignedBigInteger const NANOSECONDS_MAX_INSTANT; +extern Crypto::SignedBigInteger const& NANOSECONDS_MAX_INSTANT; // https://tc39.es/proposal-temporal/#eqn-nsMinInstant -extern Crypto::SignedBigInteger const NANOSECONDS_MIN_INSTANT; +extern Crypto::SignedBigInteger const& NANOSECONDS_MIN_INSTANT; // https://tc39.es/proposal-temporal/#eqn-nsPerDay -extern Crypto::UnsignedBigInteger const NANOSECONDS_PER_DAY; +extern Crypto::UnsignedBigInteger const& NANOSECONDS_PER_DAY; // Non-standard: -extern Crypto::UnsignedBigInteger const NANOSECONDS_PER_HOUR; -extern Crypto::UnsignedBigInteger const NANOSECONDS_PER_MINUTE; -extern Crypto::UnsignedBigInteger const NANOSECONDS_PER_SECOND; -extern Crypto::UnsignedBigInteger const NANOSECONDS_PER_MILLISECOND; -extern Crypto::UnsignedBigInteger const NANOSECONDS_PER_MICROSECOND; -extern Crypto::UnsignedBigInteger const NANOSECONDS_PER_NANOSECOND; +extern Crypto::UnsignedBigInteger const& NANOSECONDS_PER_HOUR; +extern Crypto::UnsignedBigInteger const& NANOSECONDS_PER_MINUTE; +extern Crypto::UnsignedBigInteger const& NANOSECONDS_PER_SECOND; +extern Crypto::UnsignedBigInteger const& NANOSECONDS_PER_MILLISECOND; +extern Crypto::UnsignedBigInteger const& NANOSECONDS_PER_MICROSECOND; +extern Crypto::UnsignedBigInteger const& NANOSECONDS_PER_NANOSECOND; -extern Crypto::UnsignedBigInteger const MICROSECONDS_PER_MILLISECOND; -extern Crypto::UnsignedBigInteger const MILLISECONDS_PER_SECOND; -extern Crypto::UnsignedBigInteger const SECONDS_PER_MINUTE; -extern Crypto::UnsignedBigInteger const MINUTES_PER_HOUR; -extern Crypto::UnsignedBigInteger const HOURS_PER_DAY; +extern Crypto::UnsignedBigInteger const& MICROSECONDS_PER_MILLISECOND; +extern Crypto::UnsignedBigInteger const& MILLISECONDS_PER_SECOND; +extern Crypto::UnsignedBigInteger const& SECONDS_PER_MINUTE; +extern Crypto::UnsignedBigInteger const& MINUTES_PER_HOUR; +extern Crypto::UnsignedBigInteger const& HOURS_PER_DAY; bool is_valid_epoch_nanoseconds(Crypto::SignedBigInteger const& epoch_nanoseconds); ThrowCompletionOr> create_temporal_instant(VM&, BigInt const& epoch_nanoseconds, GC::Ptr new_target = {}); diff --git a/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp b/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp index 7236d04fce..b692ed304f 100644 --- a/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp +++ b/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -51,10 +52,18 @@ ISODateTime combine_iso_date_and_time_record(ISODate iso_date, Time const& time) } // nsMinInstant - nsPerDay -static auto const DATETIME_NANOSECONDS_MIN = "-8640000086400000000000"_sbigint; +static auto const& datetime_nanoseconds_min() +{ + static NeverDestroyed value { "-8640000086400000000000"_sbigint }; + return *value; +} // nsMaxInstant + nsPerDay -static auto const DATETIME_NANOSECONDS_MAX = "8640000086400000000000"_sbigint; +static auto const& datetime_nanoseconds_max() +{ + static NeverDestroyed value { "8640000086400000000000"_sbigint }; + return *value; +} // 5.5.4 ISODateTimeWithinLimits ( isoDateTime ), https://tc39.es/proposal-temporal/#sec-temporal-isodatetimewithinlimits bool iso_date_time_within_limits(ISODateTime const& iso_date_time) @@ -67,11 +76,11 @@ bool iso_date_time_within_limits(ISODateTime const& iso_date_time) auto nanoseconds = get_utc_epoch_nanoseconds(iso_date_time); // 3. If ns ≤ nsMinInstant - nsPerDay, return false. - if (nanoseconds <= DATETIME_NANOSECONDS_MIN) + if (nanoseconds <= datetime_nanoseconds_min()) return false; // 4. If ns ≥ nsMaxInstant + nsPerDay, return false. - if (nanoseconds >= DATETIME_NANOSECONDS_MAX) + if (nanoseconds >= datetime_nanoseconds_max()) return false; // 5. Return true. diff --git a/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index 7e44cde1b6..d978bdfdce 100644 --- a/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -510,12 +511,16 @@ bool time_zone_equals(StringView one, StringView two) } // OPTIMIZATION: The result of parsing a time zone identifier will not change, so we can cache the result. -static HashMap s_time_zone_id_cache; +static auto& time_zone_id_cache() +{ + static NeverDestroyed> cache; + return *cache; +} // 11.1.16 ParseTimeZoneIdentifier ( identifier ), https://tc39.es/proposal-temporal/#sec-parsetimezoneidentifier ThrowCompletionOr parse_time_zone_identifier(VM& vm, String const& identifier) { - if (auto result = s_time_zone_id_cache.get(identifier); result.has_value()) + if (auto result = time_zone_id_cache().get(identifier); result.has_value()) return *result; // 1. Let parseResult be ParseText(StringToCodePoints(identifier), TimeZoneIdentifier). @@ -526,7 +531,7 @@ ThrowCompletionOr parse_time_zone_identifier(VM& vm, S return vm.throw_completion(ErrorType::TemporalInvalidTimeZoneString, identifier); auto result = parse_time_zone_identifier(*parse_result); - s_time_zone_id_cache.set(identifier, result); + time_zone_id_cache().set(identifier, result); return result; } @@ -535,7 +540,7 @@ ThrowCompletionOr parse_time_zone_identifier(VM& vm, S ParsedTimeZoneIdentifier const& parse_time_zone_identifier(String const& identifier) { // OPTIMIZATION: Some callers can assume that parsing will succeed. - return s_time_zone_id_cache.ensure(identifier, [&]() { + return time_zone_id_cache().ensure(identifier, [&]() { // 1. Let parseResult be ParseText(StringToCodePoints(identifier), TimeZoneIdentifier). auto parse_result = parse_iso8601(Production::TimeZoneIdentifier, identifier); VERIFY(parse_result.has_value()); diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index 9839183705..a2185bcdef 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -58,7 +59,11 @@ static inline bool same_type_for_equality(Value const& lhs, Value const& rhs) return false; } -static Crypto::SignedBigInteger const BIGINT_ZERO { 0 }; +static auto const& bigint_zero() +{ + static NeverDestroyed zero { 0 }; + return *zero; +} static ALWAYS_INLINE bool both_number(Value const& lhs, Value const& rhs) { @@ -306,7 +311,7 @@ ThrowCompletionOr Value::is_regexp(VM& vm) const return false; // 2. Let matcher be ? Get(argument, @@match). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto matcher = TRY(as_object().get(vm.well_known_symbol_match(), cache)); // 3. If matcher is not undefined, return ToBoolean(matcher). @@ -554,7 +559,7 @@ bool Value::to_boolean_slow_case() const case STRING_TAG: return !as_string().is_empty(); case BIGINT_TAG: - return as_bigint().big_integer() != BIGINT_ZERO; + return as_bigint().big_integer() != bigint_zero(); case OBJECT_TAG: // B.3.6.1 Changes to ToBoolean, https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-to-boolean // 3. If argument is an Object and argument has an [[IsHTMLDDA]] internal slot, return false. @@ -575,7 +580,7 @@ ThrowCompletionOr Value::to_primitive_slow_case(VM& vm, PreferredType pre // 1. If input is an Object, then if (is_object()) { // a. Let exoticToPrim be ? GetMethod(input, @@toPrimitive). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto exotic_to_primitive = TRY(get_method(vm, vm.well_known_symbol_to_primitive(), cache)); // b. If exoticToPrim is not undefined, then @@ -934,7 +939,7 @@ static Optional string_to_bigint(VM& vm, StringView string) // 4. Let mv be the MV of literal. // 5. Assert: mv is an integer. auto bigint = MUST(Crypto::SignedBigInteger::from_base(result->base, result->literal)); - if (result->is_negative && (bigint != BIGINT_ZERO)) + if (result->is_negative && (bigint != bigint_zero())) bigint.negate(); // 6. Return ℤ(mv). @@ -1615,8 +1620,8 @@ ThrowCompletionOr unary_minus(VM& vm, Value lhs) // 6.1.6.2.1 BigInt::unaryMinus ( x ), https://tc39.es/ecma262/#sec-numeric-types-bigint-unaryMinus // 1. If x is 0ℤ, return 0ℤ. - if (old_value.as_bigint().big_integer() == BIGINT_ZERO) - return BigInt::create(vm, BIGINT_ZERO); + if (old_value.as_bigint().big_integer() == bigint_zero()) + return BigInt::create(vm, bigint_zero()); // 2. Return the BigInt value that represents the negation of ℝ(x). auto big_integer_negated = old_value.as_bigint().big_integer(); @@ -1944,7 +1949,7 @@ ThrowCompletionOr div(VM& vm, Value lhs, Value rhs) auto x = lhs_numeric.as_bigint().big_integer(); auto y = rhs_numeric.as_bigint().big_integer(); // 1. If y is 0ℤ, throw a RangeError exception. - if (y == BIGINT_ZERO) + if (y == bigint_zero()) return vm.throw_completion(ErrorType::DivisionByZero); // 2. Let quotient be ℝ(x) / ℝ(y). // 3. Return the BigInt value that represents quotient rounded towards 0 to the next integer value. @@ -1984,7 +1989,7 @@ ThrowCompletionOr mod(VM& vm, Value lhs, Value rhs) auto n = lhs_numeric.as_bigint().big_integer(); auto d = rhs_numeric.as_bigint().big_integer(); // 1. If d is 0ℤ, throw a RangeError exception. - if (d == BIGINT_ZERO) + if (d == bigint_zero()) return vm.throw_completion(ErrorType::DivisionByZero); // 2. If n is 0ℤ, return 0ℤ. // 3. Let quotient be ℝ(n) / ℝ(d). @@ -2153,7 +2158,7 @@ ThrowCompletionOr instance_of(VM& vm, Value value, Value target) return vm.throw_completion(ErrorType::NotAnObject, target); // 2. Let instOfHandler be ? GetMethod(target, @@hasInstance). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto instance_of_handler = TRY(target.get_method(vm, vm.well_known_symbol_has_instance(), cache)); // 3. If instOfHandler is not undefined, then @@ -2199,7 +2204,7 @@ ThrowCompletionOr ordinary_has_instance(VM& vm, Value lhs, Value rhs) auto* lhs_object = &lhs.as_object(); // 4. Let P be ? Get(C, "prototype"). - static Bytecode::StaticPropertyLookupCache cache; + static auto& cache = *new Bytecode::StaticPropertyLookupCache; auto rhs_prototype = TRY(rhs.get(vm, vm.names.prototype, cache)); // 5. If P is not an Object, throw a TypeError exception. diff --git a/Libraries/LibJS/SyntaxHighlighter.cpp b/Libraries/LibJS/SyntaxHighlighter.cpp index c3af4987e0..3da98c26f9 100644 --- a/Libraries/LibJS/SyntaxHighlighter.cpp +++ b/Libraries/LibJS/SyntaxHighlighter.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -154,13 +155,13 @@ void SyntaxHighlighter::rehighlight(Palette const& palette) Vector SyntaxHighlighter::matching_token_pairs_impl() const { - static Vector pairs; - if (pairs.is_empty()) { - pairs.append({ pack_token_data(TokenType::CurlyOpen, TokenCategory::Punctuation), pack_token_data(TokenType::CurlyClose, TokenCategory::Punctuation) }); - pairs.append({ pack_token_data(TokenType::ParenOpen, TokenCategory::Punctuation), pack_token_data(TokenType::ParenClose, TokenCategory::Punctuation) }); - pairs.append({ pack_token_data(TokenType::BracketOpen, TokenCategory::Punctuation), pack_token_data(TokenType::BracketClose, TokenCategory::Punctuation) }); + static NeverDestroyed> pairs; + if (pairs->is_empty()) { + pairs->append({ pack_token_data(TokenType::CurlyOpen, TokenCategory::Punctuation), pack_token_data(TokenType::CurlyClose, TokenCategory::Punctuation) }); + pairs->append({ pack_token_data(TokenType::ParenOpen, TokenCategory::Punctuation), pack_token_data(TokenType::ParenClose, TokenCategory::Punctuation) }); + pairs->append({ pack_token_data(TokenType::BracketOpen, TokenCategory::Punctuation), pack_token_data(TokenType::BracketClose, TokenCategory::Punctuation) }); } - return pairs; + return *pairs; } bool SyntaxHighlighter::token_types_equal(u64 token1, u64 token2) const diff --git a/Libraries/LibLine/Editor.cpp b/Libraries/LibLine/Editor.cpp index de7a772880..0e01289baa 100644 --- a/Libraries/LibLine/Editor.cpp +++ b/Libraries/LibLine/Editor.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -929,8 +930,10 @@ ErrorOr Editor::handle_read_event() Utf8View input_view { StringView { m_incomplete_data.data(), valid_bytes } }; size_t consumed_code_points = 0; - static Vector csi_parameter_bytes; - static Vector csi_intermediate_bytes; + static NeverDestroyed> s_csi_parameter_bytes; + static NeverDestroyed> s_csi_intermediate_bytes; + auto& csi_parameter_bytes = *s_csi_parameter_bytes; + auto& csi_intermediate_bytes = *s_csi_intermediate_bytes; Vector csi_parameters; u8 csi_final; enum CSIMod { diff --git a/Libraries/LibMedia/Audio/AudioDevices.cpp b/Libraries/LibMedia/Audio/AudioDevices.cpp index a9da260442..3243728041 100644 --- a/Libraries/LibMedia/Audio/AudioDevices.cpp +++ b/Libraries/LibMedia/Audio/AudioDevices.cpp @@ -10,7 +10,7 @@ namespace Media { AudioDevices& AudioDevices::the() { - static AudioDevices devices; + static AudioDevices& devices = *new AudioDevices; return devices; } diff --git a/Libraries/LibMedia/Audio/PulseAudioWrappers.cpp b/Libraries/LibMedia/Audio/PulseAudioWrappers.cpp index 3196eea1d1..026c1c590e 100644 --- a/Libraries/LibMedia/Audio/PulseAudioWrappers.cpp +++ b/Libraries/LibMedia/Audio/PulseAudioWrappers.cpp @@ -6,25 +6,31 @@ #include "PulseAudioWrappers.h" +#include #include #include namespace Audio { static PulseAudioContext* s_pulse_audio_context; -static Sync::RecursiveMutex s_pulse_audio_context_mutex; + +static Sync::RecursiveMutex& pulse_audio_context_mutex() +{ + static NeverDestroyed mutex; + return *mutex; +} ErrorOr> PulseAudioContext::the() { - auto instantiation_locker = Sync::MutexLocker(s_pulse_audio_context_mutex); + auto instantiation_locker = Sync::MutexLocker(pulse_audio_context_mutex()); // Lock and unlock the mutex to ensure that the mutex is fully unlocked at application // exit. static bool registered_atexit_callback = false; if (!registered_atexit_callback) { auto atexit_result = atexit([]() { - s_pulse_audio_context_mutex.lock(); - s_pulse_audio_context_mutex.unlock(); + pulse_audio_context_mutex().lock(); + pulse_audio_context_mutex().unlock(); }); if (atexit_result) return Error::from_string_literal("Unable to set PulseAudioContext atexit action"); @@ -112,7 +118,7 @@ ErrorOr> PulseAudioContext::the() bool PulseAudioContext::is_connected() { - auto locker = Sync::MutexLocker(s_pulse_audio_context_mutex); + auto locker = Sync::MutexLocker(pulse_audio_context_mutex()); return s_pulse_audio_context != nullptr; } @@ -125,7 +131,7 @@ PulseAudioContext::PulseAudioContext(pa_threaded_mainloop* main_loop, pa_mainloo PulseAudioContext::~PulseAudioContext() { - auto locker = Sync::MutexLocker(s_pulse_audio_context_mutex); + auto locker = Sync::MutexLocker(pulse_audio_context_mutex()); { auto loop_locker = main_loop_locker(); diff --git a/Libraries/LibUnicode/CharacterTypes.cpp b/Libraries/LibUnicode/CharacterTypes.cpp index fa5fc3a993..2a937d1570 100644 --- a/Libraries/LibUnicode/CharacterTypes.cpp +++ b/Libraries/LibUnicode/CharacterTypes.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -53,8 +54,17 @@ static constexpr GeneralCategory GENERAL_CATEGORY_SEPARATOR = U_CHAR_CATEGORY_CO static constexpr GeneralCategory GENERAL_CATEGORY_OTHER = U_CHAR_CATEGORY_COUNT + 8; static constexpr GeneralCategory GENERAL_CATEGORY_LIMIT = U_CHAR_CATEGORY_COUNT + 9; -static HashMap> s_category_sets_with_case_closure; -static HashMap> s_property_sets_with_case_closure; +static auto& category_sets_with_case_closure() +{ + static NeverDestroyed>> sets; + return *sets; +} + +static auto& property_sets_with_case_closure() +{ + static NeverDestroyed>> sets; + return *sets; +} Optional general_category_from_string(StringView general_category) { @@ -123,7 +133,7 @@ bool code_point_has_general_category(u32 code_point, GeneralCategory general_cat if (case_sensitivity == CaseSensitivity::CaseSensitive) return false; - auto& set = s_category_sets_with_case_closure.ensure(general_category, [&] { + auto& set = category_sets_with_case_closure().ensure(general_category, [&] { UErrorCode status = U_ZERO_ERROR; auto new_set = make(); new_set->applyIntPropertyValue(UCHAR_GENERAL_CATEGORY_MASK, static_cast(category_mask), status); @@ -231,7 +241,7 @@ bool code_point_has_property(u32 code_point, Property property, CaseSensitivity if (case_sensitivity == CaseSensitivity::CaseSensitive) return false; - auto& set = s_property_sets_with_case_closure.ensure(property, [&] { + auto& set = property_sets_with_case_closure().ensure(property, [&] { UErrorCode status = U_ZERO_ERROR; auto new_set = make(); new_set->applyIntPropertyValue(icu_property, 1, status); diff --git a/Libraries/LibUnicode/CurrencyCode.cpp b/Libraries/LibUnicode/CurrencyCode.cpp index e6a1326318..1779d20766 100644 --- a/Libraries/LibUnicode/CurrencyCode.cpp +++ b/Libraries/LibUnicode/CurrencyCode.cpp @@ -5,6 +5,7 @@ */ #include +#include #include namespace Unicode { @@ -13,7 +14,7 @@ static auto const& ensure_currency_codes() { // https://www.iso.org/iso-4217-currency-codes.html // https://www.six-group.com/dam/download/financial-information/data-center/iso-currrency/amendments/lists/list_one.xml - static HashMap currency_codes { + static NeverDestroyed> currency_codes { HashMap { { "AED"sv, { 2 } }, { "AFN"sv, { 2 } }, { "ALL"sv, { 2 } }, @@ -193,9 +194,9 @@ static auto const& ensure_currency_codes() { "ZAR"sv, { 2 } }, { "ZMW"sv, { 2 } }, { "ZWL"sv, { 2 } }, - }; + } }; - return currency_codes; + return *currency_codes; } Optional get_currency_code(StringView currency) diff --git a/Libraries/LibUnicode/ICU.cpp b/Libraries/LibUnicode/ICU.cpp index 5519df25f2..b1f66bfed9 100644 --- a/Libraries/LibUnicode/ICU.cpp +++ b/Libraries/LibUnicode/ICU.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -17,15 +18,24 @@ namespace Unicode { -static HashMap> s_locale_cache; -static HashMap> s_time_zone_cache; +static auto& locale_cache() +{ + static NeverDestroyed>> cache; + return *cache; +} + +static auto& time_zone_cache() +{ + static NeverDestroyed>> cache; + return *cache; +} Optional LocaleData::for_locale(StringView locale) { - auto locale_data = s_locale_cache.get(locale); + auto locale_data = locale_cache().get(locale); if (!locale_data.has_value()) { - locale_data = s_locale_cache.ensure(MUST(String::from_utf8(locale)), [&]() -> OwnPtr { + locale_data = locale_cache().ensure(MUST(String::from_utf8(locale)), [&]() -> OwnPtr { UErrorCode status = U_ZERO_ERROR; auto icu_locale = icu::Locale::forLanguageTag(icu_string_piece(locale), status); @@ -164,10 +174,10 @@ icu::TimeZoneNames& LocaleData::time_zone_names() Optional TimeZoneData::for_time_zone(StringView time_zone) { - auto time_zone_data = s_time_zone_cache.get(time_zone); + auto time_zone_data = time_zone_cache().get(time_zone); if (!time_zone_data.has_value()) { - time_zone_data = s_time_zone_cache.ensure(MUST(String::from_utf8(time_zone)), [&]() -> OwnPtr { + time_zone_data = time_zone_cache().ensure(MUST(String::from_utf8(time_zone)), [&]() -> OwnPtr { auto icu_time_zone = adopt_own_if_nonnull(icu::TimeZone::createTimeZone(icu_string(time_zone))); if (!icu_time_zone || *icu_time_zone == icu::TimeZone::getUnknown()) return nullptr; diff --git a/Libraries/LibUnicode/Locale.cpp b/Libraries/LibUnicode/Locale.cpp index 3aba12d80c..edfa404c21 100644 --- a/Libraries/LibUnicode/Locale.cpp +++ b/Libraries/LibUnicode/Locale.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -530,7 +531,7 @@ static void define_locales_without_scripts(HashTable& locales) bool is_locale_available(StringView locale) { - static auto available_locales = []() { + static NeverDestroyed> available_locales { []() { i32 count = 0; auto const* locale_list = icu::Locale::getAvailableLocales(count); @@ -549,9 +550,9 @@ bool is_locale_available(StringView locale) define_locales_without_scripts(available_locales); return available_locales; - }(); + }() }; - return available_locales.contains(locale); + return available_locales->contains(locale); } Style style_from_string(StringView style) diff --git a/Libraries/LibUnicode/TimeZone.cpp b/Libraries/LibUnicode/TimeZone.cpp index 680c872645..e6c7f2c4a1 100644 --- a/Libraries/LibUnicode/TimeZone.cpp +++ b/Libraries/LibUnicode/TimeZone.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -16,7 +17,11 @@ namespace Unicode { -static Optional cached_system_time_zone; +static auto& cached_system_time_zone() +{ + static NeverDestroyed> cached_system_time_zone; + return *cached_system_time_zone; +} static String current_time_zone_impl(OwnPtr time_zone) { @@ -49,12 +54,12 @@ static String current_default_time_zone() String current_time_zone() { - return cached_system_time_zone.ensure([] { return current_host_time_zone(); }); + return cached_system_time_zone().ensure([] { return current_host_time_zone(); }); } void clear_system_time_zone_cache() { - cached_system_time_zone.clear(); + cached_system_time_zone().clear(); } ErrorOr set_current_time_zone(StringView time_zone) @@ -64,7 +69,7 @@ ErrorOr set_current_time_zone(StringView time_zone) return Error::from_string_literal("Unable to find the provided time zone"); icu::TimeZone::setDefault(time_zone_data->time_zone()); - cached_system_time_zone = current_default_time_zone(); + cached_system_time_zone() = current_default_time_zone(); return {}; } @@ -128,8 +133,8 @@ static Vector icu_available_time_zones(Optional const& regio Vector const& available_time_zones() { - static auto time_zones = icu_available_time_zones({}); - return time_zones; + static NeverDestroyed> time_zones { icu_available_time_zones({}) }; + return *time_zones; } Vector available_time_zones_in_region(StringView region) diff --git a/Libraries/LibUnicode/UnicodeKeywords.cpp b/Libraries/LibUnicode/UnicodeKeywords.cpp index cfc167c2e8..5e69e827f8 100644 --- a/Libraries/LibUnicode/UnicodeKeywords.cpp +++ b/Libraries/LibUnicode/UnicodeKeywords.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -37,14 +38,14 @@ Vector available_keyword_values(StringView locale, StringView key) Vector const& available_calendars() { - static auto calendars = []() { + static NeverDestroyed> calendars { []() { auto calendars = available_calendars("und"sv); quick_sort(calendars); return calendars; - }(); + }() }; - return calendars; + return *calendars; } Vector available_calendars(StringView locale) @@ -68,7 +69,7 @@ Vector available_calendars(StringView locale) Vector const& available_currencies() { - static auto currencies = []() -> Vector { + static NeverDestroyed> currencies { []() -> Vector { UErrorCode status = U_ZERO_ERROR; auto* currencies = ucurr_openISOCurrencies(UCURR_ALL, &status); @@ -95,26 +96,26 @@ Vector const& available_currencies() quick_sort(result); return result; - }(); + }() }; - return currencies; + return *currencies; } Vector const& available_collation_case_orderings() { - static Vector case_orderings { "false"_string, "lower"_string, "upper"_string }; - return case_orderings; + static NeverDestroyed> case_orderings { Vector { "false"_string, "lower"_string, "upper"_string } }; + return *case_orderings; } Vector const& available_collation_numeric_orderings() { - static Vector case_orderings { "false"_string, "true"_string }; - return case_orderings; + static NeverDestroyed> case_orderings { Vector { "false"_string, "true"_string } }; + return *case_orderings; } Vector const& available_collations() { - static auto collations = []() -> Vector { + static NeverDestroyed> collations { []() -> Vector { UErrorCode status = U_ZERO_ERROR; auto keywords = adopt_own_if_nonnull(icu::Collator::getKeywordValues("collation", status)); @@ -129,9 +130,9 @@ Vector const& available_collations() quick_sort(collations); return collations; - }(); + }() }; - return collations; + return *collations; } Vector available_collations(StringView locale) @@ -160,8 +161,8 @@ Vector available_collations(StringView locale) Vector const& available_hour_cycles() { - static Vector case_orderings { "h11"_string, "h12"_string, "h23"_string, "h24"_string }; - return case_orderings; + static NeverDestroyed> hour_cycles { Vector { "h11"_string, "h12"_string, "h23"_string, "h24"_string } }; + return *hour_cycles; } Vector available_hour_cycles(StringView locale) @@ -183,7 +184,7 @@ Vector available_hour_cycles(StringView locale) Vector const& available_number_systems() { - static auto number_systems = []() -> Vector { + static NeverDestroyed> number_systems { []() -> Vector { UErrorCode status = U_ZERO_ERROR; auto keywords = adopt_own_if_nonnull(icu::NumberingSystem::getAvailableNames(status)); @@ -200,9 +201,9 @@ Vector const& available_number_systems() quick_sort(number_systems); return number_systems; - }(); + }() }; - return number_systems; + return *number_systems; } Vector available_number_systems(StringView locale) diff --git a/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp b/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp index f86b31a531..a4e734ae45 100644 --- a/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp +++ b/Libraries/LibWasm/AbstractMachine/AbstractMachine.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -16,21 +17,25 @@ namespace Wasm { -static Vector s_module_stats; +static auto& module_stats() +{ + static NeverDestroyed> stats; + return *stats; +} void record_module_stats(ModuleStats stats) { - s_module_stats.append(move(stats)); + module_stats().append(move(stats)); } void dump_module_stats() { - if (s_module_stats.is_empty()) { + if (module_stats().is_empty()) { warnln("wasm-stats: no modules compiled yet"); return; } - warnln("wasm-stats: {} module(s) compiled", s_module_stats.size()); + warnln("wasm-stats: {} module(s) compiled", module_stats().size()); warnln("wasm-stats: hash input KiB parse ms validate ms cl ms cl blob KiB funcs cache"); AK::Duration total_parse; @@ -40,7 +45,7 @@ void dump_module_stats() size_t total_blob = 0; size_t total_hits = 0; - for (auto const& s : s_module_stats) { + for (auto const& s : module_stats()) { StringBuilder hash_prefix; for (size_t i = 0; i < 4; ++i) hash_prefix.appendff("{:02x}", s.wasm_hash[i]); diff --git a/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp b/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp index 12c8511c5a..f84f82eb36 100644 --- a/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp +++ b/Libraries/LibWasm/AbstractMachine/BytecodeInterpreter.cpp @@ -5973,7 +5973,7 @@ CompiledInstructions try_compile_instructions(Expression const& expression, Span I64Const, I64ConstGetLocal, } pattern_state { InsnPatternState::Nothing }; - static Instruction nop { Instructions::nop }; + static auto& nop = *new Instruction { Instructions::nop }; size_t calls_in_expression = 0; diff --git a/Libraries/LibWasm/CraneliftBridge.cpp b/Libraries/LibWasm/CraneliftBridge.cpp index 562e78f140..1f123f27df 100644 --- a/Libraries/LibWasm/CraneliftBridge.cpp +++ b/Libraries/LibWasm/CraneliftBridge.cpp @@ -141,9 +141,14 @@ struct CacheState { Vector pending_batch; }; -static thread_local CacheState s_cranelift_cache_state; static thread_local u32 s_active_function_index = NumericLimits::max(); +static CacheState& cranelift_cache_state() +{ + static thread_local auto* state = new CacheState; + return *state; +} + static u64 compute_layout_hash(RuntimeHelpers const& h) { auto fnv1a = [](u64 hash, u64 value) { @@ -1262,7 +1267,7 @@ static void try_cranelift_compile_batch(Vector& batch) ? ReadonlySpan {} : ReadonlySpan { reinterpret_cast(base + reloc_region_start + trap_offset), trap_count }; - auto& capture = s_cranelift_cache_state.cache_capture; + auto& capture = cranelift_cache_state().cache_capture; if (capture.capturing && batch[i].function_index != NumericLimits::max()) { if (auto copy = ByteBuffer::copy(code_bytes.data(), code_bytes.size()); !copy.is_error()) { CacheRecord rec; @@ -1305,8 +1310,8 @@ bool try_cranelift_compile(CompiledInstructions& compiled, u32 result_arity) // Cache hit: install from the parsed blob instead of going through cranelift. // dispatches[] has just been populated by try_compile_instructions, so handler_ptr is ready to be set. - if (s_cranelift_cache_state.pending_install.active && s_active_function_index != NumericLimits::max()) { - auto record = s_cranelift_cache_state.pending_install.records.take(s_active_function_index); + if (cranelift_cache_state().pending_install.active && s_active_function_index != NumericLimits::max()) { + auto record = cranelift_cache_state().pending_install.records.take(s_active_function_index); if (record.has_value()) { static auto cache_install_helpers = make_runtime_helpers(); if (install_compiled_function( @@ -1319,7 +1324,7 @@ bool try_cranelift_compile(CompiledInstructions& compiled, u32 result_arity) return true; } // Put it back so we can try later. - s_cranelift_cache_state.pending_install.records.set(s_active_function_index, record.release_value()); + cranelift_cache_state().pending_install.records.set(s_active_function_index, record.release_value()); } } @@ -1352,9 +1357,9 @@ bool try_cranelift_compile(CompiledInstructions& compiled, u32 result_arity) static size_t s_min_insns = read_size_env("CRANELIFT_MIN_INSNS", 0); static size_t s_min_fn = read_size_env("CRANELIFT_MIN_FN", 0); static size_t s_max_fn = read_size_env("CRANELIFT_MAX_FN", NumericLimits::max()); - static auto s_skip_fn = read_set_env("CRANELIFT_SKIP_FN"); - static auto s_only_fn = read_set_env("CRANELIFT_ONLY_FN"); - static auto s_dump_fn = read_set_env("CRANELIFT_DUMP_FN"); + static auto& s_skip_fn = *new HashTable(read_set_env("CRANELIFT_SKIP_FN")); + static auto& s_only_fn = *new HashTable(read_set_env("CRANELIFT_ONLY_FN")); + static auto& s_dump_fn = *new HashTable(read_set_env("CRANELIFT_DUMP_FN")); static bool s_trace = getenv("CRANELIFT_TRACE") != nullptr; static size_t s_func_counter = 0; @@ -1435,22 +1440,22 @@ bool try_cranelift_compile(CompiledInstructions& compiled, u32 result_arity) } } - s_cranelift_cache_state.pending_batch.append({ move(flat), result_arity, s_active_function_index, &compiled }); + cranelift_cache_state().pending_batch.append({ move(flat), result_arity, s_active_function_index, &compiled }); return false; // Not compiled yet, will be compiled in flush. #endif } void flush_cranelift_batch() { - if (s_cranelift_cache_state.pending_batch.is_empty()) + if (cranelift_cache_state().pending_batch.is_empty()) return; - try_cranelift_compile_batch(s_cranelift_cache_state.pending_batch); - s_cranelift_cache_state.pending_batch.clear(); + try_cranelift_compile_batch(cranelift_cache_state().pending_batch); + cranelift_cache_state().pending_batch.clear(); } void discard_cranelift_batch() { - s_cranelift_cache_state.pending_batch.clear(); + cranelift_cache_state().pending_batch.clear(); } void free_cranelift_code(void* handle) @@ -1473,30 +1478,30 @@ void set_cranelift_active_function_index(u32 function_index) void begin_cranelift_cache_capture() { - s_cranelift_cache_state.cache_capture.capturing = true; - s_cranelift_cache_state.cache_capture.records.clear(); + cranelift_cache_state().cache_capture.capturing = true; + cranelift_cache_state().cache_capture.records.clear(); } void abort_cranelift_cache_capture() { - s_cranelift_cache_state.cache_capture.capturing = false; - s_cranelift_cache_state.cache_capture.records.clear(); + cranelift_cache_state().cache_capture.capturing = false; + cranelift_cache_state().cache_capture.records.clear(); } void abort_cranelift_cache_install() { - s_cranelift_cache_state.pending_install.active = false; - s_cranelift_cache_state.pending_install.records.clear(); + cranelift_cache_state().pending_install.active = false; + cranelift_cache_state().pending_install.records.clear(); } Optional serialize_cranelift_cache_blob(ReadonlyBytes wasm_hash) { ScopeGuard reset = [] { - s_cranelift_cache_state.cache_capture.capturing = false; - s_cranelift_cache_state.cache_capture.records.clear(); + cranelift_cache_state().cache_capture.capturing = false; + cranelift_cache_state().cache_capture.records.clear(); }; - auto const& capture = s_cranelift_cache_state.cache_capture; + auto const& capture = cranelift_cache_state().cache_capture; if (!capture.capturing || capture.records.is_empty()) return {}; @@ -1618,10 +1623,10 @@ bool try_install_cranelift_cache_blob(ReadonlyBytes expected_wasm_hash, Readonly __builtin_memcpy(&trap, blob.data() + trap_off + j * sizeof(CraneliftTrap), sizeof(CraneliftTrap)); rec.traps.unchecked_append(trap); } - s_cranelift_cache_state.pending_install.records.set(entry->function_index, move(rec)); + cranelift_cache_state().pending_install.records.set(entry->function_index, move(rec)); } - s_cranelift_cache_state.pending_install.active = true; + cranelift_cache_state().pending_install.active = true; return true; } diff --git a/Libraries/LibWasm/Printer/Printer.cpp b/Libraries/LibWasm/Printer/Printer.cpp index 0a2ea01c9c..783d785e8a 100644 --- a/Libraries/LibWasm/Printer/Printer.cpp +++ b/Libraries/LibWasm/Printer/Printer.cpp @@ -13,8 +13,8 @@ namespace Wasm { struct Names { - static HashMap instruction_names; - static HashMap instructions_by_name; + static HashMap& instruction_names; + static HashMap& instructions_by_name; }; ByteString instruction_name(OpCode const& opcode) @@ -845,7 +845,7 @@ void Printer::print(Wasm::Reference const& value) } -HashMap Wasm::Names::instruction_names { +HashMap& Wasm::Names::instruction_names = *new HashMap { { Instructions::unreachable, "unreachable" }, { Instructions::nop, "nop" }, { Instructions::block, "block" }, @@ -1368,4 +1368,4 @@ HashMap Wasm::Names::instruction_names { { Instructions::synthetic_i64_shrs2local, "synthetic:i64.shrs2local" }, { Instructions::synthetic_local_seti64_const, "synthetic:local.seti64_const" }, }; -HashMap Wasm::Names::instructions_by_name; +HashMap& Wasm::Names::instructions_by_name = *new HashMap; diff --git a/Libraries/LibWasm/WASI/Wasi.cpp b/Libraries/LibWasm/WASI/Wasi.cpp index 2ce479f010..3db347e75c 100644 --- a/Libraries/LibWasm/WASI/Wasi.cpp +++ b/Libraries/LibWasm/WASI/Wasi.cpp @@ -922,7 +922,7 @@ struct Names { ErrorOr Implementation::function_by_name(StringView name) { auto name_for_comparison = TRY(FlyString::from_utf8(name)); - static auto names = TRY(Names::construct()); + static auto& names = *new Names(TRY(Names::construct())); #define IMPL(x) \ if (name_for_comparison == names.x) \ diff --git a/Libraries/LibWeb/ARIA/AttributeNames.cpp b/Libraries/LibWeb/ARIA/AttributeNames.cpp index 8ecd09f5b2..79688db084 100644 --- a/Libraries/LibWeb/ARIA/AttributeNames.cpp +++ b/Libraries/LibWeb/ARIA/AttributeNames.cpp @@ -9,7 +9,7 @@ namespace Web::ARIA::AttributeNames { #define __ENUMERATE_ARIA_ATTRIBUTE(name, attribute) \ - FlyString name = attribute##_fly_string; + FlyString const& name = *new FlyString(attribute##_fly_string); ENUMERATE_ARIA_ATTRIBUTES #undef __ENUMERATE_ARIA_ATTRIBUTE diff --git a/Libraries/LibWeb/ARIA/AttributeNames.h b/Libraries/LibWeb/ARIA/AttributeNames.h index ee17569428..237f920d3f 100644 --- a/Libraries/LibWeb/ARIA/AttributeNames.h +++ b/Libraries/LibWeb/ARIA/AttributeNames.h @@ -68,7 +68,7 @@ namespace Web::ARIA::AttributeNames { __ENUMERATE_ARIA_ATTRIBUTE(aria_value_text, "aria-valuetext") #define __ENUMERATE_ARIA_ATTRIBUTE(name, attribute) \ - extern FlyString name; + extern FlyString const& name; ENUMERATE_ARIA_ATTRIBUTES #undef __ENUMERATE_ARIA_ATTRIBUTE diff --git a/Libraries/LibWeb/ARIA/RoleType.cpp b/Libraries/LibWeb/ARIA/RoleType.cpp index f97b5b65a0..e17f1452b8 100644 --- a/Libraries/LibWeb/ARIA/RoleType.cpp +++ b/Libraries/LibWeb/ARIA/RoleType.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -47,54 +48,54 @@ constexpr StateAndProperties supported_properties_array[] = { HashTable const& RoleType::supported_states() const { - static HashTable states; - if (states.is_empty()) - states.set_from(supported_state_array); - return states; + static NeverDestroyed> states; + if (states->is_empty()) + states->set_from(supported_state_array); + return *states; } HashTable const& RoleType::supported_properties() const { - static HashTable properties; - if (properties.is_empty()) - properties.set_from(supported_properties_array); - return properties; + static NeverDestroyed> properties; + if (properties->is_empty()) + properties->set_from(supported_properties_array); + return *properties; } HashTable const& RoleType::required_states() const { - static HashTable states; - return states; + static NeverDestroyed> states; + return *states; } HashTable const& RoleType::required_properties() const { - static HashTable properties; - return properties; + static NeverDestroyed> properties; + return *properties; } HashTable const& RoleType::prohibited_properties() const { - static HashTable properties; - return properties; + static NeverDestroyed> properties; + return *properties; } HashTable const& RoleType::prohibited_states() const { - static HashTable states; - return states; + static NeverDestroyed> states; + return *states; } HashTable const& RoleType::required_context_roles() const { - static HashTable roles; - return roles; + static NeverDestroyed> roles; + return *roles; } HashTable const& RoleType::required_owned_elements() const { - static HashTable roles; - return roles; + static NeverDestroyed> roles; + return *roles; } ErrorOr RoleType::serialize_as_json(JsonObjectSerializer& object) const diff --git a/Libraries/LibWeb/Bindings/Intrinsics.h b/Libraries/LibWeb/Bindings/Intrinsics.h index 8d99fcdb42..a3511d6c09 100644 --- a/Libraries/LibWeb/Bindings/Intrinsics.h +++ b/Libraries/LibWeb/Bindings/Intrinsics.h @@ -9,18 +9,19 @@ #include #include #include +#include #include #include #include #include #include -#define WEB_SET_PROTOTYPE_FOR_INTERFACE_WITH_CUSTOM_NAME(interface_class, interface_name) \ - do { \ - static auto name = #interface_name##_fly_string; \ - if (!shape().prototype()) { \ - set_prototype(&Bindings::ensure_web_prototype(realm, name)); \ - } \ +#define WEB_SET_PROTOTYPE_FOR_INTERFACE_WITH_CUSTOM_NAME(interface_class, interface_name) \ + do { \ + static NeverDestroyed name { #interface_name##_fly_string }; \ + if (!shape().prototype()) { \ + set_prototype(&Bindings::ensure_web_prototype(realm, *name)); \ + } \ } while (0) #define WEB_SET_PROTOTYPE_FOR_INTERFACE(interface_name) WEB_SET_PROTOTYPE_FOR_INTERFACE_WITH_CUSTOM_NAME(interface_name, interface_name) diff --git a/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Libraries/LibWeb/Bindings/MainThreadVM.cpp index 16f9bdeb79..2e567f4fce 100644 --- a/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -8,6 +8,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -53,7 +54,11 @@ namespace Web::Bindings { -static RefPtr s_main_thread_vm; +static auto& main_thread_vm_ptr() +{ + static NeverDestroyed> vm; + return *vm; +} // https://html.spec.whatwg.org/multipage/webappapis.html#active-script HTML::Script* active_script() @@ -93,37 +98,37 @@ static NonnullOwnPtr create_agent(GC::Heap& heap, AgentType type) void initialize_main_thread_vm(AgentType type) { - VERIFY(!s_main_thread_vm); + VERIFY(!main_thread_vm_ptr()); - s_main_thread_vm = JS::VM::create(); - s_main_thread_vm->set_agent(create_agent(s_main_thread_vm->heap(), type)); + main_thread_vm_ptr() = JS::VM::create(); + main_thread_vm_ptr()->set_agent(create_agent(main_thread_vm_ptr()->heap(), type)); - s_main_thread_vm->on_unimplemented_property_access = [](auto const& object, auto const& property_key) { + main_thread_vm_ptr()->on_unimplemented_property_access = [](auto const& object, auto const& property_key) { dbgln("FIXME: Unimplemented IDL interface: '{}.{}'", object.class_name(), property_key.to_string()); }; // NOTE: We intentionally leak the main thread JavaScript VM. // This avoids doing an exhaustive garbage collection on process exit. - s_main_thread_vm->ref(); + main_thread_vm_ptr()->ref(); // 8.1.6.1 HostEnsureCanAddPrivateElement(O), https://html.spec.whatwg.org/multipage/webappapis.html#the-hostensurecanaddprivateelement-implementation - s_main_thread_vm->host_ensure_can_add_private_element = [](JS::Object const& object) -> JS::ThrowCompletionOr { + main_thread_vm_ptr()->host_ensure_can_add_private_element = [](JS::Object const& object) -> JS::ThrowCompletionOr { // 1. If O is a WindowProxy object, or implements Location, then return ThrowCompletion(a new TypeError). if (is(object) || is(object)) - return s_main_thread_vm->throw_completion("Cannot add private elements to window or location object"sv); + return main_thread_vm_ptr()->throw_completion("Cannot add private elements to window or location object"sv); // 2. Return NormalCompletion(unused). return {}; }; // 8.1.6.2 HostEnsureCanCompileStrings(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg), https://html.spec.whatwg.org/multipage/webappapis.html#hostensurecancompilestrings(realm,-parameterstrings,-bodystring,-codestring,-compilationtype,-parameterargs,-bodyarg) - s_main_thread_vm->host_ensure_can_compile_strings = [](JS::Realm& realm, ReadonlySpan parameter_strings, StringView body_string, StringView code_string, JS::CompilationType compilation_type, ReadonlySpan parameter_args, JS::Value body_arg) -> JS::ThrowCompletionOr { + main_thread_vm_ptr()->host_ensure_can_compile_strings = [](JS::Realm& realm, ReadonlySpan parameter_strings, StringView body_string, StringView code_string, JS::CompilationType compilation_type, ReadonlySpan parameter_args, JS::Value body_arg) -> JS::ThrowCompletionOr { // 1. Perform ? EnsureCSPDoesNotBlockStringCompilation(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg). [CSP] return ContentSecurityPolicy::ensure_csp_does_not_block_string_compilation(realm, parameter_strings, body_string, code_string, compilation_type, parameter_args, body_arg); }; // 8.1.6.3 HostGetCodeForEval(argument), https://html.spec.whatwg.org/multipage/webappapis.html#hostgetcodeforeval(argument) - s_main_thread_vm->host_get_code_for_eval = [](JS::Object const& argument) -> GC::Ptr { + main_thread_vm_ptr()->host_get_code_for_eval = [](JS::Object const& argument) -> GC::Ptr { // 1. If argument is a TrustedScript object, then return argument's data. if (auto const* trusted_script = as_if(argument); trusted_script) return JS::PrimitiveString::create(argument.vm(), trusted_script->to_string()); @@ -133,8 +138,8 @@ void initialize_main_thread_vm(AgentType type) }; // 8.1.5.3 HostPromiseRejectionTracker(promise, operation), https://html.spec.whatwg.org/multipage/webappapis.html#the-hostpromiserejectiontracker-implementation - s_main_thread_vm->host_promise_rejection_tracker = [](JS::Promise& promise, JS::Promise::RejectionOperation operation) { - auto& vm = *s_main_thread_vm; + main_thread_vm_ptr()->host_promise_rejection_tracker = [](JS::Promise& promise, JS::Promise::RejectionOperation operation) { + auto& vm = *main_thread_vm_ptr(); // 1. Let script be the running script. // The running script is the script in the [[HostDefined]] field in the ScriptOrModule component of the running JavaScript execution context. @@ -188,7 +193,7 @@ void initialize_main_thread_vm(AgentType type) // 4. Queue a global task on the DOM manipulation task source given global to fire an event named rejectionhandled at global, using PromiseRejectionEvent, // with the promise attribute initialized to promise, and the reason attribute initialized to the value of promise's [[PromiseResult]] internal slot. - HTML::queue_global_task(HTML::Task::Source::DOMManipulation, global, GC::create_function(s_main_thread_vm->heap(), [&global, &promise] { + HTML::queue_global_task(HTML::Task::Source::DOMManipulation, global, GC::create_function(main_thread_vm_ptr()->heap(), [&global, &promise] { // FIXME: This currently assumes that global is a WindowObject. auto& window = as(global); @@ -208,7 +213,7 @@ void initialize_main_thread_vm(AgentType type) }; // 8.1.5.4.1 HostCallJobCallback(callback, V, argumentsList), https://html.spec.whatwg.org/multipage/webappapis.html#hostcalljobcallback - s_main_thread_vm->host_call_job_callback = [](JS::JobCallback& callback, JS::Value this_value, ReadonlySpan arguments_list) { + main_thread_vm_ptr()->host_call_job_callback = [](JS::JobCallback& callback, JS::Value this_value, ReadonlySpan arguments_list) { auto& callback_host_defined = as(*callback.custom_data()); // 1. Let incumbent settings be callback.[[HostDefined]].[[IncumbentSettings]]. @@ -222,15 +227,15 @@ void initialize_main_thread_vm(AgentType type) // 4. If script execution context is not null, then push script execution context onto the JavaScript execution context stack. if (script_execution_context) - s_main_thread_vm->push_execution_context(*script_execution_context); + main_thread_vm_ptr()->push_execution_context(*script_execution_context); // 5. Let result be Call(callback.[[Callback]], V, argumentsList). - auto result = JS::call(*s_main_thread_vm, callback.callback(), this_value, arguments_list); + auto result = JS::call(*main_thread_vm_ptr(), callback.callback(), this_value, arguments_list); // 6. If script execution context is not null, then pop script execution context from the JavaScript execution context stack. if (script_execution_context) { - VERIFY(&s_main_thread_vm->running_execution_context() == script_execution_context); - s_main_thread_vm->pop_execution_context(); + VERIFY(&main_thread_vm_ptr()->running_execution_context() == script_execution_context); + main_thread_vm_ptr()->pop_execution_context(); } // 7. Clean up after running a callback with incumbent settings. @@ -241,12 +246,12 @@ void initialize_main_thread_vm(AgentType type) }; // 8.1.5.4.2 HostEnqueueFinalizationRegistryCleanupJob(finalizationRegistry), https://html.spec.whatwg.org/multipage/webappapis.html#hostenqueuefinalizationregistrycleanupjob - s_main_thread_vm->host_enqueue_finalization_registry_cleanup_job = [](JS::FinalizationRegistry& finalization_registry) { + main_thread_vm_ptr()->host_enqueue_finalization_registry_cleanup_job = [](JS::FinalizationRegistry& finalization_registry) { // 1. Let global be finalizationRegistry.[[Realm]]'s global object. auto& global = finalization_registry.realm().global_object(); // 2. Queue a global task on the JavaScript engine task source given global to perform the following steps: - HTML::queue_global_task(HTML::Task::Source::JavaScriptEngine, global, GC::create_function(s_main_thread_vm->heap(), [&finalization_registry] { + HTML::queue_global_task(HTML::Task::Source::JavaScriptEngine, global, GC::create_function(main_thread_vm_ptr()->heap(), [&finalization_registry] { // 1. Let entry be finalizationRegistry.[[CleanupCallback]].[[Callback]].[[Realm]]'s environment settings object. // AD-HOC: The spec assumes [[Callback]] has a [[Realm]] internal slot, but Proxy and BoundFunction // exotic objects do not. Use GetFunctionRealm to unwrap these exotic objects, falling back to @@ -274,8 +279,8 @@ void initialize_main_thread_vm(AgentType type) }; // 8.1.5.4.3 HostEnqueuePromiseJob(job, realm), https://html.spec.whatwg.org/multipage/webappapis.html#hostenqueuepromisejob - s_main_thread_vm->host_enqueue_promise_job = [](GC::Ref()>> job, JS::Realm* realm) { - auto& vm = *s_main_thread_vm; + main_thread_vm_ptr()->host_enqueue_promise_job = [](GC::Ref()>> job, JS::Realm* realm) { + auto& vm = *main_thread_vm_ptr(); // IMPLEMENTATION DEFINED: The JS spec says we must take implementation defined steps to make the currently active script or module at the time of HostEnqueuePromiseJob being invoked // also be the active script or module of the job at the time of its invocation. @@ -341,12 +346,12 @@ void initialize_main_thread_vm(AgentType type) })); }; - s_main_thread_vm->host_promise_job_queue_is_empty = []() -> bool { + main_thread_vm_ptr()->host_promise_job_queue_is_empty = []() -> bool { return HTML::main_thread_event_loop().microtask_queue_empty(); }; // 8.1.5.4.4 HostMakeJobCallback(callable), https://html.spec.whatwg.org/multipage/webappapis.html#hostmakejobcallback - s_main_thread_vm->host_make_job_callback = [](JS::FunctionObject& callable) -> GC::Ref { + main_thread_vm_ptr()->host_make_job_callback = [](JS::FunctionObject& callable) -> GC::Ref { // 1. Let incumbent settings be the incumbent settings object. auto& incumbent_settings = HTML::incumbent_settings_object(); @@ -375,11 +380,11 @@ void initialize_main_thread_vm(AgentType type) // 5. Return the JobCallback Record { [[Callback]]: callable, [[HostDefined]]: { [[IncumbentSettings]]: incumbent settings, [[ActiveScriptContext]]: script execution context } }. auto host_defined = adopt_own(*new WebEngineCustomJobCallbackData(incumbent_settings, move(script_execution_context))); - return JS::JobCallback::create(*s_main_thread_vm, callable, move(host_defined)); + return JS::JobCallback::create(*main_thread_vm_ptr(), callable, move(host_defined)); }; // 8.1.6.7.1 HostGetImportMetaProperties(moduleRecord), https://html.spec.whatwg.org/multipage/webappapis.html#hostgetimportmetaproperties - s_main_thread_vm->host_get_import_meta_properties = [](JS::SourceTextModule& module_record) { + main_thread_vm_ptr()->host_get_import_meta_properties = [](JS::SourceTextModule& module_record) { auto& realm = module_record.realm(); auto& vm = realm.vm(); @@ -420,14 +425,14 @@ void initialize_main_thread_vm(AgentType type) }; // 8.1.6.7.2 HostGetSupportedImportAttributes(), https://html.spec.whatwg.org/multipage/webappapis.html#hostgetsupportedimportassertions - s_main_thread_vm->host_get_supported_import_attributes = []() -> Vector { + main_thread_vm_ptr()->host_get_supported_import_attributes = []() -> Vector { // 1. Return « "type" ». return { "type"_utf16 }; }; // 8.1.6.7.3 HostLoadImportedModule(referrer, moduleRequest, loadState, payload), https://html.spec.whatwg.org/multipage/webappapis.html#hostloadimportedmodule - s_main_thread_vm->host_load_imported_module = [](JS::ImportedModuleReferrer referrer, JS::ModuleRequest const& module_request, GC::Ptr load_state, JS::ImportedModulePayload payload) -> void { - auto& vm = *s_main_thread_vm; + main_thread_vm_ptr()->host_load_imported_module = [](JS::ImportedModuleReferrer referrer, JS::ModuleRequest const& module_request, GC::Ptr load_state, JS::ImportedModulePayload payload) -> void { + auto& vm = *main_thread_vm_ptr(); // 1. Let settingsObject be the current settings object. GC::Ref settings_object = HTML::current_settings_object(); @@ -649,20 +654,20 @@ void initialize_main_thread_vm(AgentType type) HTML::fetch_single_imported_module_script(settings_object->realm(), url.release_value(), *fetch_client, destination, fetch_options, settings_object, fetch_referrer, module_request, perform_fetch, on_single_fetch_complete); }; - s_main_thread_vm->host_unrecognized_date_string = [](StringView date) { + main_thread_vm_ptr()->host_unrecognized_date_string = [](StringView date) { dbgln("Unable to parse date string: \"{}\"", date); }; - s_main_thread_vm->host_resize_array_buffer = [default_host_resize_array_buffer = move(s_main_thread_vm->host_resize_array_buffer)](JS::ArrayBuffer& buffer, size_t new_byte_length) -> JS::ThrowCompletionOr { - auto wasm_handled = TRY(WebAssembly::Detail::host_resize_array_buffer(*s_main_thread_vm, buffer, new_byte_length)); + main_thread_vm_ptr()->host_resize_array_buffer = [default_host_resize_array_buffer = move(main_thread_vm_ptr()->host_resize_array_buffer)](JS::ArrayBuffer& buffer, size_t new_byte_length) -> JS::ThrowCompletionOr { + auto wasm_handled = TRY(WebAssembly::Detail::host_resize_array_buffer(*main_thread_vm_ptr(), buffer, new_byte_length)); if (wasm_handled == JS::HandledByHost::Handled) return JS::HandledByHost::Handled; return default_host_resize_array_buffer(buffer, new_byte_length); }; - s_main_thread_vm->host_grow_shared_array_buffer = [default_host_grow_shared_array_buffer = move(s_main_thread_vm->host_grow_shared_array_buffer)](JS::ArrayBuffer& buffer, size_t new_byte_length) -> JS::ThrowCompletionOr { - auto wasm_handled = TRY(WebAssembly::Detail::host_grow_shared_array_buffer(*s_main_thread_vm, buffer, new_byte_length)); + main_thread_vm_ptr()->host_grow_shared_array_buffer = [default_host_grow_shared_array_buffer = move(main_thread_vm_ptr()->host_grow_shared_array_buffer)](JS::ArrayBuffer& buffer, size_t new_byte_length) -> JS::ThrowCompletionOr { + auto wasm_handled = TRY(WebAssembly::Detail::host_grow_shared_array_buffer(*main_thread_vm_ptr(), buffer, new_byte_length)); if (wasm_handled == JS::HandledByHost::Handled) return JS::HandledByHost::Handled; @@ -672,8 +677,8 @@ void initialize_main_thread_vm(AgentType type) JS::VM& main_thread_vm() { - VERIFY(s_main_thread_vm); - return *s_main_thread_vm; + VERIFY(main_thread_vm_ptr()); + return *main_thread_vm_ptr(); } // https://dom.spec.whatwg.org/#queue-a-mutation-observer-compound-microtask diff --git a/Libraries/LibWeb/CSS/CSSNestedDeclarations.cpp b/Libraries/LibWeb/CSS/CSSNestedDeclarations.cpp index 0b56f355dd..28aa46dcb4 100644 --- a/Libraries/LibWeb/CSS/CSSNestedDeclarations.cpp +++ b/Libraries/LibWeb/CSS/CSSNestedDeclarations.cpp @@ -5,6 +5,7 @@ */ #include "CSSNestedDeclarations.h" +#include #include #include #include @@ -48,7 +49,7 @@ void CSSNestedDeclarations::visit_edges(Cell::Visitor& visitor) static SelectorList absolutize_parent_selectors(CSSNestedDeclarations const& nested_declarations) { - static SelectorList s_where_scope_selector_list { + static NeverDestroyed where_scope_selector_list { SelectorList { Selector::create({ Selector::CompoundSelector { .combinator = Selector::Combinator::None, @@ -77,7 +78,7 @@ static SelectorList absolutize_parent_selectors(CSSNestedDeclarations const& nes }, }, }), - }; + } }; for (auto const* parent_rule = nested_declarations.parent_rule(); parent_rule; parent_rule = parent_rule->parent_rule()) { if (auto const* parent_style_rule = as_if(parent_rule)) @@ -86,7 +87,7 @@ static SelectorList absolutize_parent_selectors(CSSNestedDeclarations const& nes // https://drafts.csswg.org/css-cascade-6/#scoped-declarations // Declarations may be used directly with the body of a @scope rule. Contiguous runs of declarations are // wrapped in nested declarations rules, which match the scoping root with zero specificity. - return s_where_scope_selector_list; + return *where_scope_selector_list; } } diff --git a/Libraries/LibWeb/CSS/CounterStyle.cpp b/Libraries/LibWeb/CSS/CounterStyle.cpp index 8dc1363074..04f8676ba5 100644 --- a/Libraries/LibWeb/CSS/CounterStyle.cpp +++ b/Libraries/LibWeb/CSS/CounterStyle.cpp @@ -13,7 +13,7 @@ namespace Web::CSS { // https://drafts.csswg.org/css-counter-styles-3/#decimal NonnullRefPtr CounterStyle::decimal() { - static auto decimal_counter_style = CounterStyle::create( + static auto const& decimal_counter_style = CounterStyle::create( "decimal"_fly_string, GenericCounterStyleAlgorithm { CounterStyleSystem::Numeric, { "0"_fly_string, "1"_fly_string, "2"_fly_string, "3"_fly_string, "4"_fly_string, "5"_fly_string, "6"_fly_string, "7"_fly_string, "8"_fly_string, "9"_fly_string } }, CounterStyleNegativeSign { .prefix = "-"_fly_string, .suffix = ""_fly_string }, @@ -21,7 +21,8 @@ NonnullRefPtr CounterStyle::decimal() ". "_fly_string, { { NumericLimits::min(), NumericLimits::max() } }, {}, - CounterStylePad { .minimum_length = 0, .symbol = ""_fly_string }); + CounterStylePad { .minimum_length = 0, .symbol = ""_fly_string }) + .leak_ref(); return decimal_counter_style; } @@ -29,7 +30,7 @@ NonnullRefPtr CounterStyle::decimal() // https://drafts.csswg.org/css-counter-styles-3/#disc NonnullRefPtr CounterStyle::disc() { - static auto disc_counter_style = CounterStyle::create( + static auto const& disc_counter_style = CounterStyle::create( "disc"_fly_string, GenericCounterStyleAlgorithm { CounterStyleSystem::Cyclic, { "•"_fly_string } }, CounterStyleNegativeSign { .prefix = ""_fly_string, .suffix = " "_fly_string }, @@ -37,7 +38,8 @@ NonnullRefPtr CounterStyle::disc() " "_fly_string, { { NumericLimits::min(), NumericLimits::max() } }, "decimal"_fly_string, - CounterStylePad { .minimum_length = 0, .symbol = ""_fly_string }); + CounterStylePad { .minimum_length = 0, .symbol = ""_fly_string }) + .leak_ref(); return disc_counter_style; } diff --git a/Libraries/LibWeb/CSS/FontComputer.cpp b/Libraries/LibWeb/CSS/FontComputer.cpp index a669c1d45d..196a83fcb6 100644 --- a/Libraries/LibWeb/CSS/FontComputer.cpp +++ b/Libraries/LibWeb/CSS/FontComputer.cpp @@ -684,7 +684,7 @@ NonnullRefPtr FontComputer::compute_font_for_style_v Gfx::Font const& FontComputer::initial_font() const { // FIXME: This is not correct. - static auto font = ComputedProperties::font_fallback(false, false, 12); + static auto const& font = ComputedProperties::font_fallback(false, false, 12).leak_ref(); return font; } diff --git a/Libraries/LibWeb/CSS/Interpolation.cpp b/Libraries/LibWeb/CSS/Interpolation.cpp index 5cd95410aa..f21dec1acc 100644 --- a/Libraries/LibWeb/CSS/Interpolation.cpp +++ b/Libraries/LibWeb/CSS/Interpolation.cpp @@ -105,10 +105,10 @@ static RefPtr interpolate_scale(DOM::Element& element, Calcula if (a_from.to_keyword() == Keyword::None && a_to.to_keyword() == Keyword::None) return a_from; - static auto one = TransformationStyleValue::create(PropertyID::Scale, TransformFunction::Scale, { NumberStyleValue::create(1), NumberStyleValue::create(1) }); + static auto const& one = TransformationStyleValue::create(PropertyID::Scale, TransformFunction::Scale, { NumberStyleValue::create(1), NumberStyleValue::create(1) }).leak_ref(); - auto const& from = a_from.to_keyword() == Keyword::None ? *one : a_from; - auto const& to = a_to.to_keyword() == Keyword::None ? *one : a_to; + auto const& from = a_from.to_keyword() == Keyword::None ? one : a_from; + auto const& to = a_to.to_keyword() == Keyword::None ? one : a_to; auto const& from_transform = from.as_transformation(); auto const& to_transform = to.as_transformation(); @@ -122,9 +122,9 @@ static RefPtr interpolate_scale(DOM::Element& element, Calcula RefPtr interpolated_z; if (from_transform.values().size() == 3 || to_transform.values().size() == 3) { - static auto one_value = NumberStyleValue::create(1); - auto from = from_transform.values().size() == 3 ? from_transform.values()[2] : one_value; - auto to = to_transform.values().size() == 3 ? to_transform.values()[2] : one_value; + static auto const& one_value = NumberStyleValue::create(1).leak_ref(); + auto from = from_transform.values().size() == 3 ? from_transform.values()[2] : ValueComparingNonnullRefPtr { one_value }; + auto to = to_transform.values().size() == 3 ? to_transform.values()[2] : ValueComparingNonnullRefPtr { one_value }; interpolated_z = interpolate_value(element, calculation_context, from, to, delta, allow_discrete); if (!interpolated_z) return {}; @@ -363,11 +363,11 @@ static RefPtr interpolate_translate(DOM::Element& element, Cal if (a_from.to_keyword() == Keyword::None && a_to.to_keyword() == Keyword::None) return a_from; - static auto zero_px = LengthStyleValue::create(Length::make_px(0)); - static auto zero = TransformationStyleValue::create(PropertyID::Translate, TransformFunction::Translate, { zero_px, zero_px }); + static auto const& zero_px = LengthStyleValue::create(Length::make_px(0)).leak_ref(); + static auto const& zero = TransformationStyleValue::create(PropertyID::Translate, TransformFunction::Translate, { zero_px, zero_px }).leak_ref(); - auto const& from = a_from.to_keyword() == Keyword::None ? *zero : a_from; - auto const& to = a_to.to_keyword() == Keyword::None ? *zero : a_to; + auto const& from = a_from.to_keyword() == Keyword::None ? zero : a_from; + auto const& to = a_to.to_keyword() == Keyword::None ? zero : a_to; auto const& from_transform = from.as_transformation(); auto const& to_transform = to.as_transformation(); @@ -426,11 +426,11 @@ static RefPtr interpolate_rotate(DOM::Element& element, Calcul if (a_from.to_keyword() == Keyword::None && a_to.to_keyword() == Keyword::None) return a_from; - static auto zero_degrees_value = AngleStyleValue::create(Angle::make_degrees(0)); - static auto zero = TransformationStyleValue::create(PropertyID::Rotate, TransformFunction::Rotate, { zero_degrees_value }); + static auto const& zero_degrees_value = AngleStyleValue::create(Angle::make_degrees(0)).leak_ref(); + static auto const& zero = TransformationStyleValue::create(PropertyID::Rotate, TransformFunction::Rotate, { zero_degrees_value }).leak_ref(); - auto const& from = a_from.to_keyword() == Keyword::None ? *zero : a_from; - auto const& to = a_to.to_keyword() == Keyword::None ? *zero : a_to; + auto const& from = a_from.to_keyword() == Keyword::None ? zero : a_from; + auto const& to = a_to.to_keyword() == Keyword::None ? zero : a_to; auto const& from_transform = from.as_transformation(); auto const& to_transform = to.as_transformation(); @@ -674,9 +674,9 @@ ValueComparingRefPtr interpolate_property(DOM::Element& elemen } if (property_id == PropertyID::FontStyle) { - auto static oblique_0deg_value = FontStyleStyleValue::create(FontStyleKeyword::Oblique, AngleStyleValue::create(Angle::make_degrees(0))); - auto from_value = from->as_font_style().font_style() == FontStyleKeyword::Normal ? oblique_0deg_value : from; - auto to_value = to->as_font_style().font_style() == FontStyleKeyword::Normal ? oblique_0deg_value : to; + static auto const& oblique_0deg_value = FontStyleStyleValue::create(FontStyleKeyword::Oblique, AngleStyleValue::create(Angle::make_degrees(0))).leak_ref(); + auto from_value = from->as_font_style().font_style() == FontStyleKeyword::Normal ? ValueComparingNonnullRefPtr { oblique_0deg_value } : from; + auto to_value = to->as_font_style().font_style() == FontStyleKeyword::Normal ? ValueComparingNonnullRefPtr { oblique_0deg_value } : to; return interpolate_value(element, calculation_context, from_value, to_value, delta, allow_discrete); } diff --git a/Libraries/LibWeb/CSS/Parser/ErrorReporter.cpp b/Libraries/LibWeb/CSS/Parser/ErrorReporter.cpp index dadf8dbed7..8aa3e3b457 100644 --- a/Libraries/LibWeb/CSS/Parser/ErrorReporter.cpp +++ b/Libraries/LibWeb/CSS/Parser/ErrorReporter.cpp @@ -49,8 +49,8 @@ String serialize_parsing_error(ParsingError const& error) ErrorReporter& ErrorReporter::the() { - static ErrorReporter s_error_reporter {}; - return s_error_reporter; + static ErrorReporter& error_reporter = *new ErrorReporter; + return error_reporter; } void ErrorReporter::report(ParsingError&& error) diff --git a/Libraries/LibWeb/CSS/Parser/Helpers.cpp b/Libraries/LibWeb/CSS/Parser/Helpers.cpp index 43529c1c75..7d18a88c77 100644 --- a/Libraries/LibWeb/CSS/Parser/Helpers.cpp +++ b/Libraries/LibWeb/CSS/Parser/Helpers.cpp @@ -22,9 +22,9 @@ namespace Web { GC::Ref internal_css_realm() { - static GC::Root realm; - static GC::Root window; - static OwnPtr execution_context; + static auto& realm = *new GC::Root; + static auto& window = *new GC::Root; + static auto& execution_context = *new OwnPtr; if (!realm) { execution_context = Bindings::create_a_new_javascript_realm( Bindings::main_thread_vm(), diff --git a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp index e113c55524..a38c1cd43d 100644 --- a/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/PropertyParsing.cpp @@ -4637,7 +4637,7 @@ RefPtr Parser::parse_scroll_timeline_value(TokenStreamas_value_list().values()[0]; + static auto const& default_axis = *new ValueComparingNonnullRefPtr(property_initial_value(PropertyID::ScrollTimelineAxis)->as_value_list().values()[0]); tokens.discard_whitespace(); @@ -5981,11 +5981,17 @@ RefPtr Parser::parse_view_timeline_value(TokenStreamas_value_list().values()[0]; - static auto default_inset = property_initial_value(PropertyID::ViewTimelineInset)->as_value_list().values()[0]; + static auto const& default_axis = *new ValueComparingNonnullRefPtr(property_initial_value(PropertyID::ViewTimelineAxis)->as_value_list().values()[0]); + static auto const& default_inset = *new ValueComparingNonnullRefPtr(property_initial_value(PropertyID::ViewTimelineInset)->as_value_list().values()[0]); - axes.append(axis ? axis.release_nonnull() : default_axis); - insets.append(inset ? inset.release_nonnull() : default_inset); + if (axis) + axes.append(axis.release_nonnull()); + else + axes.append(default_axis); + if (inset) + insets.append(inset.release_nonnull()); + else + insets.append(default_inset); }; tokens.discard_whitespace(); diff --git a/Libraries/LibWeb/CSS/Selector.cpp b/Libraries/LibWeb/CSS/Selector.cpp index a214f5a659..9193b4860d 100644 --- a/Libraries/LibWeb/CSS/Selector.cpp +++ b/Libraries/LibWeb/CSS/Selector.cpp @@ -7,6 +7,7 @@ #include "Selector.h" #include +#include #include #include #include @@ -946,7 +947,7 @@ SelectorList adapt_nested_relative_selector_list(SelectorList const& selectors, SelectorList absolutize_selectors_relative_to(SelectorList const& selectors, GC::Ptr parent) { // NB: We use `:where(:scope)` to avoid adding specificity. - static Selector::SimpleSelector const s_where_scope_selector { + static NeverDestroyed where_scope_selector { Selector::SimpleSelector { .type = Selector::SimpleSelector::Type::PseudoClass, .value = Selector::SimpleSelector::PseudoClassSelector { .type = PseudoClass::Where, @@ -966,7 +967,7 @@ SelectorList absolutize_selectors_relative_to(SelectorList const& selectors, GC: }), }, }, - }; + } }; // Replace all occurrences of `&` with the nearest ancestor style rule's selector list wrapped in `:is(...)`, // or if we have no such ancestor, with `:scope`. @@ -994,7 +995,7 @@ SelectorList absolutize_selectors_relative_to(SelectorList const& selectors, GC: }; } - return s_where_scope_selector; + return *where_scope_selector; }(); SelectorList absolutized_selectors; diff --git a/Libraries/LibWeb/CSS/StyleComputer.cpp b/Libraries/LibWeb/CSS/StyleComputer.cpp index 32823d6f8b..8d4a8f3386 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -158,10 +159,10 @@ void StyleComputer::visit_edges(Visitor& visitor) Optional StyleComputer::user_agent_style_sheet_source(StringView name) { - extern String default_stylesheet_source; - extern String quirks_mode_stylesheet_source; - extern String mathml_stylesheet_source; - extern String svg_stylesheet_source; + extern String const& default_stylesheet_source; + extern String const& quirks_mode_stylesheet_source; + extern String const& mathml_stylesheet_source; + extern String const& svg_stylesheet_source; if (name == "CSS/Default.css"sv) return default_stylesheet_source; @@ -2197,9 +2198,9 @@ GC::Ptr StyleComputer::compute_style_impl(DOM::AbstractEleme if (did_change_custom_properties.has_value()) { auto new_custom_property_data = abstract_element.custom_property_data(); if (old_custom_property_data.ptr() != new_custom_property_data.ptr()) { - static OrderedHashMap const empty_own_values; - auto const& old_own = old_custom_property_data ? old_custom_property_data->own_values() : empty_own_values; - auto const& new_own = new_custom_property_data ? new_custom_property_data->own_values() : empty_own_values; + static NeverDestroyed> empty_own_values; + auto const& old_own = old_custom_property_data ? old_custom_property_data->own_values() : *empty_own_values; + auto const& new_own = new_custom_property_data ? new_custom_property_data->own_values() : *empty_own_values; if (old_own != new_own) *did_change_custom_properties = true; } @@ -2235,8 +2236,8 @@ RefPtr StyleComputer::recascade_font_size_if_needed(DOM::Abstr // FIXME: This should be configurable. constexpr CSSPixels default_monospace_font_size_in_px = 13; - static auto monospace_font_family_name = Platform::FontPlugin::the().generic_font_name(Platform::GenericFont::Monospace, 400, 0); - static auto monospace_font = Gfx::FontDatabase::the().get(monospace_font_family_name, default_monospace_font_size_in_px * 0.75f, 400, Gfx::FontWidth::Normal, 0); + static auto const& monospace_font_family_name = *new String(Platform::FontPlugin::the().generic_font_name(Platform::GenericFont::Monospace, 400, 0)); + static auto const& monospace_font = Gfx::FontDatabase::the().get(monospace_font_family_name, default_monospace_font_size_in_px * 0.75f, 400, Gfx::FontWidth::Normal, 0).release_nonnull().leak_ref(); // Reconstruct the line of ancestor elements we need to inherit style from, and then do the cascade again // but only for the font-size property. @@ -2305,7 +2306,7 @@ RefPtr StyleComputer::recascade_font_size_if_needed(DOM::Abstr bool did_resolve_viewport_relative_length = false; Length::ResolutionContext resolution_context { .viewport_rect = viewport_rect(), - .font_metrics = { current_size_in_px, monospace_font->with_size(current_size_in_px * 0.75f)->pixel_metrics(), inherited_line_height }, + .font_metrics = { current_size_in_px, monospace_font.with_size(current_size_in_px * 0.75f)->pixel_metrics(), inherited_line_height }, .root_font_metrics = m_root_element_font_metrics, .font_metrics_depend_on_viewport_metrics = current_size_depends_on_viewport_metrics || inherited_font_metrics_depend_on_viewport_metrics, .root_font_metrics_depend_on_viewport_metrics = m_root_element_font_metrics_depend_on_viewport_metrics, @@ -2864,7 +2865,7 @@ NonnullRefPtr StyleComputer::compute_corner_shape(NonnullRefPt case Keyword::Round: // The corner shape is a quarter of a convex ellipse. Equivalent to superellipse(1). // NB: We cache this value since 'round' is the initial value of the `corner-*-*-shape` properties - static NonnullRefPtr const cached_round_value = SuperellipseStyleValue::create(NumberStyleValue::create(1)); + static auto const& cached_round_value = SuperellipseStyleValue::create(NumberStyleValue::create(1)).leak_ref(); return cached_round_value; case Keyword::Squircle: // The corner shape is a quarter of a "squircle", a convex curve between round and square. Equivalent to superellipse(2). diff --git a/Libraries/LibWeb/CSS/StyleScope.cpp b/Libraries/LibWeb/CSS/StyleScope.cpp index bb7e93df90..9b7b225b86 100644 --- a/Libraries/LibWeb/CSS/StyleScope.cpp +++ b/Libraries/LibWeb/CSS/StyleScope.cpp @@ -199,9 +199,9 @@ void StyleScope::build_rule_cache_if_needed() const static CSSStyleSheet& default_stylesheet() { - static GC::Root sheet; + static auto& sheet = *new GC::Root; if (!sheet.cell()) { - extern String default_stylesheet_source; + extern String const& default_stylesheet_source; sheet = GC::make_root(parse_css_stylesheet(CSS::Parser::ParsingParams(internal_css_realm(), Parser::IsUAStyleSheet::Yes), default_stylesheet_source)); } return *sheet; @@ -209,9 +209,9 @@ static CSSStyleSheet& default_stylesheet() static CSSStyleSheet& quirks_mode_stylesheet() { - static GC::Root sheet; + static auto& sheet = *new GC::Root; if (!sheet.cell()) { - extern String quirks_mode_stylesheet_source; + extern String const& quirks_mode_stylesheet_source; sheet = GC::make_root(parse_css_stylesheet(CSS::Parser::ParsingParams(internal_css_realm(), Parser::IsUAStyleSheet::Yes), quirks_mode_stylesheet_source)); } return *sheet; @@ -219,9 +219,9 @@ static CSSStyleSheet& quirks_mode_stylesheet() static CSSStyleSheet& mathml_stylesheet() { - static GC::Root sheet; + static auto& sheet = *new GC::Root; if (!sheet.cell()) { - extern String mathml_stylesheet_source; + extern String const& mathml_stylesheet_source; sheet = GC::make_root(parse_css_stylesheet(CSS::Parser::ParsingParams(internal_css_realm(), Parser::IsUAStyleSheet::Yes), mathml_stylesheet_source)); } return *sheet; @@ -229,9 +229,9 @@ static CSSStyleSheet& mathml_stylesheet() static CSSStyleSheet& svg_stylesheet() { - static GC::Root sheet; + static auto& sheet = *new GC::Root; if (!sheet.cell()) { - extern String svg_stylesheet_source; + extern String const& svg_stylesheet_source; sheet = GC::make_root(parse_css_stylesheet(CSS::Parser::ParsingParams(internal_css_realm(), Parser::IsUAStyleSheet::Yes), svg_stylesheet_source)); } return *sheet; diff --git a/Libraries/LibWeb/CSS/StyleValues/EmptyOptionalStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/EmptyOptionalStyleValue.h index e7991d999a..665f0e0a39 100644 --- a/Libraries/LibWeb/CSS/StyleValues/EmptyOptionalStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/EmptyOptionalStyleValue.h @@ -14,7 +14,7 @@ class EmptyOptionalStyleValue final : public StyleValueWithDefaultOperators create() { - auto static const instance = adopt_ref(*new (nothrow) EmptyOptionalStyleValue()); + static auto& instance = adopt_ref(*new (nothrow) EmptyOptionalStyleValue()).leak_ref(); return instance; } diff --git a/Libraries/LibWeb/CSS/StyleValues/GuaranteedInvalidStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/GuaranteedInvalidStyleValue.h index ef973803e4..8849b603fa 100644 --- a/Libraries/LibWeb/CSS/StyleValues/GuaranteedInvalidStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/GuaranteedInvalidStyleValue.h @@ -15,7 +15,7 @@ class GuaranteedInvalidStyleValue final : public StyleValueWithDefaultOperators< public: static ValueComparingNonnullRefPtr create() { - static ValueComparingNonnullRefPtr instance = adopt_ref(*new (nothrow) GuaranteedInvalidStyleValue()); + static auto& instance = adopt_ref(*new (nothrow) GuaranteedInvalidStyleValue()).leak_ref(); return instance; } virtual ~GuaranteedInvalidStyleValue() override = default; diff --git a/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.cpp index bc736ab99b..0061e0037e 100644 --- a/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/ImageStyleValue.cpp @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -25,7 +26,11 @@ namespace Web::CSS { -static HashTable s_active_animation_timers; +static HashTable& active_animation_timers() +{ + static NeverDestroyed> timers; + return *timers; +} ValueComparingNonnullRefPtr ImageStyleValue::create(URL const& url) { @@ -48,7 +53,7 @@ ImageStyleValue::~ImageStyleValue() = default; u64 ImageStyleValue::active_animation_timer_count(DOM::Document const& document) { u64 count = 0; - for (auto const* image_style_value : s_active_animation_timers) { + for (auto const* image_style_value : active_animation_timers()) { if (any_of(image_style_value->m_clients, [&](auto const* client) { return client->document() == &document; })) @@ -125,14 +130,14 @@ void ImageStyleValue::start_animation_timer_if_needed(DOM::Document& document) c m_timer->set_interval(current_frame_duration()); m_timer->start(); - s_active_animation_timers.set(this); + active_animation_timers().set(this); } void ImageStyleValue::stop_animation_timer() const { if (m_timer && m_timer->is_active()) { m_timer->stop(); - s_active_animation_timers.remove(this); + active_animation_timers().remove(this); } } diff --git a/Libraries/LibWeb/CSS/StyleValues/KeywordStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/KeywordStyleValue.h index 192fb53a6f..6928d957e5 100644 --- a/Libraries/LibWeb/CSS/StyleValues/KeywordStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/KeywordStyleValue.h @@ -20,23 +20,23 @@ public: { switch (keyword) { case Keyword::Inherit: { - static ValueComparingNonnullRefPtr const inherit_instance = adopt_ref(*new (nothrow) KeywordStyleValue(Keyword::Inherit)); + static auto const& inherit_instance = adopt_ref(*new (nothrow) KeywordStyleValue(Keyword::Inherit)).leak_ref(); return inherit_instance; } case Keyword::Initial: { - static ValueComparingNonnullRefPtr const initial_instance = adopt_ref(*new (nothrow) KeywordStyleValue(Keyword::Initial)); + static auto const& initial_instance = adopt_ref(*new (nothrow) KeywordStyleValue(Keyword::Initial)).leak_ref(); return initial_instance; } case Keyword::Revert: { - static ValueComparingNonnullRefPtr const revert_instance = adopt_ref(*new (nothrow) KeywordStyleValue(Keyword::Revert)); + static auto const& revert_instance = adopt_ref(*new (nothrow) KeywordStyleValue(Keyword::Revert)).leak_ref(); return revert_instance; } case Keyword::RevertLayer: { - static ValueComparingNonnullRefPtr const revert_layer_instance = adopt_ref(*new (nothrow) KeywordStyleValue(Keyword::RevertLayer)); + static auto const& revert_layer_instance = adopt_ref(*new (nothrow) KeywordStyleValue(Keyword::RevertLayer)).leak_ref(); return revert_layer_instance; } case Keyword::Unset: { - static ValueComparingNonnullRefPtr const unset_instance = adopt_ref(*new (nothrow) KeywordStyleValue(Keyword::Unset)); + static auto const& unset_instance = adopt_ref(*new (nothrow) KeywordStyleValue(Keyword::Unset)).leak_ref(); return unset_instance; } default: diff --git a/Libraries/LibWeb/CSS/StyleValues/LengthStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/LengthStyleValue.cpp index 0971e9714e..32a05b3eff 100644 --- a/Libraries/LibWeb/CSS/StyleValues/LengthStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/LengthStyleValue.cpp @@ -15,11 +15,11 @@ ValueComparingNonnullRefPtr LengthStyleValue::create(Len { if (length.is_px()) { if (length.raw_value() == 0) { - static auto value = adopt_ref(*new (nothrow) LengthStyleValue(CSS::Length::make_px(0))); + static auto const& value = adopt_ref(*new (nothrow) LengthStyleValue(CSS::Length::make_px(0))).leak_ref(); return value; } if (length.raw_value() == 1) { - static auto value = adopt_ref(*new (nothrow) LengthStyleValue(CSS::Length::make_px(1))); + static auto const& value = adopt_ref(*new (nothrow) LengthStyleValue(CSS::Length::make_px(1))).leak_ref(); return value; } } diff --git a/Libraries/LibWeb/CSS/SyntaxHighlighter/SyntaxHighlighter.cpp b/Libraries/LibWeb/CSS/SyntaxHighlighter/SyntaxHighlighter.cpp index 203adc3805..436004331d 100644 --- a/Libraries/LibWeb/CSS/SyntaxHighlighter/SyntaxHighlighter.cpp +++ b/Libraries/LibWeb/CSS/SyntaxHighlighter/SyntaxHighlighter.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -156,14 +157,14 @@ void SyntaxHighlighter::rehighlight(Palette const& palette) Vector SyntaxHighlighter::matching_token_pairs_impl() const { - static Vector pairs; - if (pairs.is_empty()) { - pairs.append({ static_cast(CSS::Parser::Token::Type::OpenCurly), static_cast(CSS::Parser::Token::Type::CloseCurly) }); - pairs.append({ static_cast(CSS::Parser::Token::Type::OpenParen), static_cast(CSS::Parser::Token::Type::CloseParen) }); - pairs.append({ static_cast(CSS::Parser::Token::Type::OpenSquare), static_cast(CSS::Parser::Token::Type::CloseSquare) }); - pairs.append({ static_cast(CSS::Parser::Token::Type::CDO), static_cast(CSS::Parser::Token::Type::CDC) }); + static NeverDestroyed> pairs; + if (pairs->is_empty()) { + pairs->append({ static_cast(CSS::Parser::Token::Type::OpenCurly), static_cast(CSS::Parser::Token::Type::CloseCurly) }); + pairs->append({ static_cast(CSS::Parser::Token::Type::OpenParen), static_cast(CSS::Parser::Token::Type::CloseParen) }); + pairs->append({ static_cast(CSS::Parser::Token::Type::OpenSquare), static_cast(CSS::Parser::Token::Type::CloseSquare) }); + pairs->append({ static_cast(CSS::Parser::Token::Type::CDO), static_cast(CSS::Parser::Token::Type::CDC) }); } - return pairs; + return *pairs; } bool SyntaxHighlighter::token_types_equal(u64 token0, u64 token1) const diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveOperations.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveOperations.cpp index 3609c1d5a2..b47c633e41 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveOperations.cpp +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/DirectiveOperations.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -32,55 +33,59 @@ namespace Web::ContentSecurityPolicy::Directives { // Will return an ordered set of the fallback directives for a specific directive. // The returned ordered set is sorted from most relevant to least relevant and it includes the effective directive // itself. -static HashMap> fetch_directive_fallback_list { - // "script-src-elem" - // 1. Return << "script-src-elem", "script-src", "default-src" >>. - { "script-src-elem"sv, { "script-src-elem"sv, "script-src"sv, "default-src"sv } }, +static auto const& fetch_directive_fallback_list() +{ + static NeverDestroyed>> list { HashMap> { + // "script-src-elem" + // 1. Return << "script-src-elem", "script-src", "default-src" >>. + { "script-src-elem"sv, { "script-src-elem"sv, "script-src"sv, "default-src"sv } }, - // "script-src-attr" - // 1. Return << "script-src-attr", "script-src", "default-src" >>. - { "script-src-attr"sv, { "script-src-attr"sv, "script-src"sv, "default-src"sv } }, + // "script-src-attr" + // 1. Return << "script-src-attr", "script-src", "default-src" >>. + { "script-src-attr"sv, { "script-src-attr"sv, "script-src"sv, "default-src"sv } }, - // "style-src-elem" - // 1. Return << "style-src-elem", "style-src", "default-src" >>. - { "style-src-elem"sv, { "style-src-elem"sv, "style-src"sv, "default-src"sv } }, + // "style-src-elem" + // 1. Return << "style-src-elem", "style-src", "default-src" >>. + { "style-src-elem"sv, { "style-src-elem"sv, "style-src"sv, "default-src"sv } }, - // "style-src-attr" - // 1. Return << "style-src-attr", "style-src", "default-src" >>. - { "style-src-attr"sv, { "style-src-attr"sv, "style-src"sv, "default-src"sv } }, + // "style-src-attr" + // 1. Return << "style-src-attr", "style-src", "default-src" >>. + { "style-src-attr"sv, { "style-src-attr"sv, "style-src"sv, "default-src"sv } }, - // "worker-src" - // 1. Return << "worker-src", "child-src", "script-src", "default-src" >>. - { "worker-src"sv, { "worker-src"sv, "child-src"sv, "script-src"sv, "default-src"sv } }, + // "worker-src" + // 1. Return << "worker-src", "child-src", "script-src", "default-src" >>. + { "worker-src"sv, { "worker-src"sv, "child-src"sv, "script-src"sv, "default-src"sv } }, - // "connect-src" - // 1. Return << "connect-src", "default-src" >>. - { "connect-src"sv, { "connect-src"sv, "default-src"sv } }, + // "connect-src" + // 1. Return << "connect-src", "default-src" >>. + { "connect-src"sv, { "connect-src"sv, "default-src"sv } }, - // "manifest-src" - // 1. Return << "manifest-src", "default-src" >>. - { "manifest-src"sv, { "manifest-src"sv, "default-src"sv } }, + // "manifest-src" + // 1. Return << "manifest-src", "default-src" >>. + { "manifest-src"sv, { "manifest-src"sv, "default-src"sv } }, - // "object-src" - // 1. Return << "object-src", "default-src" >>. - { "object-src"sv, { "object-src"sv, "default-src"sv } }, + // "object-src" + // 1. Return << "object-src", "default-src" >>. + { "object-src"sv, { "object-src"sv, "default-src"sv } }, - // "frame-src" - // 1. Return << "frame-src", "child-src", "default-src" >>. - { "frame-src"sv, { "frame-src"sv, "child-src"sv, "default-src"sv } }, + // "frame-src" + // 1. Return << "frame-src", "child-src", "default-src" >>. + { "frame-src"sv, { "frame-src"sv, "child-src"sv, "default-src"sv } }, - // "media-src" - // 1. Return << "media-src", "default-src" >>. - { "media-src"sv, { "media-src"sv, "default-src"sv } }, + // "media-src" + // 1. Return << "media-src", "default-src" >>. + { "media-src"sv, { "media-src"sv, "default-src"sv } }, - // "font-src" - // 1. Return << "font-src", "default-src" >>. - { "font-src"sv, { "font-src"sv, "default-src"sv } }, + // "font-src" + // 1. Return << "font-src", "default-src" >>. + { "font-src"sv, { "font-src"sv, "default-src"sv } }, - // "img-src" - // 1. Return << "img-src", "default-src" >>. - { "img-src"sv, { "img-src"sv, "default-src"sv } }, -}; + // "img-src" + // 1. Return << "img-src", "default-src" >>. + { "img-src"sv, { "img-src"sv, "default-src"sv } }, + } }; + return *list; +} // https://w3c.github.io/webappsec-csp/#effective-directive-for-a-request Optional get_the_effective_directive_for_request(GC::Ref request) @@ -186,8 +191,8 @@ Vector get_fetch_directive_fallback_list(Optional directi if (!directive_name.has_value()) return {}; - auto list_iterator = fetch_directive_fallback_list.find(directive_name.value()); - if (list_iterator == fetch_directive_fallback_list.end()) + auto list_iterator = fetch_directive_fallback_list().find(directive_name.value()); + if (list_iterator == fetch_directive_fallback_list().end()) return {}; return list_iterator->value; diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordSources.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordSources.cpp index 5ec0532e33..28c64417da 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordSources.cpp +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordSources.cpp @@ -9,7 +9,7 @@ namespace Web::ContentSecurityPolicy::Directives::KeywordSources { #define __ENUMERATE_KEYWORD_SOURCE(name, value) \ - FlyString name = value##_fly_string; + FlyString const& name = *new FlyString(value##_fly_string); ENUMERATE_KEYWORD_SOURCES #undef __ENUMERATE_KEYWORD_SOURCE diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordSources.h b/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordSources.h index ab753f318e..6a0090f310 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordSources.h +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordSources.h @@ -21,7 +21,7 @@ namespace Web::ContentSecurityPolicy::Directives::KeywordSources { __ENUMERATE_KEYWORD_SOURCE(UnsafeAllowRedirects, "'unsafe-allow-redirects'") \ __ENUMERATE_KEYWORD_SOURCE(WasmUnsafeEval, "'wasm-unsafe-eval'") -#define __ENUMERATE_KEYWORD_SOURCE(name, value) extern FlyString name; +#define __ENUMERATE_KEYWORD_SOURCE(name, value) extern FlyString const& name; ENUMERATE_KEYWORD_SOURCES #undef __ENUMERATE_KEYWORD_SOURCE diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordTrustedTypes.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordTrustedTypes.cpp index 08d4bd1373..cca55a25fd 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordTrustedTypes.cpp +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordTrustedTypes.cpp @@ -9,7 +9,7 @@ namespace Web::ContentSecurityPolicy::Directives::KeywordTrustedTypes { #define __ENUMERATE_KEYWORD_TRUSTED_TYPE(name, value) \ - FlyString name = value##_fly_string; + FlyString const& name = *new FlyString(value##_fly_string); ENUMERATE_KEYWORD_TRUSTED_TYPES #undef __ENUMERATE_KEYWORD_TRUSTED_TYPE diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordTrustedTypes.h b/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordTrustedTypes.h index a07ad3c38c..6d79ca807e 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordTrustedTypes.h +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/KeywordTrustedTypes.h @@ -16,7 +16,7 @@ namespace Web::ContentSecurityPolicy::Directives::KeywordTrustedTypes { __ENUMERATE_KEYWORD_TRUSTED_TYPE(None, "'none'") \ __ENUMERATE_KEYWORD_TRUSTED_TYPE(WildCard, "*") -#define __ENUMERATE_KEYWORD_TRUSTED_TYPE(name, value) extern FlyString name; +#define __ENUMERATE_KEYWORD_TRUSTED_TYPE(name, value) extern FlyString const& name; ENUMERATE_KEYWORD_TRUSTED_TYPES #undef __ENUMERATE_KEYWORD_TRUSTED_TYPE diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/Names.cpp b/Libraries/LibWeb/ContentSecurityPolicy/Directives/Names.cpp index 11df1b5748..a21aad3752 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/Names.cpp +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/Names.cpp @@ -9,7 +9,7 @@ namespace Web::ContentSecurityPolicy::Directives::Names { #define __ENUMERATE_DIRECTIVE_NAME(name, value) \ - FlyString name = value##_fly_string; + FlyString const& name = *new FlyString(value##_fly_string); ENUMERATE_DIRECTIVE_NAMES #undef __ENUMERATE_DIRECTIVE_NAME diff --git a/Libraries/LibWeb/ContentSecurityPolicy/Directives/Names.h b/Libraries/LibWeb/ContentSecurityPolicy/Directives/Names.h index d1a77e5f04..31e9882892 100644 --- a/Libraries/LibWeb/ContentSecurityPolicy/Directives/Names.h +++ b/Libraries/LibWeb/ContentSecurityPolicy/Directives/Names.h @@ -37,7 +37,7 @@ namespace Web::ContentSecurityPolicy::Directives::Names { __ENUMERATE_DIRECTIVE_NAME(WebRTC, "webrtc") \ __ENUMERATE_DIRECTIVE_NAME(WorkerSrc, "worker-src") -#define __ENUMERATE_DIRECTIVE_NAME(name, value) extern FlyString name; +#define __ENUMERATE_DIRECTIVE_NAME(name, value) extern FlyString const& name; ENUMERATE_DIRECTIVE_NAMES #undef __ENUMERATE_DIRECTIVE_NAME diff --git a/Libraries/LibWeb/Crypto/SubtleCrypto.cpp b/Libraries/LibWeb/Crypto/SubtleCrypto.cpp index 442e14540c..dae3a64432 100644 --- a/Libraries/LibWeb/Crypto/SubtleCrypto.cpp +++ b/Libraries/LibWeb/Crypto/SubtleCrypto.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -1573,8 +1574,8 @@ GC::Ref SubtleCrypto::decapsulate_bits(AlgorithmIdentifier deca SupportedAlgorithmsMap& supported_algorithms_internal() { - static SupportedAlgorithmsMap s_supported_algorithms; - return s_supported_algorithms; + static NeverDestroyed supported_algorithms; + return *supported_algorithms; } // https://w3c.github.io/webcrypto/#algorithm-normalization-internal diff --git a/Libraries/LibWeb/DOM/DOMTokenList.cpp b/Libraries/LibWeb/DOM/DOMTokenList.cpp index 597cfcbbbc..5268d6064d 100644 --- a/Libraries/LibWeb/DOM/DOMTokenList.cpp +++ b/Libraries/LibWeb/DOM/DOMTokenList.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -237,7 +238,7 @@ WebIDL::ExceptionOr DOMTokenList::supports(StringView token) // https://dom.spec.whatwg.org/#concept-domtokenlist-validation WebIDL::ExceptionOr DOMTokenList::run_validation_steps(StringView token) { - static HashMap> supported_tokens_map = { + static NeverDestroyed>> supported_tokens_map { HashMap> { // https://html.spec.whatwg.org/multipage/links.html#linkTypes { { HTML::TagNames::link, HTML::AttributeNames::rel }, { "modulepreload"sv, "preload"sv, "preconnect"sv, "dns-prefetch"sv, "stylesheet"sv, "icon"sv, "alternate"sv, "prefetch"sv, "prerender"sv, "next"sv, "manifest"sv, "apple-touch-icon"sv, "apple-touch-icon-precomposed"sv, "canonical"sv } }, @@ -251,10 +252,10 @@ WebIDL::ExceptionOr DOMTokenList::run_validation_steps(StringView token) // https://html.spec.whatwg.org/multipage/iframe-embed-object.html#attr-iframe-sandbox { { HTML::TagNames::iframe, HTML::AttributeNames::sandbox }, { "allow-downloads"sv, "allow-forms"sv, "allow-modals"sv, "allow-orientation-lock"sv, "allow-pointer-lock"sv, "allow-popups"sv, "allow-popups-to-escape-sandbox"sv, "allow-presentation"sv, "allow-same-origin"sv, "allow-scripts"sv, "allow-top-navigation"sv, "allow-top-navigation-by-user-activation"sv, "allow-top-navigation-to-custom-protocols"sv } }, - }; + } }; // 1. If set’s element and attribute name does not define supported tokens, then throw a TypeError. - auto supported_tokens = supported_tokens_map.get({ m_associated_element->local_name(), m_associated_attribute }); + auto supported_tokens = supported_tokens_map->get({ m_associated_element->local_name(), m_associated_attribute }); if (!supported_tokens.has_value()) return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, MUST(String::formatted("Attribute {} does not define any supported tokens", m_associated_attribute)) }; diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 3d1e91fb59..bdf6f66079 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -3547,8 +3547,8 @@ DocumentType const* Document::doctype() const String const& Document::compat_mode() const { - static String const back_compat = "BackCompat"_string; - static String const css1_compat = "CSS1Compat"_string; + static String const& back_compat = *new String("BackCompat"_string); + static String const& css1_compat = *new String("CSS1Compat"_string); if (m_quirks_mode == QuirksMode::Yes) return back_compat; diff --git a/Libraries/LibWeb/DOM/DocumentLoading.cpp b/Libraries/LibWeb/DOM/DocumentLoading.cpp index 6b58bad445..501241a351 100644 --- a/Libraries/LibWeb/DOM/DocumentLoading.cpp +++ b/Libraries/LibWeb/DOM/DocumentLoading.cpp @@ -6,8 +6,10 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include +#include #include #include #include @@ -421,7 +423,7 @@ static GC::Ref load_pdf_document(HTML::NavigationParams const& na VERIFY(navigation_params.response->url().has_value()); auto pdf_url = navigation_params.response->url().value(); - static auto const s_viewer_bytes = MUST(Core::Resource::load_from_uri("resource://ladybird/pdfjs/web/viewer.html"sv))->clone_data(); + static NeverDestroyed viewer_bytes { MUST(Core::Resource::load_from_uri("resource://ladybird/pdfjs/web/viewer.html"sv))->clone_data() }; auto document = MUST(DOM::Document::create_and_initialize(DOM::Document::Type::HTML, "text/html"_string, navigation_params)); document->set_origin(URL::Origin("resource"_string, String {}, {})); @@ -441,7 +443,7 @@ static GC::Ref load_pdf_document(HTML::NavigationParams const& na document->add_event_listener_without_options("ladybirdviewerready"_fly_string, *DOM::IDLEventListener::create(realm, *callback)); Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(document->heap(), [document, pdf_url] { - auto parser = HTML::HTMLParser::create_with_uncertain_encoding(document, s_viewer_bytes); + auto parser = HTML::HTMLParser::create_with_uncertain_encoding(document, *viewer_bytes); if (document->ready_to_run_scripts()) { parser->run(pdf_url); } else { diff --git a/Libraries/LibWeb/DOM/MutationType.cpp b/Libraries/LibWeb/DOM/MutationType.cpp index 2c66b8fe07..395429113b 100644 --- a/Libraries/LibWeb/DOM/MutationType.cpp +++ b/Libraries/LibWeb/DOM/MutationType.cpp @@ -9,7 +9,7 @@ namespace Web::DOM::MutationType { #define __ENUMERATE_MUTATION_TYPE(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_MUTATION_TYPES #undef __ENUMERATE_MUTATION_TYPE diff --git a/Libraries/LibWeb/DOM/MutationType.h b/Libraries/LibWeb/DOM/MutationType.h index 993cd748f7..fda2db6777 100644 --- a/Libraries/LibWeb/DOM/MutationType.h +++ b/Libraries/LibWeb/DOM/MutationType.h @@ -16,7 +16,7 @@ namespace Web::DOM::MutationType { __ENUMERATE_MUTATION_TYPE(characterData) \ __ENUMERATE_MUTATION_TYPE(childList) -#define __ENUMERATE_MUTATION_TYPE(name) extern WEB_API FlyString name; +#define __ENUMERATE_MUTATION_TYPE(name) extern WEB_API FlyString const& name; ENUMERATE_MUTATION_TYPES #undef __ENUMERATE_MUTATION_TYPE diff --git a/Libraries/LibWeb/DOM/Node.cpp b/Libraries/LibWeb/DOM/Node.cpp index 1f59a17ada..bc1af2db1e 100644 --- a/Libraries/LibWeb/DOM/Node.cpp +++ b/Libraries/LibWeb/DOM/Node.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -82,8 +83,8 @@ namespace Web::DOM { static UniqueNodeID s_next_unique_id; static GC::WeakHashMap& node_directory() { - static GC::WeakHashMap directory; - return directory; + static NeverDestroyed> directory; + return *directory; } static UniqueNodeID allocate_unique_id(Node& node) diff --git a/Libraries/LibWeb/DOM/QualifiedName.cpp b/Libraries/LibWeb/DOM/QualifiedName.cpp index 531a2af72f..c261d4d9b1 100644 --- a/Libraries/LibWeb/DOM/QualifiedName.cpp +++ b/Libraries/LibWeb/DOM/QualifiedName.cpp @@ -5,6 +5,7 @@ */ #include +#include #include namespace Web::DOM { @@ -33,18 +34,22 @@ struct ImplTraits : public Traits { } }; -static HashTable impls; +static HashTable& impls() +{ + static NeverDestroyed> impls; + return *impls; +} static NonnullRefPtr ensure_impl(FlyString const& local_name, Optional const& prefix, Optional const& namespace_) { unsigned hash = hash_impl(local_name, prefix, namespace_); - auto it = impls.find(hash, [&](QualifiedName::Impl* entry) { + auto it = impls().find(hash, [&](QualifiedName::Impl* entry) { return entry->local_name == local_name && entry->prefix == prefix && entry->namespace_ == namespace_; }); - if (it != impls.end()) + if (it != impls().end()) return *(*it); return adopt_ref(*new QualifiedName::Impl(local_name, prefix, namespace_)); } @@ -60,13 +65,13 @@ QualifiedName::Impl::Impl(FlyString const& a_local_name, Optional con , prefix(a_prefix) , namespace_(a_namespace) { - impls.set(this); + impls().set(this); make_internal_string(); } QualifiedName::Impl::~Impl() { - impls.remove(this); + impls().remove(this); } // https://dom.spec.whatwg.org/#concept-attribute-qualified-name diff --git a/Libraries/LibWeb/DOM/Range.cpp b/Libraries/LibWeb/DOM/Range.cpp index 4afced455f..7279fc4679 100644 --- a/Libraries/LibWeb/DOM/Range.cpp +++ b/Libraries/LibWeb/DOM/Range.cpp @@ -8,6 +8,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -41,8 +42,8 @@ GC_DEFINE_ALLOCATOR(Range); HashTable& Range::live_ranges() { - static HashTable ranges; - return ranges; + static NeverDestroyed> ranges; + return *ranges; } GC::Ref Range::create(HTML::Window& window) diff --git a/Libraries/LibWeb/Editing/CommandNames.cpp b/Libraries/LibWeb/Editing/CommandNames.cpp index a86f4c5a8c..da8c32fe1d 100644 --- a/Libraries/LibWeb/Editing/CommandNames.cpp +++ b/Libraries/LibWeb/Editing/CommandNames.cpp @@ -9,7 +9,7 @@ namespace Web::Editing::CommandNames { #define __ENUMERATE_COMMAND_NAME(name, command) \ - FlyString name = command##_fly_string; + FlyString const& name = *new FlyString(command##_fly_string); ENUMERATE_COMMAND_NAMES #undef __ENUMERATE_COMMAND_NAME diff --git a/Libraries/LibWeb/Editing/CommandNames.h b/Libraries/LibWeb/Editing/CommandNames.h index 84d9f7e5fc..fbb0817fe5 100644 --- a/Libraries/LibWeb/Editing/CommandNames.h +++ b/Libraries/LibWeb/Editing/CommandNames.h @@ -53,7 +53,7 @@ namespace Web::Editing::CommandNames { __ENUMERATE_COMMAND_NAME(unlink, "unlink") \ __ENUMERATE_COMMAND_NAME(useCSS, "useCSS") -#define __ENUMERATE_COMMAND_NAME(name, command) extern FlyString name; +#define __ENUMERATE_COMMAND_NAME(name, command) extern FlyString const& name; ENUMERATE_COMMAND_NAMES #undef __ENUMERATE_COMMAND_NAME diff --git a/Libraries/LibWeb/Editing/Commands.cpp b/Libraries/LibWeb/Editing/Commands.cpp index 7a6ce31628..5ae617dc1c 100644 --- a/Libraries/LibWeb/Editing/Commands.cpp +++ b/Libraries/LibWeb/Editing/Commands.cpp @@ -2508,269 +2508,273 @@ bool command_use_css_action(DOM::Document& document, Utf16String const& value) return true; } -static Array const commands { - // https://w3c.github.io/editing/docs/execCommand/#the-backcolor-command - CommandDefinition { - .command = CommandNames::backColor, - .action = command_back_color_action, - .relevant_css_property = CSS::PropertyID::BackgroundColor, - .mapped_value = "formatBackColor"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-bold-command - CommandDefinition { - .command = CommandNames::bold, - .action = command_bold_action, - .relevant_css_property = CSS::PropertyID::FontWeight, - .inline_activated_values = { "bold"sv, "600"sv, "700"sv, "800"sv, "900"sv }, - .mapped_value = "formatBold"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-createlink-command - CommandDefinition { - .command = CommandNames::createLink, - .action = command_create_link_action, - .mapped_value = "insertLink"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-delete-command - CommandDefinition { - .command = CommandNames::delete_, - .action = command_delete_action, - .preserves_overrides = true, - .mapped_value = "deleteContentBackward"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-defaultparagraphseparator-command - CommandDefinition { - .command = CommandNames::defaultParagraphSeparator, - .action = command_default_paragraph_separator_action, - .value = command_default_paragraph_separator_value, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-fontname-command - CommandDefinition { - .command = CommandNames::fontName, - .action = command_font_name_action, - .relevant_css_property = CSS::PropertyID::FontFamily, - .mapped_value = "formatFontName"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-fontsize-command - CommandDefinition { - .command = CommandNames::fontSize, - .action = command_font_size_action, - .value = command_font_size_value, - .relevant_css_property = CSS::PropertyID::FontSize, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-forecolor-command - CommandDefinition { - .command = CommandNames::foreColor, - .action = command_fore_color_action, - .relevant_css_property = CSS::PropertyID::Color, - .mapped_value = "formatFontColor"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-formatblock-command - CommandDefinition { - .command = CommandNames::formatBlock, - .action = command_format_block_action, - .indeterminate = command_format_block_indeterminate, - .value = command_format_block_value, - .preserves_overrides = true, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-forwarddelete-command - CommandDefinition { - .command = CommandNames::forwardDelete, - .action = command_forward_delete_action, - .preserves_overrides = true, - .mapped_value = "deleteContentForward"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-hilitecolor-command - CommandDefinition { - .command = CommandNames::hiliteColor, - .action = command_back_color_action, // For historical reasons, backColor and hiliteColor behave identically. - .relevant_css_property = CSS::PropertyID::BackgroundColor, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-indent-command - CommandDefinition { - .command = CommandNames::indent, - .action = command_indent_action, - .preserves_overrides = true, - .mapped_value = "formatIndent"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-inserthorizontalrule-command - CommandDefinition { - .command = CommandNames::insertHorizontalRule, - .action = command_insert_horizontal_rule_action, - .preserves_overrides = true, - .mapped_value = "insertHorizontalRule"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-inserthtml-command - CommandDefinition { - .command = CommandNames::insertHTML, - .action = command_insert_html_action, - .preserves_overrides = true, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-insertimage-command - CommandDefinition { - .command = CommandNames::insertImage, - .action = command_insert_image_action, - .preserves_overrides = true, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-insertlinebreak-command - CommandDefinition { - .command = CommandNames::insertLineBreak, - .action = command_insert_linebreak_action, - .preserves_overrides = true, - .mapped_value = "insertLineBreak"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-insertorderedlist-command - CommandDefinition { - .command = CommandNames::insertOrderedList, - .action = command_insert_ordered_list_action, - .indeterminate = command_insert_ordered_list_indeterminate, - .state = command_insert_ordered_list_state, - .preserves_overrides = true, - .mapped_value = "insertOrderedList"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-insertparagraph-command - CommandDefinition { - .command = CommandNames::insertParagraph, - .action = command_insert_paragraph_action, - .preserves_overrides = true, - .mapped_value = "insertParagraph"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-inserttext-command - CommandDefinition { - .command = CommandNames::insertText, - .action = command_insert_text_action, - .mapped_value = "insertText"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-insertunorderedlist-command - CommandDefinition { - .command = CommandNames::insertUnorderedList, - .action = command_insert_unordered_list_action, - .indeterminate = command_insert_unordered_list_indeterminate, - .state = command_insert_unordered_list_state, - .preserves_overrides = true, - .mapped_value = "insertUnorderedList"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-italic-command - CommandDefinition { - .command = CommandNames::italic, - .action = command_italic_action, - .relevant_css_property = CSS::PropertyID::FontStyle, - .inline_activated_values = { "italic"sv, "oblique"sv }, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-justifycenter-command - CommandDefinition { - .command = CommandNames::justifyCenter, - .action = command_justify_center_action, - .indeterminate = command_justify_center_indeterminate, - .state = command_justify_center_state, - .value = command_justify_center_value, - .preserves_overrides = true, - .mapped_value = "formatJustifyCenter"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-justifyfull-command - CommandDefinition { - .command = CommandNames::justifyFull, - .action = command_justify_full_action, - .indeterminate = command_justify_full_indeterminate, - .state = command_justify_full_state, - .value = command_justify_full_value, - .preserves_overrides = true, - .mapped_value = "formatJustifyFull"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-justifyleft-command - CommandDefinition { - .command = CommandNames::justifyLeft, - .action = command_justify_left_action, - .indeterminate = command_justify_left_indeterminate, - .state = command_justify_left_state, - .value = command_justify_left_value, - .preserves_overrides = true, - .mapped_value = "formatJustifyLeft"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-justifyright-command - CommandDefinition { - .command = CommandNames::justifyRight, - .action = command_justify_right_action, - .indeterminate = command_justify_right_indeterminate, - .state = command_justify_right_state, - .value = command_justify_right_value, - .preserves_overrides = true, - .mapped_value = "formatJustifyRight"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-outdent-command - CommandDefinition { - .command = CommandNames::outdent, - .action = command_outdent_action, - .preserves_overrides = true, - .mapped_value = "formatOutdent"_fly_string, - }, - // AD-HOC: This is a Ladybird-specific formatting command that is not part of the spec. It has no action and as - // such, it's not supported in userland (yet). The relevant CSS property `white-space` is used to indicate - // that if this style value is found during editing commands, it is recorded and restored where necessary. - // This is used to keep things like
..
intact when a selection is - // deleted, for example. - CommandDefinition { - .command = CommandNames::preserveWhitespace, - .relevant_css_property = CSS::PropertyID::WhiteSpace, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-removeformat-command - CommandDefinition { - .command = CommandNames::removeFormat, - .action = command_remove_format_action, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-selectall-command - CommandDefinition { - .command = CommandNames::selectAll, - .action = command_select_all_action, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-strikethrough-command - CommandDefinition { - .command = CommandNames::strikethrough, - .action = command_strikethrough_action, - .inline_activated_values = { "line-through"sv }, - .mapped_value = "formatStrikeThrough"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-stylewithcss-command - CommandDefinition { - .command = CommandNames::styleWithCSS, - .action = command_style_with_css_action, - .state = command_style_with_css_state, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-subscript-command - CommandDefinition { - .command = CommandNames::subscript, - .action = command_subscript_action, - .indeterminate = command_subscript_indeterminate, - .inline_activated_values = { "subscript"sv }, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-superscript-command - CommandDefinition { - .command = CommandNames::superscript, - .action = command_superscript_action, - .indeterminate = command_superscript_indeterminate, - .inline_activated_values = { "superscript"sv }, - .mapped_value = "formatSuperscript"_fly_string, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-underline-command - CommandDefinition { - .command = CommandNames::underline, - .action = command_underline_action, - .inline_activated_values = { "underline"sv }, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-unlink-command - CommandDefinition { - .command = CommandNames::unlink, - .action = command_unlink_action, - }, - // https://w3c.github.io/editing/docs/execCommand/#the-usecss-command - CommandDefinition { - .command = CommandNames::useCSS, - .action = command_use_css_action, - }, -}; +static auto const& command_definitions() +{ + static auto const& definitions = *new Array { + // https://w3c.github.io/editing/docs/execCommand/#the-backcolor-command + CommandDefinition { + .command = CommandNames::backColor, + .action = command_back_color_action, + .relevant_css_property = CSS::PropertyID::BackgroundColor, + .mapped_value = "formatBackColor"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-bold-command + CommandDefinition { + .command = CommandNames::bold, + .action = command_bold_action, + .relevant_css_property = CSS::PropertyID::FontWeight, + .inline_activated_values = { "bold"sv, "600"sv, "700"sv, "800"sv, "900"sv }, + .mapped_value = "formatBold"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-createlink-command + CommandDefinition { + .command = CommandNames::createLink, + .action = command_create_link_action, + .mapped_value = "insertLink"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-delete-command + CommandDefinition { + .command = CommandNames::delete_, + .action = command_delete_action, + .preserves_overrides = true, + .mapped_value = "deleteContentBackward"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-defaultparagraphseparator-command + CommandDefinition { + .command = CommandNames::defaultParagraphSeparator, + .action = command_default_paragraph_separator_action, + .value = command_default_paragraph_separator_value, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-fontname-command + CommandDefinition { + .command = CommandNames::fontName, + .action = command_font_name_action, + .relevant_css_property = CSS::PropertyID::FontFamily, + .mapped_value = "formatFontName"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-fontsize-command + CommandDefinition { + .command = CommandNames::fontSize, + .action = command_font_size_action, + .value = command_font_size_value, + .relevant_css_property = CSS::PropertyID::FontSize, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-forecolor-command + CommandDefinition { + .command = CommandNames::foreColor, + .action = command_fore_color_action, + .relevant_css_property = CSS::PropertyID::Color, + .mapped_value = "formatFontColor"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-formatblock-command + CommandDefinition { + .command = CommandNames::formatBlock, + .action = command_format_block_action, + .indeterminate = command_format_block_indeterminate, + .value = command_format_block_value, + .preserves_overrides = true, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-forwarddelete-command + CommandDefinition { + .command = CommandNames::forwardDelete, + .action = command_forward_delete_action, + .preserves_overrides = true, + .mapped_value = "deleteContentForward"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-hilitecolor-command + CommandDefinition { + .command = CommandNames::hiliteColor, + .action = command_back_color_action, // For historical reasons, backColor and hiliteColor behave identically. + .relevant_css_property = CSS::PropertyID::BackgroundColor, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-indent-command + CommandDefinition { + .command = CommandNames::indent, + .action = command_indent_action, + .preserves_overrides = true, + .mapped_value = "formatIndent"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-inserthorizontalrule-command + CommandDefinition { + .command = CommandNames::insertHorizontalRule, + .action = command_insert_horizontal_rule_action, + .preserves_overrides = true, + .mapped_value = "insertHorizontalRule"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-inserthtml-command + CommandDefinition { + .command = CommandNames::insertHTML, + .action = command_insert_html_action, + .preserves_overrides = true, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-insertimage-command + CommandDefinition { + .command = CommandNames::insertImage, + .action = command_insert_image_action, + .preserves_overrides = true, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-insertlinebreak-command + CommandDefinition { + .command = CommandNames::insertLineBreak, + .action = command_insert_linebreak_action, + .preserves_overrides = true, + .mapped_value = "insertLineBreak"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-insertorderedlist-command + CommandDefinition { + .command = CommandNames::insertOrderedList, + .action = command_insert_ordered_list_action, + .indeterminate = command_insert_ordered_list_indeterminate, + .state = command_insert_ordered_list_state, + .preserves_overrides = true, + .mapped_value = "insertOrderedList"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-insertparagraph-command + CommandDefinition { + .command = CommandNames::insertParagraph, + .action = command_insert_paragraph_action, + .preserves_overrides = true, + .mapped_value = "insertParagraph"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-inserttext-command + CommandDefinition { + .command = CommandNames::insertText, + .action = command_insert_text_action, + .mapped_value = "insertText"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-insertunorderedlist-command + CommandDefinition { + .command = CommandNames::insertUnorderedList, + .action = command_insert_unordered_list_action, + .indeterminate = command_insert_unordered_list_indeterminate, + .state = command_insert_unordered_list_state, + .preserves_overrides = true, + .mapped_value = "insertUnorderedList"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-italic-command + CommandDefinition { + .command = CommandNames::italic, + .action = command_italic_action, + .relevant_css_property = CSS::PropertyID::FontStyle, + .inline_activated_values = { "italic"sv, "oblique"sv }, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-justifycenter-command + CommandDefinition { + .command = CommandNames::justifyCenter, + .action = command_justify_center_action, + .indeterminate = command_justify_center_indeterminate, + .state = command_justify_center_state, + .value = command_justify_center_value, + .preserves_overrides = true, + .mapped_value = "formatJustifyCenter"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-justifyfull-command + CommandDefinition { + .command = CommandNames::justifyFull, + .action = command_justify_full_action, + .indeterminate = command_justify_full_indeterminate, + .state = command_justify_full_state, + .value = command_justify_full_value, + .preserves_overrides = true, + .mapped_value = "formatJustifyFull"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-justifyleft-command + CommandDefinition { + .command = CommandNames::justifyLeft, + .action = command_justify_left_action, + .indeterminate = command_justify_left_indeterminate, + .state = command_justify_left_state, + .value = command_justify_left_value, + .preserves_overrides = true, + .mapped_value = "formatJustifyLeft"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-justifyright-command + CommandDefinition { + .command = CommandNames::justifyRight, + .action = command_justify_right_action, + .indeterminate = command_justify_right_indeterminate, + .state = command_justify_right_state, + .value = command_justify_right_value, + .preserves_overrides = true, + .mapped_value = "formatJustifyRight"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-outdent-command + CommandDefinition { + .command = CommandNames::outdent, + .action = command_outdent_action, + .preserves_overrides = true, + .mapped_value = "formatOutdent"_fly_string, + }, + // AD-HOC: This is a Ladybird-specific formatting command that is not part of the spec. It has no action and as + // such, it's not supported in userland (yet). The relevant CSS property `white-space` is used to indicate + // that if this style value is found during editing commands, it is recorded and restored where necessary. + // This is used to keep things like
..
intact when a selection is + // deleted, for example. + CommandDefinition { + .command = CommandNames::preserveWhitespace, + .relevant_css_property = CSS::PropertyID::WhiteSpace, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-removeformat-command + CommandDefinition { + .command = CommandNames::removeFormat, + .action = command_remove_format_action, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-selectall-command + CommandDefinition { + .command = CommandNames::selectAll, + .action = command_select_all_action, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-strikethrough-command + CommandDefinition { + .command = CommandNames::strikethrough, + .action = command_strikethrough_action, + .inline_activated_values = { "line-through"sv }, + .mapped_value = "formatStrikeThrough"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-stylewithcss-command + CommandDefinition { + .command = CommandNames::styleWithCSS, + .action = command_style_with_css_action, + .state = command_style_with_css_state, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-subscript-command + CommandDefinition { + .command = CommandNames::subscript, + .action = command_subscript_action, + .indeterminate = command_subscript_indeterminate, + .inline_activated_values = { "subscript"sv }, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-superscript-command + CommandDefinition { + .command = CommandNames::superscript, + .action = command_superscript_action, + .indeterminate = command_superscript_indeterminate, + .inline_activated_values = { "superscript"sv }, + .mapped_value = "formatSuperscript"_fly_string, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-underline-command + CommandDefinition { + .command = CommandNames::underline, + .action = command_underline_action, + .inline_activated_values = { "underline"sv }, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-unlink-command + CommandDefinition { + .command = CommandNames::unlink, + .action = command_unlink_action, + }, + // https://w3c.github.io/editing/docs/execCommand/#the-usecss-command + CommandDefinition { + .command = CommandNames::useCSS, + .action = command_use_css_action, + }, + }; + return definitions; +} Optional find_command_definition(FlyString const& command) { - for (auto& definition : commands) { + for (auto& definition : command_definitions()) { if (command.equals_ignoring_ascii_case(definition.command)) return definition; } diff --git a/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp b/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp index f17d04f75a..1c2014632f 100644 --- a/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp +++ b/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp @@ -95,8 +95,8 @@ public: static HTTPCache& the() { - static HTTPCache s_cache; - return s_cache; + static HTTPCache& cache = *new HTTPCache; + return cache; } void clear_cache() @@ -2569,7 +2569,7 @@ void set_sec_fetch_user_header(Infrastructure::Request& request) // 4. Set header’s value to true. // NOTE: See https://datatracker.ietf.org/doc/html/rfc8941#name-booleans for boolean format in RFC 8941. - static ByteString value = "?1"sv; + static ByteString const& value = *new ByteString("?1"sv); // 5. Set a structured field value `Sec-Fetch-User`/header in r’s header list. request.header_list()->append({ "Sec-Fetch-User"sv, value }); diff --git a/Libraries/LibWeb/FileAPI/BlobURLStore.cpp b/Libraries/LibWeb/FileAPI/BlobURLStore.cpp index 6eef516822..b3c2f05a63 100644 --- a/Libraries/LibWeb/FileAPI/BlobURLStore.cpp +++ b/Libraries/LibWeb/FileAPI/BlobURLStore.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -20,8 +21,8 @@ namespace Web::FileAPI { BlobURLStore& blob_url_store() { - static GC::ConservativeHashMap store; - return store; + static NeverDestroyed> store; + return *store; } // https://w3c.github.io/FileAPI/#unicodeBlobURL diff --git a/Libraries/LibWeb/Gamepad/EventNames.cpp b/Libraries/LibWeb/Gamepad/EventNames.cpp index 9b97b2c947..e039da2d32 100644 --- a/Libraries/LibWeb/Gamepad/EventNames.cpp +++ b/Libraries/LibWeb/Gamepad/EventNames.cpp @@ -9,7 +9,7 @@ namespace Web::Gamepad::EventNames { #define __ENUMERATE_GAMEPAD_EVENT(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_GAMEPAD_EVENTS #undef __ENUMERATE_GAMEPAD_EVENT diff --git a/Libraries/LibWeb/Gamepad/EventNames.h b/Libraries/LibWeb/Gamepad/EventNames.h index 9379d8e853..5b2f5e1f58 100644 --- a/Libraries/LibWeb/Gamepad/EventNames.h +++ b/Libraries/LibWeb/Gamepad/EventNames.h @@ -14,7 +14,7 @@ namespace Web::Gamepad::EventNames { __ENUMERATE_GAMEPAD_EVENT(gamepadconnected) \ __ENUMERATE_GAMEPAD_EVENT(gamepaddisconnected) -#define __ENUMERATE_GAMEPAD_EVENT(name) extern FlyString name; +#define __ENUMERATE_GAMEPAD_EVENT(name) extern FlyString const& name; ENUMERATE_GAMEPAD_EVENTS #undef __ENUMERATE_GAMEPAD_EVENT diff --git a/Libraries/LibWeb/HTML/AnimatedDecodedImageData.cpp b/Libraries/LibWeb/HTML/AnimatedDecodedImageData.cpp index 067c880e63..dd8296f37c 100644 --- a/Libraries/LibWeb/HTML/AnimatedDecodedImageData.cpp +++ b/Libraries/LibWeb/HTML/AnimatedDecodedImageData.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -19,8 +20,8 @@ GC_DEFINE_ALLOCATOR(AnimatedDecodedImageData); HashMap>& AnimatedDecodedImageData::session_registry() { - static HashMap> s_registry; - return s_registry; + static NeverDestroyed>> registry; + return *registry; } void AnimatedDecodedImageData::install_frame_delivery_callback() diff --git a/Libraries/LibWeb/HTML/AttributeNames.cpp b/Libraries/LibWeb/HTML/AttributeNames.cpp index e8abb863ee..14f9442705 100644 --- a/Libraries/LibWeb/HTML/AttributeNames.cpp +++ b/Libraries/LibWeb/HTML/AttributeNames.cpp @@ -10,7 +10,7 @@ namespace Web::HTML { namespace AttributeNames { #define __ENUMERATE_HTML_ATTRIBUTE(name, attribute) \ - FlyString name = attribute##_fly_string; + FlyString const& name = *new FlyString(attribute##_fly_string); ENUMERATE_HTML_ATTRIBUTES #undef __ENUMERATE_HTML_ATTRIBUTE diff --git a/Libraries/LibWeb/HTML/AttributeNames.h b/Libraries/LibWeb/HTML/AttributeNames.h index ad8b252aa8..d4dedb9d1d 100644 --- a/Libraries/LibWeb/HTML/AttributeNames.h +++ b/Libraries/LibWeb/HTML/AttributeNames.h @@ -331,7 +331,7 @@ namespace AttributeNames { __ENUMERATE_HTML_ATTRIBUTE(wrap, "wrap") \ __ENUMERATE_HTML_ATTRIBUTE(writingsuggestions, "writingsuggestions") -#define __ENUMERATE_HTML_ATTRIBUTE(name, attribute) extern WEB_API FlyString name; +#define __ENUMERATE_HTML_ATTRIBUTE(name, attribute) extern WEB_API FlyString const& name; ENUMERATE_HTML_ATTRIBUTES #undef __ENUMERATE_HTML_ATTRIBUTE diff --git a/Libraries/LibWeb/HTML/BroadcastChannel.cpp b/Libraries/LibWeb/HTML/BroadcastChannel.cpp index 826222f21c..256c984252 100644 --- a/Libraries/LibWeb/HTML/BroadcastChannel.cpp +++ b/Libraries/LibWeb/HTML/BroadcastChannel.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -61,23 +62,27 @@ void BroadcastChannelRepository::unregister_channel(GC::Ref ch auto const& BroadcastChannelRepository::registered_channels_for_key(StorageAPI::StorageKey key) const { - static Vector> s_empty_channels; + static NeverDestroyed>> empty_channels; auto maybe_channels = m_channels.get(key); if (!maybe_channels.has_value()) - return s_empty_channels; + return *empty_channels; return maybe_channels.value(); } -static BroadcastChannelRepository s_broadcast_channel_repository; +static BroadcastChannelRepository& broadcast_channel_repository() +{ + static NeverDestroyed repository; + return *repository; +} GC_DEFINE_ALLOCATOR(BroadcastChannel); GC::Ref BroadcastChannel::construct_impl(JS::Realm& realm, FlyString const& name) { auto channel = realm.create(realm, name); - s_broadcast_channel_repository.register_channel(channel); + broadcast_channel_repository().register_channel(channel); return channel; } @@ -96,7 +101,7 @@ void BroadcastChannel::initialize(JS::Realm& realm) void BroadcastChannel::finalize() { Base::finalize(); - s_broadcast_channel_repository.unregister_channel(*this); + broadcast_channel_repository().unregister_channel(*this); } // https://html.spec.whatwg.org/multipage/web-messaging.html#eligible-for-messaging @@ -166,7 +171,7 @@ void BroadcastChannel::deliver_message_locally(BroadcastChannelMessage const& me GC::RootVector> destinations; // * The result of running obtain a storage key for non-storage purposes with their relevant settings object equals sourceStorageKey. - auto same_origin_broadcast_channels = s_broadcast_channel_repository.registered_channels_for_key(message.storage_key); + auto same_origin_broadcast_channels = broadcast_channel_repository().registered_channels_for_key(message.storage_key); for (auto const& channel : same_origin_broadcast_channels) { // * They are eligible for messaging. if (!channel->is_eligible_for_messaging()) @@ -226,7 +231,7 @@ void BroadcastChannel::close() // The close() method steps are to set this's closed flag to true. m_closed_flag = true; - s_broadcast_channel_repository.unregister_channel(*this); + broadcast_channel_repository().unregister_channel(*this); } // https://html.spec.whatwg.org/multipage/web-messaging.html#handler-broadcastchannel-onmessage diff --git a/Libraries/LibWeb/HTML/BrowsingContextGroup.cpp b/Libraries/LibWeb/HTML/BrowsingContextGroup.cpp index e2e9c8cfc5..cee35aa194 100644 --- a/Libraries/LibWeb/HTML/BrowsingContextGroup.cpp +++ b/Libraries/LibWeb/HTML/BrowsingContextGroup.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -16,8 +17,8 @@ GC_DEFINE_ALLOCATOR(BrowsingContextGroup); // https://html.spec.whatwg.org/multipage/browsers.html#browsing-context-group-set static HashTable>& user_agent_browsing_context_group_set() { - static HashTable> set; - return set; + static NeverDestroyed>> set; + return *set; } BrowsingContextGroup::BrowsingContextGroup(GC::Ref page) diff --git a/Libraries/LibWeb/HTML/CrossOrigin/AbstractOperations.cpp b/Libraries/LibWeb/HTML/CrossOrigin/AbstractOperations.cpp index a54c4f2972..a9e51d20c9 100644 --- a/Libraries/LibWeb/HTML/CrossOrigin/AbstractOperations.cpp +++ b/Libraries/LibWeb/HTML/CrossOrigin/AbstractOperations.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -313,10 +314,9 @@ Vector cross_origin_properties(Variant property_names { - "window"_fly_string, "self"_fly_string, "location"_fly_string, "close"_fly_string, "closed"_fly_string, "focus"_fly_string, "blur"_fly_string, "frames"_fly_string, "length"_fly_string, "top"_fly_string, "opener"_fly_string, "parent"_fly_string, "postMessage"_fly_string - }; - return (property_key.is_string() && any_of(property_names, [&](auto const& name) { return property_key.as_string() == name; })) || property_key.is_number(); + static NeverDestroyed> property_names { Array { + "window"_fly_string, "self"_fly_string, "location"_fly_string, "close"_fly_string, "closed"_fly_string, "focus"_fly_string, "blur"_fly_string, "frames"_fly_string, "length"_fly_string, "top"_fly_string, "opener"_fly_string, "parent"_fly_string, "postMessage"_fly_string } }; + return (property_key.is_string() && any_of(*property_names, [&](auto const& name) { return property_key.as_string() == name; })) || property_key.is_number(); } // 7.2.3.2 CrossOriginPropertyFallback ( P ), https://html.spec.whatwg.org/multipage/browsers.html#crossoriginpropertyfallback-(-p-) diff --git a/Libraries/LibWeb/HTML/CustomElements/CustomElementReactionNames.cpp b/Libraries/LibWeb/HTML/CustomElements/CustomElementReactionNames.cpp index c2d1c000c8..bcbfcb8967 100644 --- a/Libraries/LibWeb/HTML/CustomElements/CustomElementReactionNames.cpp +++ b/Libraries/LibWeb/HTML/CustomElements/CustomElementReactionNames.cpp @@ -9,7 +9,7 @@ namespace Web::HTML::CustomElementReactionNames { #define __ENUMERATE_CUSTOM_ELEMENT_REACTION_NAME(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_CUSTOM_ELEMENT_REACTION_NAMES #undef __ENUMERATE_CUSTOM_ELEMENT_REACTION_NAME diff --git a/Libraries/LibWeb/HTML/CustomElements/CustomElementReactionNames.h b/Libraries/LibWeb/HTML/CustomElements/CustomElementReactionNames.h index ef64b0c1c8..c1986ebfb5 100644 --- a/Libraries/LibWeb/HTML/CustomElements/CustomElementReactionNames.h +++ b/Libraries/LibWeb/HTML/CustomElements/CustomElementReactionNames.h @@ -22,7 +22,7 @@ namespace Web::HTML::CustomElementReactionNames { __ENUMERATE_CUSTOM_ELEMENT_REACTION_NAME(formResetCallback) \ __ENUMERATE_CUSTOM_ELEMENT_REACTION_NAME(formStateRestoreCallback) -#define __ENUMERATE_CUSTOM_ELEMENT_REACTION_NAME(name) extern FlyString name; +#define __ENUMERATE_CUSTOM_ELEMENT_REACTION_NAME(name) extern FlyString const& name; ENUMERATE_CUSTOM_ELEMENT_REACTION_NAMES #undef __ENUMERATE_CUSTOM_ELEMENT_REACTION_NAME diff --git a/Libraries/LibWeb/HTML/DataTransfer.cpp b/Libraries/LibWeb/HTML/DataTransfer.cpp index ac0e74d592..9c8e45f4f7 100644 --- a/Libraries/LibWeb/HTML/DataTransfer.cpp +++ b/Libraries/LibWeb/HTML/DataTransfer.cpp @@ -23,7 +23,7 @@ GC_DEFINE_ALLOCATOR(DataTransfer); namespace DataTransferEffect { -#define __ENUMERATE_DATA_TRANSFER_EFFECT(name) FlyString name = #name##_fly_string; +#define __ENUMERATE_DATA_TRANSFER_EFFECT(name) FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_DATA_TRANSFER_EFFECTS #undef __ENUMERATE_DATA_TRANSFER_EFFECT diff --git a/Libraries/LibWeb/HTML/DataTransfer.h b/Libraries/LibWeb/HTML/DataTransfer.h index e00947d09c..d869be187a 100644 --- a/Libraries/LibWeb/HTML/DataTransfer.h +++ b/Libraries/LibWeb/HTML/DataTransfer.h @@ -26,7 +26,7 @@ namespace Web::HTML { namespace DataTransferEffect { -#define __ENUMERATE_DATA_TRANSFER_EFFECT(name) extern FlyString name; +#define __ENUMERATE_DATA_TRANSFER_EFFECT(name) extern FlyString const& name; ENUMERATE_DATA_TRANSFER_EFFECTS #undef __ENUMERATE_DATA_TRANSFER_EFFECT diff --git a/Libraries/LibWeb/HTML/EventLoop/Task.cpp b/Libraries/LibWeb/HTML/EventLoop/Task.cpp index ca6fde37c0..68fdf39b50 100644 --- a/Libraries/LibWeb/HTML/EventLoop/Task.cpp +++ b/Libraries/LibWeb/HTML/EventLoop/Task.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -12,7 +13,11 @@ namespace Web::HTML { GC_DEFINE_ALLOCATOR(Task); -static IDAllocator s_unique_task_source_allocator { static_cast(Task::Source::UniqueTaskSourceStart) }; +static IDAllocator& unique_task_source_allocator() +{ + static NeverDestroyed allocator { static_cast(Task::Source::UniqueTaskSourceStart) }; + return *allocator; +} [[nodiscard]] static TaskID allocate_task_id() { @@ -65,13 +70,13 @@ DOM::Document const* Task::document() const } UniqueTaskSource::UniqueTaskSource() - : source(static_cast(s_unique_task_source_allocator.allocate())) + : source(static_cast(unique_task_source_allocator().allocate())) { } UniqueTaskSource::~UniqueTaskSource() { - s_unique_task_source_allocator.deallocate(static_cast(source)); + unique_task_source_allocator().deallocate(static_cast(source)); } NonnullRefPtr ParallelQueue::create() diff --git a/Libraries/LibWeb/HTML/EventNames.cpp b/Libraries/LibWeb/HTML/EventNames.cpp index cf7da538cb..7834495263 100644 --- a/Libraries/LibWeb/HTML/EventNames.cpp +++ b/Libraries/LibWeb/HTML/EventNames.cpp @@ -9,7 +9,7 @@ namespace Web::HTML::EventNames { #define __ENUMERATE_HTML_EVENT(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_HTML_EVENTS #undef __ENUMERATE_HTML_EVENT diff --git a/Libraries/LibWeb/HTML/EventNames.h b/Libraries/LibWeb/HTML/EventNames.h index 6c395e3a34..c3d59c5f31 100644 --- a/Libraries/LibWeb/HTML/EventNames.h +++ b/Libraries/LibWeb/HTML/EventNames.h @@ -154,7 +154,7 @@ namespace Web::HTML::EventNames { __ENUMERATE_HTML_EVENT(webkitAnimationStart) \ __ENUMERATE_HTML_EVENT(webkitTransitionEnd) -#define __ENUMERATE_HTML_EVENT(name) extern WEB_API FlyString name; +#define __ENUMERATE_HTML_EVENT(name) extern WEB_API FlyString const& name; ENUMERATE_HTML_EVENTS #undef __ENUMERATE_HTML_EVENT diff --git a/Libraries/LibWeb/HTML/HTMLFieldSetElement.h b/Libraries/LibWeb/HTML/HTMLFieldSetElement.h index 0e7c095205..da0b501790 100644 --- a/Libraries/LibWeb/HTML/HTMLFieldSetElement.h +++ b/Libraries/LibWeb/HTML/HTMLFieldSetElement.h @@ -22,7 +22,7 @@ public: String const& type() const { - static String const fieldset = "fieldset"_string; + static String const& fieldset = *new String("fieldset"_string); return fieldset; } diff --git a/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Libraries/LibWeb/HTML/HTMLImageElement.cpp index a795510619..14afe0d2ed 100644 --- a/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -83,8 +84,8 @@ private: static BatchingDispatcher& batching_dispatcher() { - static BatchingDispatcher dispatcher; - return dispatcher; + static NeverDestroyed dispatcher; + return *dispatcher; } static bool image_element_dimensions_may_depend_on_intrinsic_size(Layout::ImageBox const& image_box) diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 78bcbee39a..517979f2de 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -13,6 +13,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -807,7 +808,7 @@ void HTMLInputElement::commit_pending_changes() // https://www.w3.org/TR/css-ui-4/#input-rules static GC::Ref inner_text_style_when_visible() { - static GC::Root style; + static auto& style = *new GC::Root; if (!style) { style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); style->set_declarations_from_text(R"~~~( @@ -825,7 +826,7 @@ static GC::Ref inner_text_style_when_visible() static GC::Ref inner_text_style_when_hidden() { - static GC::Root style; + static auto& style = *new GC::Root; if (!style) { style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); style->set_declarations_from_text(R"~~~( @@ -838,7 +839,7 @@ static GC::Ref inner_text_style_when_hidden() static GC::Ref stepper_button_style_when_visible() { - static GC::Root style; + static auto& style = *new GC::Root; if (!style) { style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); style->set_declarations_from_text(R"~~~( @@ -851,7 +852,7 @@ static GC::Ref stepper_button_style_when_visible() static GC::Ref stepper_button_style_when_hidden() { - static GC::Root style; + static auto& style = *new GC::Root; if (!style) { style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); style->set_declarations_from_text(R"~~~( @@ -863,7 +864,7 @@ static GC::Ref stepper_button_style_when_hidden() static GC::Ref placeholder_style_when_visible() { - static GC::Root style; + static auto& style = *new GC::Root; if (!style) { style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); style->set_declarations_from_text(R"~~~( @@ -881,7 +882,7 @@ static GC::Ref placeholder_style_when_visible() static GC::Ref placeholder_style_when_hidden() { - static GC::Root style; + static auto& style = *new GC::Root; if (!style) { style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); style->set_declarations_from_text("display: none;"sv); @@ -1130,7 +1131,7 @@ void HTMLInputElement::create_text_input_shadow_tree() auto element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML)); { - static GC::Root style; + static auto& style = *new GC::Root; if (!style) { style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); style->set_declarations_from_text(R"~~~( @@ -1149,7 +1150,7 @@ void HTMLInputElement::create_text_input_shadow_tree() // https://www.w3.org/TR/css-ui-4/#input-rules m_inner_text_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML)); { - static GC::Root style; + static auto& style = *new GC::Root; if (!style) { style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); style->set_declarations_from_text(R"~~~( @@ -3603,10 +3604,10 @@ bool HTMLInputElement::suffering_from_being_missing() const // https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address static regex::ECMAScriptRegex& valid_email_address_regex() { - static auto regex = MUST(regex::ECMAScriptRegex::compile( + static NeverDestroyed regex { MUST(regex::ECMAScriptRegex::compile( "^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"sv, - regex::ECMAScriptCompileFlags {})); - return regex; + regex::ECMAScriptCompileFlags {})) }; + return *regex; } // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-a-type-mismatch diff --git a/Libraries/LibWeb/HTML/HTMLSelectElement.cpp b/Libraries/LibWeb/HTML/HTMLSelectElement.cpp index 15a16e054b..2176f72637 100644 --- a/Libraries/LibWeb/HTML/HTMLSelectElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLSelectElement.cpp @@ -419,8 +419,8 @@ void HTMLSelectElement::children_changed(ChildrenChangedMetadata const& metadata String const& HTMLSelectElement::type() const { // The type IDL attribute, on getting, must return the string "select-one" if the multiple attribute is absent, and the string "select-multiple" if the multiple attribute is present. - static String const select_one = "select-one"_string; - static String const select_multiple = "select-multiple"_string; + static String const& select_one = *new String("select-one"_string); + static String const& select_multiple = *new String("select-multiple"_string); if (!has_attribute(AttributeNames::multiple)) return select_one; diff --git a/Libraries/LibWeb/HTML/HTMLTextAreaElement.h b/Libraries/LibWeb/HTML/HTMLTextAreaElement.h index 5698baf9f3..f5559ece73 100644 --- a/Libraries/LibWeb/HTML/HTMLTextAreaElement.h +++ b/Libraries/LibWeb/HTML/HTMLTextAreaElement.h @@ -9,6 +9,7 @@ #pragma once +#include #include #include #include @@ -35,8 +36,8 @@ public: String const& type() const { - static String const textarea = "textarea"_string; - return textarea; + static NeverDestroyed textarea { "textarea"_string }; + return *textarea; } // ^EventTarget diff --git a/Libraries/LibWeb/HTML/MediaControls.cpp b/Libraries/LibWeb/HTML/MediaControls.cpp index 864a754eca..6f8f1a52d1 100644 --- a/Libraries/LibWeb/HTML/MediaControls.cpp +++ b/Libraries/LibWeb/HTML/MediaControls.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -61,12 +62,12 @@ void MediaControls::create_shadow_tree() m_dom = MediaControlsDOM(document, *shadow_root, is_video ? MediaControlsDOM::Options::Video : MediaControlsDOM::Options::None); - static Vector s_video_class = { "video"_string }; - static Vector s_audio_class = { "audio"_string }; + static NeverDestroyed> video_class { Vector { "video"_string } }; + static NeverDestroyed> audio_class { Vector { "audio"_string } }; if (is_video) - MUST(m_dom->container->class_list()->add(s_video_class)); + MUST(m_dom->container->class_list()->add(*video_class)); else - MUST(m_dom->container->class_list()->add(s_audio_class)); + MUST(m_dom->container->class_list()->add(*audio_class)); // Initialize state update_play_pause_icon(); @@ -522,8 +523,8 @@ void MediaControls::update_timeline() while (m_buffered_ranges.size() < range_count) { auto range = MUST(DOM::create_element(m_media_element->document(), HTML::TagNames::div, Namespace::HTML)); - static auto s_timeline_buffered_class = "timeline-buffered"_string; - MUST(range->class_list()->toggle(s_timeline_buffered_class, true)); + static String const& timeline_buffered_class = *new String("timeline-buffered"_string); + MUST(range->class_list()->toggle(timeline_buffered_class, true)); MUST(range->style_for_bindings()->set_property(CSS::PropertyID::Display, "block"sv)); m_dom->timeline_track->insert_before(range, nullptr); m_buffered_ranges.empend(*range); @@ -595,18 +596,18 @@ void MediaControls::update_volume_and_mute_indicator() return MuteIconState::Empty; }(); - static constexpr auto icon_class = [](MuteIconState state) { - static Vector s_no_volume_class = {}; - static Vector s_low_volume_class = { "low"_string }; - static Vector s_high_volume_class = { "high"_string }; + static auto icon_class = [](MuteIconState state) -> Vector const& { + static NeverDestroyed> no_volume_class; + static NeverDestroyed> low_volume_class { Vector { "low"_string } }; + static NeverDestroyed> high_volume_class { Vector { "high"_string } }; switch (state) { case MuteIconState::Empty: - return s_no_volume_class; + return *no_volume_class; case MuteIconState::Low: - return s_low_volume_class; + return *low_volume_class; case MuteIconState::High: - return s_high_volume_class; + return *high_volume_class; } VERIFY_NOT_REACHED(); }; @@ -633,12 +634,12 @@ void MediaControls::update_fullscreen_icon() if (!m_dom->fullscreen_icon) return; - static auto s_fullscreen_class = "fullscreen"_string; + static String const& fullscreen_class = *new String("fullscreen"_string); VERIFY(m_media_element); auto is_fullscreen_element = m_media_element->document().fullscreen_element() == m_media_element; - MUST(m_dom->fullscreen_icon->class_list()->toggle(s_fullscreen_class, is_fullscreen_element)); + MUST(m_dom->fullscreen_icon->class_list()->toggle(fullscreen_class, is_fullscreen_element)); } void MediaControls::update_placeholder_visibility() @@ -661,13 +662,17 @@ bool MediaControls::should_show_placeholder() const return video_element.current_representation() != HTMLVideoElement::Representation::VideoFrame; } -static Vector s_visible_class = { "visible"_string }; +static Vector const& visible_class() +{ + static NeverDestroyed> visible_class { Vector { "visible"_string } }; + return *visible_class; +} void MediaControls::show_controls() { VERIFY(m_dom->control_bar); - MUST(m_dom->control_bar->class_list()->add(s_visible_class)); + MUST(m_dom->control_bar->class_list()->add(visible_class())); if (!m_hover_timer) { constexpr int hover_timeout_ms = 1000; @@ -689,7 +694,7 @@ void MediaControls::hide_controls() if (m_dom->placeholder_circle && should_show_placeholder()) return; - MUST(m_dom->control_bar->class_list()->remove(s_visible_class)); + MUST(m_dom->control_bar->class_list()->remove(visible_class())); m_hover_timer.clear(); } diff --git a/Libraries/LibWeb/HTML/MessagePort.cpp b/Libraries/LibWeb/HTML/MessagePort.cpp index b14f6cc86e..19ef5e2649 100644 --- a/Libraries/LibWeb/HTML/MessagePort.cpp +++ b/Libraries/LibWeb/HTML/MessagePort.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -34,8 +35,8 @@ GC_DEFINE_ALLOCATOR(MessagePort); static GC::WeakHashSet& all_message_ports() { - static GC::WeakHashSet ports; - return ports; + static NeverDestroyed> ports; + return *ports; } GC::Ref MessagePort::create(JS::Realm& realm) diff --git a/Libraries/LibWeb/HTML/MimeType.cpp b/Libraries/LibWeb/HTML/MimeType.cpp index 2d7fa8a87d..3b54c1e5ea 100644 --- a/Libraries/LibWeb/HTML/MimeType.cpp +++ b/Libraries/LibWeb/HTML/MimeType.cpp @@ -39,7 +39,7 @@ String const& MimeType::type() const String MimeType::description() const { // The MimeType interface's description getter steps are to return "Portable Document Format". - static String description_string = "Portable Document Format"_string; + static String const& description_string = *new String("Portable Document Format"_string); return description_string; } @@ -47,7 +47,7 @@ String MimeType::description() const String const& MimeType::suffixes() const { // The MimeType interface's suffixes getter steps are to return "pdf". - static String suffixes_string = "pdf"_string; + static String const& suffixes_string = *new String("pdf"_string); return suffixes_string; } diff --git a/Libraries/LibWeb/HTML/MimeTypeArray.cpp b/Libraries/LibWeb/HTML/MimeTypeArray.cpp index 29dbd0a37a..d998103462 100644 --- a/Libraries/LibWeb/HTML/MimeTypeArray.cpp +++ b/Libraries/LibWeb/HTML/MimeTypeArray.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -42,12 +43,12 @@ Vector MimeTypeArray::supported_property_names() const return {}; // https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-mime-types - static Vector const mime_types = { + static NeverDestroyed> mime_types { Vector { "application/pdf"_fly_string, "text/pdf"_fly_string, - }; + } }; - return mime_types; + return *mime_types; } // https://html.spec.whatwg.org/multipage/system-state.html#dom-mimetypearray-length diff --git a/Libraries/LibWeb/HTML/Navigable.cpp b/Libraries/LibWeb/HTML/Navigable.cpp index 11d6f2e30a..7f8cd0b1fb 100644 --- a/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Libraries/LibWeb/HTML/Navigable.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -248,8 +249,8 @@ void PopulateSessionHistoryEntryDocumentOutput::visit_edges(Cell::Visitor& visit HashTable>& all_navigables() { - static HashTable> set; - return set; + static NeverDestroyed>> set; + return *set; } // https://html.spec.whatwg.org/multipage/document-sequences.html#child-navigable diff --git a/Libraries/LibWeb/HTML/NavigableContainer.cpp b/Libraries/LibWeb/HTML/NavigableContainer.cpp index 63474ff44d..aeca63390d 100644 --- a/Libraries/LibWeb/HTML/NavigableContainer.cpp +++ b/Libraries/LibWeb/HTML/NavigableContainer.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -28,8 +29,8 @@ namespace Web::HTML { HashTable& NavigableContainer::all_instances() { - static HashTable set; - return set; + static NeverDestroyed> set; + return *set; } NavigableContainer::NavigableContainer(DOM::Document& document, DOM::QualifiedName qualified_name) diff --git a/Libraries/LibWeb/HTML/Parser/HTMLTokenizer.cpp b/Libraries/LibWeb/HTML/Parser/HTMLTokenizer.cpp index fba54b0f83..967181985b 100644 --- a/Libraries/LibWeb/HTML/Parser/HTMLTokenizer.cpp +++ b/Libraries/LibWeb/HTML/Parser/HTMLTokenizer.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -72,22 +73,22 @@ static Vector build_interned_name_table(size_t count, void (*fetch)(u static FlyString const& interned_rust_tag_name(uint16_t id) { - static Vector const s_table = build_interned_name_table( + static NeverDestroyed> table { build_interned_name_table( rust_html_tokenizer_interned_tag_name_count(), - rust_html_tokenizer_interned_tag_name); - if (id == 0 || id >= s_table.size()) - return s_table[0]; - return s_table[id]; + rust_html_tokenizer_interned_tag_name) }; + if (id == 0 || id >= table->size()) + return (*table)[0]; + return (*table)[id]; } static FlyString const& interned_rust_attr_name(uint16_t id) { - static Vector const s_table = build_interned_name_table( + static NeverDestroyed> table { build_interned_name_table( rust_html_tokenizer_interned_attr_name_count(), - rust_html_tokenizer_interned_attr_name); - if (id == 0 || id >= s_table.size()) - return s_table[0]; - return s_table[id]; + rust_html_tokenizer_interned_attr_name) }; + if (id == 0 || id >= table->size()) + return (*table)[0]; + return (*table)[id]; } HTMLTokenizer::HTMLTokenizer() diff --git a/Libraries/LibWeb/HTML/Plugin.cpp b/Libraries/LibWeb/HTML/Plugin.cpp index c92a6decf3..fb33ea2668 100644 --- a/Libraries/LibWeb/HTML/Plugin.cpp +++ b/Libraries/LibWeb/HTML/Plugin.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -45,7 +46,7 @@ String const& Plugin::name() const String Plugin::description() const { // The Plugin interface's description getter steps are to return "Portable Document Format". - static String description_string = "Portable Document Format"_string; + static String const& description_string = *new String("Portable Document Format"_string); return description_string; } @@ -53,7 +54,7 @@ String Plugin::description() const String Plugin::filename() const { // The Plugin interface's filename getter steps are to return "internal-pdf-viewer". - static String filename_string = "internal-pdf-viewer"_string; + static String const& filename_string = *new String("internal-pdf-viewer"_string); return filename_string; } @@ -66,12 +67,12 @@ Vector Plugin::supported_property_names() const return {}; // https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-mime-types - static Vector const mime_types = { + static NeverDestroyed> mime_types { Vector { "application/pdf"_fly_string, "text/pdf"_fly_string, - }; + } }; - return mime_types; + return *mime_types; } // https://html.spec.whatwg.org/multipage/system-state.html#dom-plugin-length diff --git a/Libraries/LibWeb/HTML/PluginArray.cpp b/Libraries/LibWeb/HTML/PluginArray.cpp index 0314345a43..362687cddc 100644 --- a/Libraries/LibWeb/HTML/PluginArray.cpp +++ b/Libraries/LibWeb/HTML/PluginArray.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -48,15 +49,15 @@ Vector PluginArray::supported_property_names() const return {}; // https://html.spec.whatwg.org/multipage/system-state.html#pdf-viewer-plugin-names - static Vector const plugin_names = { + static NeverDestroyed> plugin_names { Vector { "PDF Viewer"_fly_string, "Chrome PDF Viewer"_fly_string, "Chromium PDF Viewer"_fly_string, "Microsoft Edge PDF Viewer"_fly_string, "WebKit built-in PDF"_fly_string, - }; + } }; - return plugin_names; + return *plugin_names; } // https://html.spec.whatwg.org/multipage/system-state.html#dom-pluginarray-length diff --git a/Libraries/LibWeb/HTML/SharedWorkerGlobalScope.cpp b/Libraries/LibWeb/HTML/SharedWorkerGlobalScope.cpp index afd728ab4a..c93b719d63 100644 --- a/Libraries/LibWeb/HTML/SharedWorkerGlobalScope.cpp +++ b/Libraries/LibWeb/HTML/SharedWorkerGlobalScope.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -14,8 +15,8 @@ GC_DEFINE_ALLOCATOR(SharedWorkerGlobalScope); HashTable>& all_shared_worker_global_scopes() { - static HashTable> set; - return set; + static NeverDestroyed>> set; + return *set; } SharedWorkerGlobalScope::SharedWorkerGlobalScope(JS::Realm& realm, GC::Ref page) diff --git a/Libraries/LibWeb/HTML/SyntaxHighlighter/SyntaxHighlighter.cpp b/Libraries/LibWeb/HTML/SyntaxHighlighter/SyntaxHighlighter.cpp index 9e066d06b7..e48c4775a1 100644 --- a/Libraries/LibWeb/HTML/SyntaxHighlighter/SyntaxHighlighter.cpp +++ b/Libraries/LibWeb/HTML/SyntaxHighlighter/SyntaxHighlighter.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -191,11 +192,11 @@ void SyntaxHighlighter::rehighlight(Palette const& palette) Vector SyntaxHighlighter::matching_token_pairs_impl() const { - static Vector pairs; - if (pairs.is_empty()) { - pairs.append({ static_cast(AugmentedTokenKind::OpenTag), static_cast(AugmentedTokenKind::CloseTag) }); + static NeverDestroyed> pairs; + if (pairs->is_empty()) { + pairs->append({ static_cast(AugmentedTokenKind::OpenTag), static_cast(AugmentedTokenKind::CloseTag) }); } - return pairs; + return *pairs; } bool SyntaxHighlighter::token_types_equal(u64 token0, u64 token1) const diff --git a/Libraries/LibWeb/HTML/TagNames.cpp b/Libraries/LibWeb/HTML/TagNames.cpp index e95c29ea46..4e33da4854 100644 --- a/Libraries/LibWeb/HTML/TagNames.cpp +++ b/Libraries/LibWeb/HTML/TagNames.cpp @@ -9,7 +9,7 @@ namespace Web::HTML::TagNames { #define __ENUMERATE_HTML_TAG(name, tag) \ - FlyString name = tag##_fly_string; + FlyString const& name = *new FlyString(tag##_fly_string); ENUMERATE_HTML_TAGS #undef __ENUMERATE_HTML_TAG diff --git a/Libraries/LibWeb/HTML/TagNames.h b/Libraries/LibWeb/HTML/TagNames.h index 7e622ba281..618e733088 100644 --- a/Libraries/LibWeb/HTML/TagNames.h +++ b/Libraries/LibWeb/HTML/TagNames.h @@ -159,7 +159,7 @@ namespace Web::HTML::TagNames { __ENUMERATE_HTML_TAG(wbr, "wbr") \ __ENUMERATE_HTML_TAG(xmp, "xmp") -#define __ENUMERATE_HTML_TAG(name, tag) extern WEB_API FlyString name; +#define __ENUMERATE_HTML_TAG(name, tag) extern WEB_API FlyString const& name; ENUMERATE_HTML_TAGS #undef __ENUMERATE_HTML_TAG diff --git a/Libraries/LibWeb/HTML/TraversableNavigable.cpp b/Libraries/LibWeb/HTML/TraversableNavigable.cpp index 41ee39b607..dab33d17f6 100644 --- a/Libraries/LibWeb/HTML/TraversableNavigable.cpp +++ b/Libraries/LibWeb/HTML/TraversableNavigable.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -59,8 +60,8 @@ void TraversableNavigable::visit_edges(Cell::Visitor& visitor) static OrderedHashTable& user_agent_top_level_traversable_set() { - static OrderedHashTable set; - return set; + static NeverDestroyed> set; + return *set; } // https://html.spec.whatwg.org/multipage/document-sequences.html#creating-a-new-top-level-browsing-context diff --git a/Libraries/LibWeb/HTML/Window.cpp b/Libraries/LibWeb/HTML/Window.cpp index a8c1987f79..16bf7965c4 100644 --- a/Libraries/LibWeb/HTML/Window.cpp +++ b/Libraries/LibWeb/HTML/Window.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -87,8 +88,8 @@ GC_DEFINE_ALLOCATOR(Window); static GC::WeakHashSet& all_windows() { - static GC::WeakHashSet windows; - return windows; + static NeverDestroyed> windows; + return *windows; } void Window::for_each_active(Function callback) diff --git a/Libraries/LibWeb/HTML/WorkerAgentParent.cpp b/Libraries/LibWeb/HTML/WorkerAgentParent.cpp index 60c6a8e0e5..8fb288cde8 100644 --- a/Libraries/LibWeb/HTML/WorkerAgentParent.cpp +++ b/Libraries/LibWeb/HTML/WorkerAgentParent.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -27,8 +28,8 @@ GC_DEFINE_ALLOCATOR(WorkerAgentParent); static HashMap>& worker_agent_parents() { - static HashMap> map; - return map; + static NeverDestroyed>> map; + return *map; } WorkerAgentParent::WorkerAgentParent(URL::URL url, Bindings::WorkerOptions const& options, GC::Ptr outside_port, GC::Ref outside_settings, GC::Ref worker_event_target, Bindings::AgentType agent_type) diff --git a/Libraries/LibWeb/IndexedDB/Internal/ConnectionQueueHandler.h b/Libraries/LibWeb/IndexedDB/Internal/ConnectionQueueHandler.h index 24f728f9cb..2e915c0100 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/ConnectionQueueHandler.h +++ b/Libraries/LibWeb/IndexedDB/Internal/ConnectionQueueHandler.h @@ -20,8 +20,8 @@ public: static RequestList& for_key_and_name(StorageAPI::StorageKey const& key, String const& name); static ConnectionQueueHandler& the() { - static ConnectionQueueHandler s_instance; - return s_instance; + static ConnectionQueueHandler& instance = *new ConnectionQueueHandler; + return instance; } private: diff --git a/Libraries/LibWeb/IndexedDB/Internal/Database.cpp b/Libraries/LibWeb/IndexedDB/Internal/Database.cpp index ddea853921..4a73266990 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Database.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Database.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -14,11 +15,15 @@ namespace Web::IndexedDB { using IDBDatabaseMapping = HashMap>>; -static IDBDatabaseMapping m_databases; +static IDBDatabaseMapping& idb_databases() +{ + static NeverDestroyed databases; + return *databases; +} void Database::for_each_database(AK::Function const& visitor) { - for (auto const& [key, mapping] : m_databases) { + for (auto const& [key, mapping] : idb_databases()) { for (auto const& [_, database] : mapping) { if (!database) continue; @@ -59,7 +64,7 @@ GC::Ptr Database::object_store_with_name(String const& name) const Vector> Database::for_key(StorageAPI::StorageKey const& key) { Vector> databases; - for (auto const& database_mapping : m_databases.get(key).value_or({})) { + for (auto const& database_mapping : idb_databases().get(key).value_or({})) { databases.append(*database_mapping.value); } @@ -83,7 +88,7 @@ RequestList& ConnectionQueueHandler::for_key_and_name(StorageAPI::StorageKey con Optional Database::for_key_and_name(StorageAPI::StorageKey const& key, String const& name) { - auto database_mapping = m_databases.ensure(key, [] { return HashMap>(); }); + auto database_mapping = idb_databases().ensure(key, [] { return HashMap>(); }); if (auto maybe_database = database_mapping.get(name); maybe_database.has_value()) return *maybe_database.value(); return {}; @@ -91,14 +96,14 @@ Optional Database::for_key_and_name(StorageAPI::StorageKey const& key ErrorOr> Database::create_for_key_and_name(GC::Heap& heap, StorageAPI::StorageKey const& key, String const& name) { - auto database_mapping = TRY(m_databases.try_ensure(key, [] { + auto database_mapping = TRY(idb_databases().try_ensure(key, [] { return HashMap>(); })); auto value = Database::create(heap, name); database_mapping.set(name, value); - m_databases.set(key, database_mapping); + idb_databases().set(key, database_mapping); return value; } @@ -106,7 +111,7 @@ ErrorOr> Database::create_for_key_and_name(GC::Heap& heap, Sto ErrorOr Database::delete_for_key_and_name(StorageAPI::StorageKey const& key, String const& name) { // FIXME: Is a missing entry a failure? - auto maybe_database_mapping = m_databases.get(key); + auto maybe_database_mapping = idb_databases().get(key); if (!maybe_database_mapping.has_value()) return {}; @@ -119,7 +124,7 @@ ErrorOr Database::delete_for_key_and_name(StorageAPI::StorageKey const& ke if (!did_remove) return {}; - m_databases.set(key, database_mapping); + idb_databases().set(key, database_mapping); return {}; } diff --git a/Libraries/LibWeb/Layout/LayoutState.h b/Libraries/LibWeb/Layout/LayoutState.h index 02cf143a1c..3eea491eda 100644 --- a/Libraries/LibWeb/Layout/LayoutState.h +++ b/Libraries/LibWeb/Layout/LayoutState.h @@ -231,7 +231,7 @@ struct LayoutState { void add_floating_descendant(Box const& box) { ensure_rare_data().floating_descendants.set(&box); } HashTable> const& floating_descendants() const { - static HashTable> const empty; + static auto const& empty = *new HashTable>; return m_rare ? m_rare->floating_descendants : empty; } @@ -279,14 +279,14 @@ struct LayoutState { void set_grid_template_columns(RefPtr used_values_for_grid_template_columns) { ensure_rare_data().grid_template_columns = move(used_values_for_grid_template_columns); } RefPtr const& grid_template_columns() const { - static RefPtr const empty; + static auto const& empty = *new RefPtr; return m_rare ? m_rare->grid_template_columns : empty; } void set_grid_template_rows(RefPtr used_values_for_grid_template_rows) { ensure_rare_data().grid_template_rows = move(used_values_for_grid_template_rows); } RefPtr const& grid_template_rows() const { - static RefPtr const empty; + static auto const& empty = *new RefPtr; return m_rare ? m_rare->grid_template_rows : empty; } diff --git a/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Libraries/LibWeb/Layout/TableFormattingContext.cpp index 760f80e502..f1e0853ac0 100644 --- a/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -1348,7 +1349,7 @@ bool TableFormattingContext::border_is_less_specific(CSS::BorderData const& a, C { // Implements criteria for steps 1, 2 and 3 of border conflict resolution algorithm, as described in // https://www.w3.org/TR/CSS22/tables.html#border-conflict-resolution. - static HashMap const line_style_score = { + static NeverDestroyed> line_style_score { HashMap { { CSS::LineStyle::Inset, 0 }, { CSS::LineStyle::Groove, 1 }, { CSS::LineStyle::Outset, 2 }, @@ -1357,7 +1358,7 @@ bool TableFormattingContext::border_is_less_specific(CSS::BorderData const& a, C { CSS::LineStyle::Dashed, 5 }, { CSS::LineStyle::Solid, 6 }, { CSS::LineStyle::Double, 7 }, - }; + } }; // 1. Borders with the 'border-style' of 'hidden' take precedence over all other conflicting borders. Any border with this // value suppresses all borders at this location. @@ -1385,9 +1386,9 @@ bool TableFormattingContext::border_is_less_specific(CSS::BorderData const& a, C } else if (a.width < b.width) { return true; } - if (*line_style_score.get(a.line_style) > *line_style_score.get(b.line_style)) { + if (*line_style_score->get(a.line_style) > *line_style_score->get(b.line_style)) { return false; - } else if (*line_style_score.get(a.line_style) < *line_style_score.get(b.line_style)) { + } else if (*line_style_score->get(a.line_style) < *line_style_score->get(b.line_style)) { return true; } return false; diff --git a/Libraries/LibWeb/Loader/ContentBlocker.cpp b/Libraries/LibWeb/Loader/ContentBlocker.cpp index dccc0bbf3a..1b07adc2b0 100644 --- a/Libraries/LibWeb/Loader/ContentBlocker.cpp +++ b/Libraries/LibWeb/Loader/ContentBlocker.cpp @@ -15,7 +15,7 @@ namespace Web { ContentBlocker& ContentBlocker::the() { - static ContentBlocker blocker; + static ContentBlocker& blocker = *new ContentBlocker; return blocker; } diff --git a/Libraries/LibWeb/Loader/ProxyMappings.cpp b/Libraries/LibWeb/Loader/ProxyMappings.cpp index 30270a70be..099b63296b 100644 --- a/Libraries/LibWeb/Loader/ProxyMappings.cpp +++ b/Libraries/LibWeb/Loader/ProxyMappings.cpp @@ -9,7 +9,7 @@ Web::ProxyMappings& Web::ProxyMappings::the() { - static ProxyMappings instance {}; + static ProxyMappings& instance = *new ProxyMappings; return instance; } diff --git a/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Libraries/LibWeb/Loader/ResourceLoader.cpp index ffb3abb8cc..62b758bac0 100644 --- a/Libraries/LibWeb/Loader/ResourceLoader.cpp +++ b/Libraries/LibWeb/Loader/ResourceLoader.cpp @@ -32,25 +32,29 @@ namespace Web { -static RefPtr s_resource_loader; +static RefPtr& resource_loader() +{ + static RefPtr& resource_loader = *new RefPtr; + return resource_loader; +} void ResourceLoader::initialize(GC::Heap& heap, NonnullRefPtr request_client) { - s_resource_loader = adopt_ref(*new ResourceLoader(heap, move(request_client))); + resource_loader() = adopt_ref(*new ResourceLoader(heap, move(request_client))); } bool ResourceLoader::is_initialized() { - return s_resource_loader != nullptr; + return resource_loader() != nullptr; } ResourceLoader& ResourceLoader::the() { - if (!s_resource_loader) { + if (!resource_loader()) { dbgln("Web::ResourceLoader was not initialized"); VERIFY_NOT_REACHED(); } - return *s_resource_loader; + return *resource_loader(); } ResourceLoader::ResourceLoader(GC::Heap& heap, NonnullRefPtr request_client) diff --git a/Libraries/LibWeb/MathML/AttributeNames.cpp b/Libraries/LibWeb/MathML/AttributeNames.cpp index ffc0f20812..950a67d305 100644 --- a/Libraries/LibWeb/MathML/AttributeNames.cpp +++ b/Libraries/LibWeb/MathML/AttributeNames.cpp @@ -9,7 +9,7 @@ namespace Web::MathML::AttributeNames { #define __ENUMERATE_MATHML_ATTRIBUTE(name, attribute) \ - FlyString name = attribute##_fly_string; + FlyString const& name = *new FlyString(attribute##_fly_string); ENUMERATE_MATHML_ATTRIBUTES #undef __ENUMERATE_MATHML_ATTRIBUTE diff --git a/Libraries/LibWeb/MathML/AttributeNames.h b/Libraries/LibWeb/MathML/AttributeNames.h index 30f66c0a74..37e7c4daac 100644 --- a/Libraries/LibWeb/MathML/AttributeNames.h +++ b/Libraries/LibWeb/MathML/AttributeNames.h @@ -24,7 +24,7 @@ namespace Web::MathML::AttributeNames { __ENUMERATE_MATHML_ATTRIBUTE(scriptlevel, "scriptlevel") \ __ENUMERATE_MATHML_ATTRIBUTE(width, "width") -#define __ENUMERATE_MATHML_ATTRIBUTE(name, attribute) extern WEB_API FlyString name; +#define __ENUMERATE_MATHML_ATTRIBUTE(name, attribute) extern WEB_API FlyString const& name; ENUMERATE_MATHML_ATTRIBUTES #undef __ENUMERATE_MATHML_ATTRIBUTE diff --git a/Libraries/LibWeb/MathML/TagNames.cpp b/Libraries/LibWeb/MathML/TagNames.cpp index 0cff995ffb..e6ce1101c1 100644 --- a/Libraries/LibWeb/MathML/TagNames.cpp +++ b/Libraries/LibWeb/MathML/TagNames.cpp @@ -9,7 +9,7 @@ namespace Web::MathML::TagNames { #define __ENUMERATE_MATHML_TAG(name, tag) \ - FlyString name = tag##_fly_string; + FlyString const& name = *new FlyString(tag##_fly_string); ENUMERATE_MATHML_TAGS #undef __ENUMERATE_MATHML_TAG diff --git a/Libraries/LibWeb/MathML/TagNames.h b/Libraries/LibWeb/MathML/TagNames.h index 1fb1dcbd12..15ad943d27 100644 --- a/Libraries/LibWeb/MathML/TagNames.h +++ b/Libraries/LibWeb/MathML/TagNames.h @@ -44,7 +44,7 @@ namespace Web::MathML::TagNames { __ENUMERATE_MATHML_TAG(munderover, "munderover") \ __ENUMERATE_MATHML_TAG(semantics, "semantics") -#define __ENUMERATE_MATHML_TAG(name, tag) extern FlyString name; +#define __ENUMERATE_MATHML_TAG(name, tag) extern FlyString const& name; ENUMERATE_MATHML_TAGS #undef __ENUMERATE_MATHML_TAG diff --git a/Libraries/LibWeb/MediaCapture/MediaDevices.cpp b/Libraries/LibWeb/MediaCapture/MediaDevices.cpp index 444a96cc2f..1ecd6fb4a0 100644 --- a/Libraries/LibWeb/MediaCapture/MediaDevices.cpp +++ b/Libraries/LibWeb/MediaCapture/MediaDevices.cpp @@ -32,9 +32,9 @@ namespace Web::MediaCapture { -static String const AUDIO_INPUT_KIND = "audioinput"_string; -static String const AUDIO_OUTPUT_KIND = "audiooutput"_string; -static String const VIDEO_INPUT_KIND = "videoinput"_string; +static String const& AUDIO_INPUT_KIND = *new String("audioinput"_string); +static String const& AUDIO_OUTPUT_KIND = *new String("audiooutput"_string); +static String const& VIDEO_INPUT_KIND = *new String("videoinput"_string); using ConstrainDOMString = Variant, Bindings::ConstrainDOMStringParameters>; diff --git a/Libraries/LibWeb/MediaSourceExtensions/EventNames.cpp b/Libraries/LibWeb/MediaSourceExtensions/EventNames.cpp index 4bdf7e2e24..4a8fc3419b 100644 --- a/Libraries/LibWeb/MediaSourceExtensions/EventNames.cpp +++ b/Libraries/LibWeb/MediaSourceExtensions/EventNames.cpp @@ -9,7 +9,7 @@ namespace Web::MediaSourceExtensions::EventNames { #define __ENUMERATE_MEDIA_SOURCE_EXTENSIONS_ATTRIBUTE(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_MEDIA_SOURCE_EXTENSIONS_ATTRIBUTES #undef __ENUMERATE_MEDIA_SOURCE_EXTENSIONS_ATTRIBUTE diff --git a/Libraries/LibWeb/MediaSourceExtensions/EventNames.h b/Libraries/LibWeb/MediaSourceExtensions/EventNames.h index 7be5a325ec..801cbbbfe6 100644 --- a/Libraries/LibWeb/MediaSourceExtensions/EventNames.h +++ b/Libraries/LibWeb/MediaSourceExtensions/EventNames.h @@ -25,7 +25,7 @@ namespace Web::MediaSourceExtensions::EventNames { __ENUMERATE_MEDIA_SOURCE_EXTENSIONS_ATTRIBUTE(updateend) \ __ENUMERATE_MEDIA_SOURCE_EXTENSIONS_ATTRIBUTE(updatestart) -#define __ENUMERATE_MEDIA_SOURCE_EXTENSIONS_ATTRIBUTE(name) extern FlyString name; +#define __ENUMERATE_MEDIA_SOURCE_EXTENSIONS_ATTRIBUTE(name) extern FlyString const& name; ENUMERATE_MEDIA_SOURCE_EXTENSIONS_ATTRIBUTES #undef __ENUMERATE_MEDIA_SOURCE_EXTENSIONS_ATTRIBUTE diff --git a/Libraries/LibWeb/Namespace.cpp b/Libraries/LibWeb/Namespace.cpp index 350a15f9a4..020872036d 100644 --- a/Libraries/LibWeb/Namespace.cpp +++ b/Libraries/LibWeb/Namespace.cpp @@ -9,7 +9,7 @@ namespace Web::Namespace { #define __ENUMERATE_NAMESPACE(name, namespace_) \ - FlyString name = namespace_##_fly_string; + FlyString const& name = *new FlyString(namespace_##_fly_string); ENUMERATE_NAMESPACES #undef __ENUMERATE_NAMESPACE diff --git a/Libraries/LibWeb/Namespace.h b/Libraries/LibWeb/Namespace.h index 339e385ca4..b4cfb9b3cf 100644 --- a/Libraries/LibWeb/Namespace.h +++ b/Libraries/LibWeb/Namespace.h @@ -19,7 +19,7 @@ namespace Web::Namespace { __ENUMERATE_NAMESPACE(XML, "http://www.w3.org/XML/1998/namespace") \ __ENUMERATE_NAMESPACE(XMLNS, "http://www.w3.org/2000/xmlns/") -#define __ENUMERATE_NAMESPACE(name, namespace_) extern WEB_API FlyString name; +#define __ENUMERATE_NAMESPACE(name, namespace_) extern WEB_API FlyString const& name; ENUMERATE_NAMESPACES #undef __ENUMERATE_NAMESPACE diff --git a/Libraries/LibWeb/NavigationTiming/EntryNames.cpp b/Libraries/LibWeb/NavigationTiming/EntryNames.cpp index 2657a0651c..7b1f0a77e0 100644 --- a/Libraries/LibWeb/NavigationTiming/EntryNames.cpp +++ b/Libraries/LibWeb/NavigationTiming/EntryNames.cpp @@ -9,7 +9,7 @@ namespace Web::NavigationTiming::EntryNames { #define __ENUMERATE_NAVIGATION_TIMING_ENTRY_NAME(name, _) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_NAVIGATION_TIMING_ENTRY_NAMES #undef __ENUMERATE_NAVIGATION_TIMING_ENTRY_NAME diff --git a/Libraries/LibWeb/NavigationTiming/EntryNames.h b/Libraries/LibWeb/NavigationTiming/EntryNames.h index 6a33d86ed6..88c7b20db7 100644 --- a/Libraries/LibWeb/NavigationTiming/EntryNames.h +++ b/Libraries/LibWeb/NavigationTiming/EntryNames.h @@ -33,7 +33,7 @@ namespace Web::NavigationTiming::EntryNames { __ENUMERATE_NAVIGATION_TIMING_ENTRY_NAME(unloadEventEnd, unload_event_end) \ __ENUMERATE_NAVIGATION_TIMING_ENTRY_NAME(unloadEventStart, unload_event_start) -#define __ENUMERATE_NAVIGATION_TIMING_ENTRY_NAME(name, _) extern FlyString name; +#define __ENUMERATE_NAVIGATION_TIMING_ENTRY_NAME(name, _) extern FlyString const& name; ENUMERATE_NAVIGATION_TIMING_ENTRY_NAMES #undef __ENUMERATE_NAVIGATION_TIMING_ENTRY_NAME diff --git a/Libraries/LibWeb/PerformanceTimeline/EntryTypes.cpp b/Libraries/LibWeb/PerformanceTimeline/EntryTypes.cpp index 52e17a7994..682e88221b 100644 --- a/Libraries/LibWeb/PerformanceTimeline/EntryTypes.cpp +++ b/Libraries/LibWeb/PerformanceTimeline/EntryTypes.cpp @@ -9,7 +9,7 @@ namespace Web::PerformanceTimeline::EntryTypes { #define __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(name, type) \ - FlyString name = type##_fly_string; + FlyString const& name = *new FlyString(type##_fly_string); ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPES #undef __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE diff --git a/Libraries/LibWeb/PerformanceTimeline/EntryTypes.h b/Libraries/LibWeb/PerformanceTimeline/EntryTypes.h index 82d364603f..81eda5008c 100644 --- a/Libraries/LibWeb/PerformanceTimeline/EntryTypes.h +++ b/Libraries/LibWeb/PerformanceTimeline/EntryTypes.h @@ -24,7 +24,7 @@ namespace Web::PerformanceTimeline::EntryTypes { __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(paint, "paint") \ __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(resource, "resource") -#define __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(name, type) extern FlyString name; +#define __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(name, type) extern FlyString const& name; ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPES #undef __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE diff --git a/Libraries/LibWeb/PerformanceTimeline/EventNames.cpp b/Libraries/LibWeb/PerformanceTimeline/EventNames.cpp index 40f882a2d1..4afe741e17 100644 --- a/Libraries/LibWeb/PerformanceTimeline/EventNames.cpp +++ b/Libraries/LibWeb/PerformanceTimeline/EventNames.cpp @@ -9,7 +9,7 @@ namespace Web::PerformanceTimeline::EventNames { #define __ENUMERATE_PERFORMANCE_TIMELINE_EVENT(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_PERFORMANCE_TIMELINE_EVENTS #undef __ENUMERATE_PERFORMANCE_TIMELINE_EVENT diff --git a/Libraries/LibWeb/PerformanceTimeline/EventNames.h b/Libraries/LibWeb/PerformanceTimeline/EventNames.h index 82d33c41c2..9c6353eefd 100644 --- a/Libraries/LibWeb/PerformanceTimeline/EventNames.h +++ b/Libraries/LibWeb/PerformanceTimeline/EventNames.h @@ -13,7 +13,7 @@ namespace Web::PerformanceTimeline::EventNames { #define ENUMERATE_PERFORMANCE_TIMELINE_EVENTS \ __ENUMERATE_PERFORMANCE_TIMELINE_EVENT(resourcetimingbufferfull) -#define __ENUMERATE_PERFORMANCE_TIMELINE_EVENT(name) extern FlyString name; +#define __ENUMERATE_PERFORMANCE_TIMELINE_EVENT(name) extern FlyString const& name; ENUMERATE_PERFORMANCE_TIMELINE_EVENTS #undef __ENUMERATE_PERFORMANCE_TIMELINE_EVENT diff --git a/Libraries/LibWeb/PermissionsAPI/PermissionStore.cpp b/Libraries/LibWeb/PermissionsAPI/PermissionStore.cpp index b280bf4bba..59942812f1 100644 --- a/Libraries/LibWeb/PermissionsAPI/PermissionStore.cpp +++ b/Libraries/LibWeb/PermissionsAPI/PermissionStore.cpp @@ -41,7 +41,7 @@ URL::Origin permission_key_generation_algorithm(URL::Origin const& origin, URL:: // FIXME: This should be store at the user-agent level (IPC to the browser process) PermissionStore& PermissionStore::the() { - static PermissionStore s_the; + static auto& s_the = *new PermissionStore; return s_the; } diff --git a/Libraries/LibWeb/PermissionsPolicy/AutoplayAllowlist.cpp b/Libraries/LibWeb/PermissionsPolicy/AutoplayAllowlist.cpp index 3653214552..e151fec5c7 100644 --- a/Libraries/LibWeb/PermissionsPolicy/AutoplayAllowlist.cpp +++ b/Libraries/LibWeb/PermissionsPolicy/AutoplayAllowlist.cpp @@ -19,7 +19,7 @@ namespace Web::PermissionsPolicy { AutoplayAllowlist& AutoplayAllowlist::the() { - static AutoplayAllowlist filter; + static auto& filter = *new AutoplayAllowlist; return filter; } diff --git a/Libraries/LibWeb/SVG/AttributeNames.cpp b/Libraries/LibWeb/SVG/AttributeNames.cpp index 39b6d554e5..9e3b99d991 100644 --- a/Libraries/LibWeb/SVG/AttributeNames.cpp +++ b/Libraries/LibWeb/SVG/AttributeNames.cpp @@ -9,7 +9,7 @@ namespace Web::SVG::AttributeNames { #define __ENUMERATE_SVG_ATTRIBUTE(name, attribute) \ - FlyString name = attribute##_fly_string; + FlyString const& name = *new FlyString(attribute##_fly_string); ENUMERATE_SVG_ATTRIBUTES #undef __ENUMERATE_SVG_ATTRIBUTE diff --git a/Libraries/LibWeb/SVG/AttributeNames.h b/Libraries/LibWeb/SVG/AttributeNames.h index 7bbdbeefb0..9bf50bb1f1 100644 --- a/Libraries/LibWeb/SVG/AttributeNames.h +++ b/Libraries/LibWeb/SVG/AttributeNames.h @@ -122,7 +122,7 @@ namespace Web::SVG::AttributeNames { __ENUMERATE_SVG_ATTRIBUTE(yChannelSelector, "yChannelSelector") \ __ENUMERATE_SVG_ATTRIBUTE(zoomAndPan, "zoomAndPan") -#define __ENUMERATE_SVG_ATTRIBUTE(name, attribute) extern FlyString name; +#define __ENUMERATE_SVG_ATTRIBUTE(name, attribute) extern FlyString const& name; ENUMERATE_SVG_ATTRIBUTES #undef __ENUMERATE_SVG_ATTRIBUTE diff --git a/Libraries/LibWeb/SVG/SVGElement.cpp b/Libraries/LibWeb/SVG/SVGElement.cpp index 7f1f5cbf8f..6d6db656e2 100644 --- a/Libraries/LibWeb/SVG/SVGElement.cpp +++ b/Libraries/LibWeb/SVG/SVGElement.cpp @@ -58,7 +58,7 @@ struct NamedPropertyID { static ReadonlySpan attribute_style_properties() { // https://svgwg.org/svg2-draft/styling.html#PresentationAttributes - static Array const properties = { + static auto const& properties = *new Array { // FIXME: The `fill` attribute and CSS `fill` property are not the same! But our support is limited enough that they are equivalent for now. NamedPropertyID(CSS::PropertyID::Fill), // FIXME: The `stroke` attribute and CSS `stroke` property are not the same! But our support is limited enough that they are equivalent for now. diff --git a/Libraries/LibWeb/SVG/TagNames.cpp b/Libraries/LibWeb/SVG/TagNames.cpp index df311679a3..8a6258f766 100644 --- a/Libraries/LibWeb/SVG/TagNames.cpp +++ b/Libraries/LibWeb/SVG/TagNames.cpp @@ -9,7 +9,7 @@ namespace Web::SVG::TagNames { #define __ENUMERATE_SVG_TAG(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_SVG_TAGS #undef __ENUMERATE_SVG_TAG diff --git a/Libraries/LibWeb/SVG/TagNames.h b/Libraries/LibWeb/SVG/TagNames.h index aef6a79f42..2017dc3b5a 100644 --- a/Libraries/LibWeb/SVG/TagNames.h +++ b/Libraries/LibWeb/SVG/TagNames.h @@ -61,7 +61,7 @@ namespace Web::SVG::TagNames { __ENUMERATE_SVG_TAG(use) \ __ENUMERATE_SVG_TAG(view) -#define __ENUMERATE_SVG_TAG(name) extern FlyString name; +#define __ENUMERATE_SVG_TAG(name) extern FlyString const& name; ENUMERATE_SVG_TAGS #undef __ENUMERATE_SVG_TAG diff --git a/Libraries/LibWeb/ServiceWorker/EventNames.cpp b/Libraries/LibWeb/ServiceWorker/EventNames.cpp index 93e9f68402..f91f526e09 100644 --- a/Libraries/LibWeb/ServiceWorker/EventNames.cpp +++ b/Libraries/LibWeb/ServiceWorker/EventNames.cpp @@ -9,7 +9,7 @@ namespace Web::ServiceWorker::EventNames { #define __ENUMERATE_SERVICE_WORKER_EVENT(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_SERVICE_WORKER_EVENTS #undef __ENUMERATE_SERVICE_WORKER_EVENT diff --git a/Libraries/LibWeb/ServiceWorker/EventNames.h b/Libraries/LibWeb/ServiceWorker/EventNames.h index f449f43881..d21afa446e 100644 --- a/Libraries/LibWeb/ServiceWorker/EventNames.h +++ b/Libraries/LibWeb/ServiceWorker/EventNames.h @@ -17,7 +17,7 @@ namespace Web::ServiceWorker::EventNames { __ENUMERATE_SERVICE_WORKER_EVENT(message) \ __ENUMERATE_SERVICE_WORKER_EVENT(messageerror) -#define __ENUMERATE_SERVICE_WORKER_EVENT(name) extern FlyString name; +#define __ENUMERATE_SERVICE_WORKER_EVENT(name) extern FlyString const& name; ENUMERATE_SERVICE_WORKER_EVENTS #undef __ENUMERATE_SERVICE_WORKER_EVENT diff --git a/Libraries/LibWeb/ServiceWorker/Job.cpp b/Libraries/LibWeb/ServiceWorker/Job.cpp index 65b7500dee..331342d07a 100644 --- a/Libraries/LibWeb/ServiceWorker/Job.cpp +++ b/Libraries/LibWeb/ServiceWorker/Job.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -72,8 +73,8 @@ void Job::visit_edges(JS::Cell::Visitor& visitor) // https://w3c.github.io/ServiceWorker/#dfn-scope-to-job-queue-map static HashMap& scope_to_job_queue_map() { - static HashMap map; - return map; + static NeverDestroyed> map; + return *map; } // https://w3c.github.io/ServiceWorker/#register-algorithm diff --git a/Libraries/LibWeb/ServiceWorker/Registration.cpp b/Libraries/LibWeb/ServiceWorker/Registration.cpp index 4040395016..70a858d830 100644 --- a/Libraries/LibWeb/ServiceWorker/Registration.cpp +++ b/Libraries/LibWeb/ServiceWorker/Registration.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -13,7 +14,11 @@ namespace Web::ServiceWorker { // FIXME: Surely this needs hooks to be cleared and manipulated at the UA level // Does this need to be serialized to disk as well? -static OrderedHashMap s_registrations; +static OrderedHashMap& registration_map() +{ + static NeverDestroyed> registrations; + return *registrations; +} Registration::Registration(StorageAPI::StorageKey storage_key, URL::URL scope, Bindings::ServiceWorkerUpdateViaCache update_via_cache) : m_storage_key(move(storage_key)) @@ -28,7 +33,7 @@ bool Registration::is_unregistered() // A service worker registration is said to be unregistered if registration map[this service worker registration's (storage key, serialized scope url)] is not this service worker registration. // FIXME: Suspect that spec should say to serialize without fragment auto const key = RegistrationKey { m_storage_key, m_scope_url.serialize(URL::ExcludeFragment::Yes).to_byte_string() }; - return s_registrations.get(key).map([](auto& registration) { return ®istration; }).value_or(nullptr) != this; + return registration_map().get(key).map([](auto& registration) { return ®istration; }).value_or(nullptr) != this; } // https://w3c.github.io/ServiceWorker/#service-worker-registration-stale @@ -60,7 +65,7 @@ Optional Registration::get(StorageAPI::StorageKey const& key, Opt // 4. For each (entry storage key, entry scope) → registration of registration map: // 1. If storage key equals entry storage key and scopeString matches entry scope, then return registration. // 5. Return null. - return s_registrations.get({ key, scope_string }); + return registration_map().get({ key, scope_string }); } // https://w3c.github.io/ServiceWorker/#set-registration-algorithm @@ -75,8 +80,8 @@ Registration& Registration::set(StorageAPI::StorageKey const& storage_key, URL:: // FIXME: Is there a way to "ensure but always replace?" auto key = RegistrationKey { storage_key, scope.serialize(URL::ExcludeFragment::Yes).to_byte_string() }; - (void)s_registrations.set(key, Registration(storage_key, scope, update_via_cache)); - return s_registrations.get(key).value(); + (void)registration_map().set(key, Registration(storage_key, scope, update_via_cache)); + return registration_map().get(key).value(); } // https://w3c.github.io/ServiceWorker/#scope-match-algorithm @@ -94,7 +99,7 @@ Optional Registration::match(StorageAPI::StorageKey const& storag Vector scope_string_set; // 5. For each (entry storage key, entry scope) of registration map's keys: - for (auto& [entry_storage_key, entry_scope] : s_registrations.keys()) { + for (auto& [entry_storage_key, entry_scope] : registration_map().keys()) { // 1. If storage key equals entry storage key, then append entry scope to the end of scopeStringSet. if (entry_storage_key == storage_key) scope_string_set.append(entry_scope); @@ -130,7 +135,7 @@ Vector Registration::for_storage_key(StorageAPI::StorageKey const { Vector registrations; - for (auto& [registration_key, registration] : s_registrations) { + for (auto& [registration_key, registration] : registration_map()) { if (registration_key.key == storage_key) registrations.append(®istration); } @@ -140,7 +145,7 @@ Vector Registration::for_storage_key(StorageAPI::StorageKey const void Registration::remove(StorageAPI::StorageKey const& key, URL::URL const& scope) { - (void)s_registrations.remove({ key, scope.serialize(URL::ExcludeFragment::Yes).to_byte_string() }); + (void)registration_map().remove({ key, scope.serialize(URL::ExcludeFragment::Yes).to_byte_string() }); } // https://w3c.github.io/ServiceWorker/#get-newest-worker diff --git a/Libraries/LibWeb/TrustedTypes/RequireTrustedTypesForDirective.cpp b/Libraries/LibWeb/TrustedTypes/RequireTrustedTypesForDirective.cpp index 188c657385..38ca47fbd8 100644 --- a/Libraries/LibWeb/TrustedTypes/RequireTrustedTypesForDirective.cpp +++ b/Libraries/LibWeb/TrustedTypes/RequireTrustedTypesForDirective.cpp @@ -17,7 +17,7 @@ namespace Web::TrustedTypes { #define __ENUMERATE_REQUIRE_KEYWORD_TRUSTED_TYPES_FOR(name, value) \ - FlyString name = value##_fly_string; + FlyString const& name = *new FlyString(value##_fly_string); ENUMERATE_REQUIRE_KEYWORD_TRUSTED_TYPES_FOR #undef __ENUMERATE_REQUIRE_KEYWORD_TRUSTED_TYPES_FOR diff --git a/Libraries/LibWeb/TrustedTypes/RequireTrustedTypesForDirective.h b/Libraries/LibWeb/TrustedTypes/RequireTrustedTypesForDirective.h index 527bd0ae97..2ef66d6d5c 100644 --- a/Libraries/LibWeb/TrustedTypes/RequireTrustedTypesForDirective.h +++ b/Libraries/LibWeb/TrustedTypes/RequireTrustedTypesForDirective.h @@ -16,7 +16,7 @@ namespace Web::TrustedTypes { #define ENUMERATE_REQUIRE_KEYWORD_TRUSTED_TYPES_FOR \ __ENUMERATE_REQUIRE_KEYWORD_TRUSTED_TYPES_FOR(Script, "'script'") -#define __ENUMERATE_REQUIRE_KEYWORD_TRUSTED_TYPES_FOR(name, value) extern FlyString name; +#define __ENUMERATE_REQUIRE_KEYWORD_TRUSTED_TYPES_FOR(name, value) extern FlyString const& name; ENUMERATE_REQUIRE_KEYWORD_TRUSTED_TYPES_FOR #undef __ENUMERATE_REQUIRE_KEYWORD_TRUSTED_TYPES_FOR diff --git a/Libraries/LibWeb/TrustedTypes/TrustedTypePolicyFactory.cpp b/Libraries/LibWeb/TrustedTypes/TrustedTypePolicyFactory.cpp index 0493f4c79a..132537032f 100644 --- a/Libraries/LibWeb/TrustedTypes/TrustedTypePolicyFactory.cpp +++ b/Libraries/LibWeb/TrustedTypes/TrustedTypePolicyFactory.cpp @@ -98,7 +98,7 @@ Optional TrustedTypePolicyFactory::get_property_type(Utf16String co TrustedTypeName trusted_type; }; - static Vector const table { + static auto const& table = *new Vector { { "HTMLIFrameElement"_utf16, "srcdoc"_utf16, TrustedTypeName::TrustedHTML }, { "HTMLScriptElement"_utf16, "innerText"_utf16, TrustedTypeName::TrustedScript }, { "HTMLScriptElement"_utf16, "src"_utf16, TrustedTypeName::TrustedScriptURL }, @@ -318,7 +318,7 @@ Optional get_trusted_type_data_for_attribute(ElementInterface c #undef __ENUMERATE } - static Vector const table { + static auto const& table = *new Vector { { "HTMLIFrameElement"_utf16, {}, HTML::AttributeNames::srcdoc, TrustedTypeName::TrustedHTML, InjectionSink::HTMLIFrameElement_srcdoc }, { "HTMLScriptElement"_utf16, {}, HTML::AttributeNames::src, TrustedTypeName::TrustedScriptURL, InjectionSink::HTMLScriptElement_src }, { "SVGScriptElement"_utf16, {}, HTML::AttributeNames::href, TrustedTypeName::TrustedScriptURL, InjectionSink::SVGScriptElement_href }, diff --git a/Libraries/LibWeb/UIEvents/EventNames.cpp b/Libraries/LibWeb/UIEvents/EventNames.cpp index 02b1e3320b..a95cf02ab8 100644 --- a/Libraries/LibWeb/UIEvents/EventNames.cpp +++ b/Libraries/LibWeb/UIEvents/EventNames.cpp @@ -9,7 +9,7 @@ namespace Web::UIEvents::EventNames { #define __ENUMERATE_UI_EVENT(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_UI_EVENTS #undef __ENUMERATE_UI_EVENT diff --git a/Libraries/LibWeb/UIEvents/EventNames.h b/Libraries/LibWeb/UIEvents/EventNames.h index f91f9e9ce4..8496bb32ef 100644 --- a/Libraries/LibWeb/UIEvents/EventNames.h +++ b/Libraries/LibWeb/UIEvents/EventNames.h @@ -44,7 +44,7 @@ namespace Web::UIEvents::EventNames { __ENUMERATE_UI_EVENT(resize) \ __ENUMERATE_UI_EVENT(wheel) -#define __ENUMERATE_UI_EVENT(name) extern WEB_API FlyString name; +#define __ENUMERATE_UI_EVENT(name) extern WEB_API FlyString const& name; ENUMERATE_UI_EVENTS #undef __ENUMERATE_UI_EVENT diff --git a/Libraries/LibWeb/UIEvents/InputTypes.cpp b/Libraries/LibWeb/UIEvents/InputTypes.cpp index ce2fc1d994..d6c2f18dc5 100644 --- a/Libraries/LibWeb/UIEvents/InputTypes.cpp +++ b/Libraries/LibWeb/UIEvents/InputTypes.cpp @@ -9,7 +9,7 @@ namespace Web::UIEvents::InputTypes { #define __ENUMERATE_INPUT_TYPE(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_INPUT_TYPES #undef __ENUMERATE_INPUT_TYPE diff --git a/Libraries/LibWeb/UIEvents/InputTypes.h b/Libraries/LibWeb/UIEvents/InputTypes.h index b55fd89076..700ca04351 100644 --- a/Libraries/LibWeb/UIEvents/InputTypes.h +++ b/Libraries/LibWeb/UIEvents/InputTypes.h @@ -20,7 +20,7 @@ namespace Web::UIEvents::InputTypes { __ENUMERATE_INPUT_TYPE(insertParagraph) \ __ENUMERATE_INPUT_TYPE(insertText) -#define __ENUMERATE_INPUT_TYPE(name) extern FlyString name; +#define __ENUMERATE_INPUT_TYPE(name) extern FlyString const& name; ENUMERATE_INPUT_TYPES #undef __ENUMERATE_INPUT_TYPE diff --git a/Libraries/LibWeb/WebAssembly/WebAssembly.cpp b/Libraries/LibWeb/WebAssembly/WebAssembly.cpp index 22216c63b3..7e020ebe10 100644 --- a/Libraries/LibWeb/WebAssembly/WebAssembly.cpp +++ b/Libraries/LibWeb/WebAssembly/WebAssembly.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -53,11 +54,15 @@ static GC::Ref compile_potential_webassembly_response(JS::VM&, namespace Detail { -GC::WeakHashMap s_caches; +static GC::WeakHashMap& caches() +{ + static NeverDestroyed> caches; + return *caches; +} WebAssemblyCache& get_cache(JS::Realm& realm) { - return s_caches.ensure(realm.global_object()); + return caches().ensure(realm.global_object()); } } @@ -65,7 +70,7 @@ WebAssemblyCache& get_cache(JS::Realm& realm) void visit_edges(JS::Object& object, JS::Cell::Visitor& visitor) { auto& global_object = HTML::relevant_global_object(object); - if (auto maybe_cache = Detail::s_caches.get(global_object); maybe_cache.has_value()) { + if (auto maybe_cache = Detail::caches().get(global_object); maybe_cache.has_value()) { auto& cache = maybe_cache.value(); visitor.visit(cache.function_instances()); visitor.visit(cache.imported_objects()); @@ -83,7 +88,7 @@ void visit_edges(JS::Object& object, JS::Cell::Visitor& visitor) void finalize(JS::Object& object) { auto& global_object = HTML::relevant_global_object(object); - Detail::s_caches.remove(global_object); + Detail::caches().remove(global_object); } // https://webassembly.github.io/spec/js-api/#error-objects @@ -683,7 +688,7 @@ JS::NativeFunction* create_native_function(JS::VM& vm, Wasm::FunctionAddress add JS::ThrowCompletionOr to_webassembly_value(JS::VM& vm, JS::Value value, Wasm::ValueType const& type) { - static ::Crypto::SignedBigInteger two_64 = TRY_OR_THROW_OOM(vm, "1"_sbigint.shift_left(64)); + static auto& two_64 = *new ::Crypto::SignedBigInteger(TRY_OR_THROW_OOM(vm, "1"_sbigint.shift_left(64))); switch (type.kind()) { case Wasm::ValueType::I64: { diff --git a/Libraries/LibWeb/WebDriver/Capabilities.cpp b/Libraries/LibWeb/WebDriver/Capabilities.cpp index b88d180f4a..a458424c36 100644 --- a/Libraries/LibWeb/WebDriver/Capabilities.cpp +++ b/Libraries/LibWeb/WebDriver/Capabilities.cpp @@ -235,9 +235,9 @@ static bool matches_platform_name(StringView requested_platform_name, StringView // https://w3c.github.io/webdriver/#dfn-matching-capabilities static JsonValue match_capabilities(JsonObject const& capabilities, SessionFlags flags) { - static auto browser_name = String::from_utf8_without_validation({ BROWSER_NAME, __builtin_strlen(BROWSER_NAME) }).to_ascii_lowercase(); - static auto browser_version = String::from_utf8_without_validation({ BROWSER_VERSION, __builtin_strlen(BROWSER_VERSION) }); - static auto platform_name = String::from_utf8_without_validation({ OS_STRING, __builtin_strlen(OS_STRING) }).to_ascii_lowercase(); + static auto& browser_name = *new String(String::from_utf8_without_validation({ BROWSER_NAME, __builtin_strlen(BROWSER_NAME) }).to_ascii_lowercase()); + static auto& browser_version = *new String(String::from_utf8_without_validation({ BROWSER_VERSION, __builtin_strlen(BROWSER_VERSION) })); + static auto& platform_name = *new String(String::from_utf8_without_validation({ OS_STRING, __builtin_strlen(OS_STRING) }).to_ascii_lowercase()); // 1. Let matched capabilities be a JSON Object with the following entries: JsonObject matched_capabilities; diff --git a/Libraries/LibWeb/WebDriver/Contexts.cpp b/Libraries/LibWeb/WebDriver/Contexts.cpp index 8e2cb8fc30..99f0d8ffff 100644 --- a/Libraries/LibWeb/WebDriver/Contexts.cpp +++ b/Libraries/LibWeb/WebDriver/Contexts.cpp @@ -14,10 +14,10 @@ namespace Web::WebDriver { // https://w3c.github.io/webdriver/#dfn-web-window-identifier -static JS::PropertyKey const WEB_WINDOW_IDENTIFIER { "window-fcc6-11e5-b4f8-330a88ab9d7f"_utf16_fly_string }; +static auto const& WEB_WINDOW_IDENTIFIER = *new JS::PropertyKey("window-fcc6-11e5-b4f8-330a88ab9d7f"_utf16_fly_string); // https://w3c.github.io/webdriver/#dfn-web-frame-identifier -static JS::PropertyKey const WEB_FRAME_IDENTIFIER { "frame-075b-4da1-b6ba-e579c2d3230a"_utf16_fly_string }; +static auto const& WEB_FRAME_IDENTIFIER = *new JS::PropertyKey("frame-075b-4da1-b6ba-e579c2d3230a"_utf16_fly_string); // https://w3c.github.io/webdriver/#dfn-windowproxy-reference-object JsonObject window_proxy_reference_object(HTML::WindowProxy const& window) diff --git a/Libraries/LibWeb/WebDriver/ElementReference.cpp b/Libraries/LibWeb/WebDriver/ElementReference.cpp index 3d7559f987..83e2594aaf 100644 --- a/Libraries/LibWeb/WebDriver/ElementReference.cpp +++ b/Libraries/LibWeb/WebDriver/ElementReference.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -25,18 +26,26 @@ namespace Web::WebDriver { // https://w3c.github.io/webdriver/#dfn-web-element-identifier -static String const web_element_identifier = "element-6066-11e4-a52e-4f735466cecf"_string; -static JS::PropertyKey web_element_identifier_key { Utf16FlyString::from_utf8(web_element_identifier) }; +static auto const& web_element_identifier = *new String("element-6066-11e4-a52e-4f735466cecf"_string); +static auto const& web_element_identifier_key = *new JS::PropertyKey(Utf16FlyString::from_utf8(web_element_identifier)); // https://w3c.github.io/webdriver/#dfn-shadow-root-identifier -static String const shadow_root_identifier = "shadow-6066-11e4-a52e-4f735466cecf"_string; -static JS::PropertyKey shadow_root_identifier_key { Utf16FlyString::from_utf8(shadow_root_identifier) }; +static auto const& shadow_root_identifier = *new String("shadow-6066-11e4-a52e-4f735466cecf"_string); +static auto const& shadow_root_identifier_key = *new JS::PropertyKey(Utf16FlyString::from_utf8(shadow_root_identifier)); // https://w3c.github.io/webdriver/#dfn-browsing-context-group-node-map -static HashMap, HashTable> browsing_context_group_node_map; +static HashMap, HashTable>& browsing_context_group_node_map() +{ + static NeverDestroyed, HashTable>> map; + return *map; +} // https://w3c.github.io/webdriver/#dfn-navigable-seen-nodes-map -static HashMap, HashTable> navigable_seen_nodes_map; +static HashMap, HashTable>& navigable_seen_nodes_map() +{ + static NeverDestroyed, HashTable>> map; + return *map; +} // https://w3c.github.io/webdriver/#dfn-get-a-node GC::Ptr get_node(HTML::BrowsingContext const& browsing_context, StringView reference) @@ -47,7 +56,7 @@ GC::Ptr get_node(HTML::BrowsingContext const& browsing_context, // 3. If browsing context group node map does not contain browsing context group, return null. // 4. Let node id map be browsing context group node map[browsing context group]. - auto node_id_map = browsing_context_group_node_map.get(browsing_context_group); + auto node_id_map = browsing_context_group_node_map().get(browsing_context_group); if (!node_id_map.has_value()) return nullptr; @@ -73,7 +82,7 @@ String get_or_create_a_node_reference(HTML::BrowsingContext const& browsing_cont // 3. If browsing context group node map does not contain browsing context group, set browsing context group node // map[browsing context group] to a new weak map. // 4. Let node id map be browsing context group node map[browsing context group]. - auto& node_id_map = browsing_context_group_node_map.ensure(browsing_context_group); + auto& node_id_map = browsing_context_group_node_map().ensure(browsing_context_group); auto node_id = String::number(node.unique_id().value()); @@ -89,7 +98,7 @@ String get_or_create_a_node_reference(HTML::BrowsingContext const& browsing_cont // 4. Let navigable seen nodes map be session's navigable seen nodes map. // 5. If navigable seen nodes map does not contain navigable, set navigable seen nodes map[navigable] to an empty set. // 6. Append node id to navigable seen nodes map[navigable]. - navigable_seen_nodes_map.ensure(navigable).set(node_id); + navigable_seen_nodes_map().ensure(navigable).set(node_id); } // 6. Return node id map[node]. @@ -107,7 +116,7 @@ bool node_reference_is_known(HTML::BrowsingContext const& browsing_context, Stri // 2. Let navigable seen nodes map be session's navigable seen nodes map. // 3. If navigable seen nodes map contains navigable and navigable seen nodes map[navigable] contains reference, // return true, otherwise return false. - if (auto map = navigable_seen_nodes_map.get(navigable); map.has_value()) + if (auto map = navigable_seen_nodes_map().get(navigable); map.has_value()) return map->contains(reference); return false; } diff --git a/Libraries/LibWeb/WebDriver/Error.cpp b/Libraries/LibWeb/WebDriver/Error.cpp index f4e347255f..03f30ac395 100644 --- a/Libraries/LibWeb/WebDriver/Error.cpp +++ b/Libraries/LibWeb/WebDriver/Error.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -17,41 +18,45 @@ struct ErrorCodeData { }; // https://w3c.github.io/webdriver/#dfn-error-code -static Vector const s_error_code_data = { - { ErrorCode::ElementClickIntercepted, 400, "element click intercepted"_string }, - { ErrorCode::ElementNotInteractable, 400, "element not interactable"_string }, - { ErrorCode::InsecureCertificate, 400, "insecure certificate"_string }, - { ErrorCode::InvalidArgument, 400, "invalid argument"_string }, - { ErrorCode::InvalidCookieDomain, 400, "invalid cookie domain"_string }, - { ErrorCode::InvalidElementState, 400, "invalid element state"_string }, - { ErrorCode::InvalidSelector, 400, "invalid selector"_string }, - { ErrorCode::InvalidSessionId, 404, "invalid session id"_string }, - { ErrorCode::JavascriptError, 500, "javascript error"_string }, - { ErrorCode::MoveTargetOutOfBounds, 500, "move target out of bounds"_string }, - { ErrorCode::NoSuchAlert, 404, "no such alert"_string }, - { ErrorCode::NoSuchCookie, 404, "no such cookie"_string }, - { ErrorCode::NoSuchElement, 404, "no such element"_string }, - { ErrorCode::NoSuchFrame, 404, "no such frame"_string }, - { ErrorCode::NoSuchWindow, 404, "no such window"_string }, - { ErrorCode::NoSuchShadowRoot, 404, "no such shadow root"_string }, - { ErrorCode::ScriptTimeoutError, 500, "script timeout"_string }, - { ErrorCode::SessionNotCreated, 500, "session not created"_string }, - { ErrorCode::StaleElementReference, 404, "stale element reference"_string }, - { ErrorCode::DetachedShadowRoot, 404, "detached shadow root"_string }, - { ErrorCode::Timeout, 500, "timeout"_string }, - { ErrorCode::UnableToSetCookie, 500, "unable to set cookie"_string }, - { ErrorCode::UnableToCaptureScreen, 500, "unable to capture screen"_string }, - { ErrorCode::UnexpectedAlertOpen, 500, "unexpected alert open"_string }, - { ErrorCode::UnknownCommand, 404, "unknown command"_string }, - { ErrorCode::UnknownError, 500, "unknown error"_string }, - { ErrorCode::UnknownMethod, 405, "unknown method"_string }, - { ErrorCode::UnsupportedOperation, 500, "unsupported operation"_string }, - { ErrorCode::OutOfMemory, 500, "out of memory"_string }, -}; +static Vector const& error_code_data() +{ + static auto const& data = *new Vector { + { ErrorCode::ElementClickIntercepted, 400, "element click intercepted"_string }, + { ErrorCode::ElementNotInteractable, 400, "element not interactable"_string }, + { ErrorCode::InsecureCertificate, 400, "insecure certificate"_string }, + { ErrorCode::InvalidArgument, 400, "invalid argument"_string }, + { ErrorCode::InvalidCookieDomain, 400, "invalid cookie domain"_string }, + { ErrorCode::InvalidElementState, 400, "invalid element state"_string }, + { ErrorCode::InvalidSelector, 400, "invalid selector"_string }, + { ErrorCode::InvalidSessionId, 404, "invalid session id"_string }, + { ErrorCode::JavascriptError, 500, "javascript error"_string }, + { ErrorCode::MoveTargetOutOfBounds, 500, "move target out of bounds"_string }, + { ErrorCode::NoSuchAlert, 404, "no such alert"_string }, + { ErrorCode::NoSuchCookie, 404, "no such cookie"_string }, + { ErrorCode::NoSuchElement, 404, "no such element"_string }, + { ErrorCode::NoSuchFrame, 404, "no such frame"_string }, + { ErrorCode::NoSuchWindow, 404, "no such window"_string }, + { ErrorCode::NoSuchShadowRoot, 404, "no such shadow root"_string }, + { ErrorCode::ScriptTimeoutError, 500, "script timeout"_string }, + { ErrorCode::SessionNotCreated, 500, "session not created"_string }, + { ErrorCode::StaleElementReference, 404, "stale element reference"_string }, + { ErrorCode::DetachedShadowRoot, 404, "detached shadow root"_string }, + { ErrorCode::Timeout, 500, "timeout"_string }, + { ErrorCode::UnableToSetCookie, 500, "unable to set cookie"_string }, + { ErrorCode::UnableToCaptureScreen, 500, "unable to capture screen"_string }, + { ErrorCode::UnexpectedAlertOpen, 500, "unexpected alert open"_string }, + { ErrorCode::UnknownCommand, 404, "unknown command"_string }, + { ErrorCode::UnknownError, 500, "unknown error"_string }, + { ErrorCode::UnknownMethod, 405, "unknown method"_string }, + { ErrorCode::UnsupportedOperation, 500, "unsupported operation"_string }, + { ErrorCode::OutOfMemory, 500, "out of memory"_string }, + }; + return data; +} Error Error::from_code(ErrorCode code, String message, Optional data) { - auto const& error_code_data = s_error_code_data[to_underlying(code)]; + auto const& error_code_data = WebDriver::error_code_data()[to_underlying(code)]; return { error_code_data.http_status, diff --git a/Libraries/LibWeb/WebDriver/InputState.cpp b/Libraries/LibWeb/WebDriver/InputState.cpp index a149a58f6d..6b85e92a23 100644 --- a/Libraries/LibWeb/WebDriver/InputState.cpp +++ b/Libraries/LibWeb/WebDriver/InputState.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -11,7 +12,11 @@ namespace Web::WebDriver { // https://w3c.github.io/webdriver/#dfn-browsing-context-input-state-map -static HashMap, InputState> s_browsing_context_input_state_map; +static HashMap, InputState>& browsing_context_input_state_map() +{ + static NeverDestroyed, InputState>> map; + return *map; +} InputState::InputState() = default; InputState::~InputState() = default; @@ -24,7 +29,7 @@ InputState& get_input_state(HTML::BrowsingContext& browsing_context) // 2. Let input state map be session's browsing context input state map. // 3. If input state map does not contain browsing context, set input state map[browsing context] to create an input state. - auto& input_state = s_browsing_context_input_state_map.ensure(browsing_context); + auto& input_state = browsing_context_input_state_map().ensure(browsing_context); // 4. Return input state map[browsing context]. return input_state; @@ -38,7 +43,7 @@ void reset_input_state(HTML::BrowsingContext& browsing_context) // 2. Let input state map be session's browsing context input state map. // 3. If input state map[browsing context] exists, then remove input state map[browsing context]. - s_browsing_context_input_state_map.remove(browsing_context); + browsing_context_input_state_map().remove(browsing_context); } } diff --git a/Libraries/LibWeb/WebDriver/UserPrompt.cpp b/Libraries/LibWeb/WebDriver/UserPrompt.cpp index dd9bba9512..fdf21fc812 100644 --- a/Libraries/LibWeb/WebDriver/UserPrompt.cpp +++ b/Libraries/LibWeb/WebDriver/UserPrompt.cpp @@ -14,7 +14,11 @@ namespace Web::WebDriver { // https://w3c.github.io/webdriver/#dfn-user-prompt-handler -static UserPromptHandler s_user_prompt_handler; +static UserPromptHandler& user_prompt_handler_storage() +{ + static auto& handler = *new UserPromptHandler; + return handler; +} // https://w3c.github.io/webdriver/#dfn-known-prompt-handlers static constexpr Array known_prompt_handlers { "dismiss"sv, "accept"sv, "dismiss and notify"sv, "accept and notify"sv, "ignore"sv }; @@ -104,12 +108,12 @@ StringView PromptHandlerConfiguration::serialize() const UserPromptHandler const& user_prompt_handler() { - return s_user_prompt_handler; + return user_prompt_handler_storage(); } void set_user_prompt_handler(UserPromptHandler user_prompt_handler) { - s_user_prompt_handler = move(user_prompt_handler); + user_prompt_handler_storage() = move(user_prompt_handler); } // https://w3c.github.io/webdriver/#dfn-deserialize-as-an-unhandled-prompt-behavior @@ -192,13 +196,13 @@ Response deserialize_as_an_unhandled_prompt_behavior(JsonValue value) bool check_user_prompt_handler_matches(JsonObject const& requested_prompt_handler) { // 1. If the user prompt handler is null, return true. - if (!s_user_prompt_handler.has_value()) + if (!user_prompt_handler_storage().has_value()) return true; // 2. For each request prompt type → request handler in requested prompt handler: auto result = requested_prompt_handler.try_for_each_member([&](String const& request_prompt_type, JsonValue const& request_handler) -> ErrorOr { // 1. If the user prompt handler contains request prompt type: - if (auto handler = s_user_prompt_handler->get(prompt_type_from_string(request_prompt_type)); handler.has_value()) { + if (auto handler = user_prompt_handler_storage()->get(prompt_type_from_string(request_prompt_type)); handler.has_value()) { // 1. If the requested prompt handler's handler is not equal to the user prompt handler's handler, return false. if (handler != PromptHandlerConfiguration::deserialize(request_handler)) return AK::Error::from_string_literal("Prompt handler mismatch"); @@ -215,13 +219,13 @@ bool check_user_prompt_handler_matches(JsonObject const& requested_prompt_handle void update_the_user_prompt_handler(JsonObject const& requested_prompt_handler) { // 1. If the user prompt handler is null, set the user prompt handler to an empty map. - if (!s_user_prompt_handler.has_value()) - s_user_prompt_handler = UserPromptHandler::ValueType {}; + if (!user_prompt_handler_storage().has_value()) + user_prompt_handler_storage() = UserPromptHandler::ValueType {}; // 2. For each request prompt type → request handler in requested prompt handler: requested_prompt_handler.for_each_member([&](String const& request_prompt_type, JsonValue const& request_handler) { // 1. Set user prompt handler[request prompt type] to request handler. - s_user_prompt_handler->set( + user_prompt_handler_storage()->set( prompt_type_from_string(request_prompt_type), PromptHandlerConfiguration::deserialize(request_handler)); }); @@ -231,13 +235,13 @@ void update_the_user_prompt_handler(JsonObject const& requested_prompt_handler) JsonValue serialize_the_user_prompt_handler() { // 1. If the user prompt handler is null, return "dismiss and notify". - if (!s_user_prompt_handler.has_value()) + if (!user_prompt_handler_storage().has_value()) return "dismiss and notify"sv; // 2. If the user prompt handler has size 1, and user prompt handler contains "fallbackDefault", return the result // of serialize a prompt handler configuration with user prompt handler["fallbackDefault"]. - if (s_user_prompt_handler->size() == 1) { - if (auto handler = s_user_prompt_handler->get(PromptType::FallbackDefault); handler.has_value()) + if (user_prompt_handler_storage()->size() == 1) { + if (auto handler = user_prompt_handler_storage()->get(PromptType::FallbackDefault); handler.has_value()) return handler->serialize(); } @@ -245,7 +249,7 @@ JsonValue serialize_the_user_prompt_handler() JsonObject serialized; // 4. For each key → value of user prompt handler: - for (auto const& [key, value] : *s_user_prompt_handler) { + for (auto const& [key, value] : *user_prompt_handler_storage()) { // 1. Set serialized[key] to serialize a prompt handler configuration with value. serialized.set(prompt_type_to_string(key), value.serialize()); } diff --git a/Libraries/LibWeb/WebGL/EventNames.cpp b/Libraries/LibWeb/WebGL/EventNames.cpp index 256215447d..420d18e34a 100644 --- a/Libraries/LibWeb/WebGL/EventNames.cpp +++ b/Libraries/LibWeb/WebGL/EventNames.cpp @@ -9,7 +9,7 @@ namespace Web::WebGL::EventNames { #define __ENUMERATE_GL_EVENT(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_GL_EVENTS #undef __ENUMERATE_GL_EVENT diff --git a/Libraries/LibWeb/WebGL/EventNames.h b/Libraries/LibWeb/WebGL/EventNames.h index 67b30c17aa..e6c2ec9fcc 100644 --- a/Libraries/LibWeb/WebGL/EventNames.h +++ b/Libraries/LibWeb/WebGL/EventNames.h @@ -15,7 +15,7 @@ namespace Web::WebGL::EventNames { __ENUMERATE_GL_EVENT(webglcontextlost) \ __ENUMERATE_GL_EVENT(webglcontextrestored) -#define __ENUMERATE_GL_EVENT(name) extern FlyString name; +#define __ENUMERATE_GL_EVENT(name) extern FlyString const& name; ENUMERATE_GL_EVENTS #undef __ENUMERATE_GL_EVENT diff --git a/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp b/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp index 6835bb1ef2..b8c2a97dd1 100644 --- a/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp +++ b/Libraries/LibWeb/WebGL/WebGLRenderingContextBase.cpp @@ -112,71 +112,75 @@ struct Extension { Optional only_for_webgl_version { OptionalNone {} }; }; -static HashMap s_available_webgl_extensions { - // Khronos ratified WebGL Extensions - { "ANGLE_instanced_arrays"_string, { { "GL_ANGLE_instanced_arrays"sv }, ANGLEInstancedArrays::create, OpenGLContext::WebGLVersion::WebGL1 } }, - { "EXT_blend_minmax"_string, { { "GL_EXT_blend_minmax"sv }, EXTBlendMinMax::create, OpenGLContext::WebGLVersion::WebGL1 } }, - { "EXT_frag_depth"_string, { { "GL_EXT_frag_depth"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, - { "EXT_shader_texture_lod"_string, { { "GL_EXT_shader_texture_lod"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, - { "EXT_texture_filter_anisotropic"_string, { { "GL_EXT_texture_filter_anisotropic"sv }, EXTTextureFilterAnisotropic::create } }, - { "OES_element_index_uint"_string, { { "GL_OES_element_index_uint"sv }, OESElementIndexUint::create, OpenGLContext::WebGLVersion::WebGL1 } }, - { "OES_standard_derivatives"_string, { { "GL_OES_standard_derivatives"sv }, OESStandardDerivatives::create, OpenGLContext::WebGLVersion::WebGL1 } }, - { "OES_texture_float"_string, { { "GL_OES_texture_float"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, - { "OES_texture_float_linear"_string, { { "GL_OES_texture_float_linear"sv }, nullptr } }, - { "OES_texture_half_float"_string, { { "GL_OES_texture_half_float"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, - { "OES_texture_half_float_linear"_string, { { "GL_OES_texture_half_float_linear"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, - { "OES_vertex_array_object"_string, { { "GL_OES_vertex_array_object"sv }, OESVertexArrayObject::create, OpenGLContext::WebGLVersion::WebGL1 } }, - { "WEBGL_compressed_texture_s3tc"_string, { { "GL_EXT_texture_compression_dxt1"sv, "GL_ANGLE_texture_compression_dxt3"sv, "GL_ANGLE_texture_compression_dxt5"sv }, WebGLCompressedTextureS3tc::create } }, - { "WEBGL_debug_renderer_info"_string, { {}, WebGLDebugRendererInfo::create } }, - { "WEBGL_debug_shaders"_string, { {}, nullptr } }, - { "WEBGL_depth_texture"_string, { { "GL_ANGLE_depth_texture"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, - { "WEBGL_draw_buffers"_string, { { "GL_EXT_draw_buffers"sv }, WebGLDrawBuffers::create, OpenGLContext::WebGLVersion::WebGL1 } }, - { "WEBGL_lose_context"_string, { {}, nullptr } }, +static HashMap const& available_webgl_extensions() +{ + static auto const& extensions = *new HashMap { + // Khronos ratified WebGL Extensions + { "ANGLE_instanced_arrays"_string, { { "GL_ANGLE_instanced_arrays"sv }, ANGLEInstancedArrays::create, OpenGLContext::WebGLVersion::WebGL1 } }, + { "EXT_blend_minmax"_string, { { "GL_EXT_blend_minmax"sv }, EXTBlendMinMax::create, OpenGLContext::WebGLVersion::WebGL1 } }, + { "EXT_frag_depth"_string, { { "GL_EXT_frag_depth"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, + { "EXT_shader_texture_lod"_string, { { "GL_EXT_shader_texture_lod"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, + { "EXT_texture_filter_anisotropic"_string, { { "GL_EXT_texture_filter_anisotropic"sv }, EXTTextureFilterAnisotropic::create } }, + { "OES_element_index_uint"_string, { { "GL_OES_element_index_uint"sv }, OESElementIndexUint::create, OpenGLContext::WebGLVersion::WebGL1 } }, + { "OES_standard_derivatives"_string, { { "GL_OES_standard_derivatives"sv }, OESStandardDerivatives::create, OpenGLContext::WebGLVersion::WebGL1 } }, + { "OES_texture_float"_string, { { "GL_OES_texture_float"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, + { "OES_texture_float_linear"_string, { { "GL_OES_texture_float_linear"sv }, nullptr } }, + { "OES_texture_half_float"_string, { { "GL_OES_texture_half_float"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, + { "OES_texture_half_float_linear"_string, { { "GL_OES_texture_half_float_linear"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, + { "OES_vertex_array_object"_string, { { "GL_OES_vertex_array_object"sv }, OESVertexArrayObject::create, OpenGLContext::WebGLVersion::WebGL1 } }, + { "WEBGL_compressed_texture_s3tc"_string, { { "GL_EXT_texture_compression_dxt1"sv, "GL_ANGLE_texture_compression_dxt3"sv, "GL_ANGLE_texture_compression_dxt5"sv }, WebGLCompressedTextureS3tc::create } }, + { "WEBGL_debug_renderer_info"_string, { {}, WebGLDebugRendererInfo::create } }, + { "WEBGL_debug_shaders"_string, { {}, nullptr } }, + { "WEBGL_depth_texture"_string, { { "GL_ANGLE_depth_texture"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, + { "WEBGL_draw_buffers"_string, { { "GL_EXT_draw_buffers"sv }, WebGLDrawBuffers::create, OpenGLContext::WebGLVersion::WebGL1 } }, + { "WEBGL_lose_context"_string, { {}, nullptr } }, - // Community approved WebGL Extensions - { "EXT_clip_control"_string, { { "GL_EXT_clip_control"sv }, nullptr } }, - { "EXT_color_buffer_float"_string, { { "GL_EXT_color_buffer_float"sv }, EXTColorBufferFloat::create, OpenGLContext::WebGLVersion::WebGL2 } }, - { "EXT_color_buffer_half_float"_string, { { "GL_EXT_color_buffer_half_float"sv }, nullptr } }, - { "EXT_conservative_depth"_string, { { "GL_EXT_conservative_depth"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, - { "EXT_depth_clamp"_string, { { "GL_EXT_depth_clamp"sv }, nullptr } }, - { "EXT_disjoint_timer_query"_string, { { "GL_EXT_disjoint_timer_query"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, - { "EXT_disjoint_timer_query_webgl2"_string, { { "GL_EXT_disjoint_timer_query"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, - { "EXT_float_blend"_string, { { "GL_EXT_float_blend"sv }, nullptr } }, - { "EXT_polygon_offset_clamp"_string, { { "GL_EXT_polygon_offset_clamp"sv }, nullptr } }, - { "EXT_render_snorm"_string, { { "GL_EXT_render_snorm"sv }, EXTRenderSnorm::create, OpenGLContext::WebGLVersion::WebGL2 } }, - { "EXT_sRGB"_string, { { "GL_EXT_sRGB"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, - { "EXT_texture_compression_bptc"_string, { { "GL_EXT_texture_compression_bptc"sv }, nullptr } }, - { "EXT_texture_compression_rgtc"_string, { { "GL_EXT_texture_compression_rgtc"sv }, nullptr } }, - { "EXT_texture_mirror_clamp_to_edge"_string, { { "GL_EXT_texture_mirror_clamp_to_edge"sv }, nullptr } }, - { "EXT_texture_norm16"_string, { { "GL_EXT_texture_norm16"sv }, EXTTextureNorm16::create, OpenGLContext::WebGLVersion::WebGL2 } }, - { "KHR_parallel_shader_compile"_string, { { "GL_KHR_parallel_shader_compile"sv }, nullptr } }, - { "NV_shader_noperspective_interpolation"_string, { { "GL_NV_shader_noperspective_interpolation"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, - { "OES_draw_buffers_indexed"_string, { { "GL_OES_draw_buffers_indexed"sv }, nullptr } }, - { "OES_fbo_render_mipmap"_string, { { "GL_OES_fbo_render_mipmap"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, - { "OES_sample_variables"_string, { { "GL_OES_sample_variables"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, - { "OES_shader_multisample_interpolation"_string, { { "GL_OES_shader_multisample_interpolation"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, - { "OVR_multiview2"_string, { { "GL_OVR_multiview2"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, - { "WEBGL_blend_func_extended"_string, { { "GL_EXT_blend_func_extended"sv }, nullptr } }, - { "WEBGL_clip_cull_distance"_string, { { "GL_EXT_clip_cull_distance"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, - { "WEBGL_color_buffer_float"_string, { { "EXT_color_buffer_half_float"sv, "OES_texture_float"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, - { "WEBGL_compressed_texture_astc"_string, { { "KHR_texture_compression_astc_hdr"sv, "KHR_texture_compression_astc_ldr"sv }, nullptr } }, - { "WEBGL_compressed_texture_etc"_string, { { "GL_ANGLE_compressed_texture_etc"sv }, nullptr } }, - { "WEBGL_compressed_texture_etc1"_string, { { "GL_OES_compressed_ETC1_RGB8_texture"sv }, nullptr } }, - { "WEBGL_compressed_texture_pvrtc"_string, { { "GL_IMG_texture_compression_pvrtc"sv }, nullptr } }, - { "WEBGL_compressed_texture_s3tc_srgb"_string, { { "GL_EXT_texture_compression_s3tc_srgb"sv }, WebGLCompressedTextureS3tcSrgb::create } }, - { "WEBGL_multi_draw"_string, { { "GL_ANGLE_multi_draw"sv }, nullptr } }, - { "WEBGL_polygon_mode"_string, { { "GL_ANGLE_polygon_mode"sv }, nullptr } }, - { "WEBGL_provoking_vertex"_string, { { "GL_ANGLE_provoking_vertex"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, - { "WEBGL_render_shared_exponent"_string, { { "GL_QCOM_render_shared_exponent"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, - { "WEBGL_stencil_texturing"_string, { { "GL_ANGLE_stencil_texturing"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, -}; + // Community approved WebGL Extensions + { "EXT_clip_control"_string, { { "GL_EXT_clip_control"sv }, nullptr } }, + { "EXT_color_buffer_float"_string, { { "GL_EXT_color_buffer_float"sv }, EXTColorBufferFloat::create, OpenGLContext::WebGLVersion::WebGL2 } }, + { "EXT_color_buffer_half_float"_string, { { "GL_EXT_color_buffer_half_float"sv }, nullptr } }, + { "EXT_conservative_depth"_string, { { "GL_EXT_conservative_depth"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, + { "EXT_depth_clamp"_string, { { "GL_EXT_depth_clamp"sv }, nullptr } }, + { "EXT_disjoint_timer_query"_string, { { "GL_EXT_disjoint_timer_query"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, + { "EXT_disjoint_timer_query_webgl2"_string, { { "GL_EXT_disjoint_timer_query"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, + { "EXT_float_blend"_string, { { "GL_EXT_float_blend"sv }, nullptr } }, + { "EXT_polygon_offset_clamp"_string, { { "GL_EXT_polygon_offset_clamp"sv }, nullptr } }, + { "EXT_render_snorm"_string, { { "GL_EXT_render_snorm"sv }, EXTRenderSnorm::create, OpenGLContext::WebGLVersion::WebGL2 } }, + { "EXT_sRGB"_string, { { "GL_EXT_sRGB"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, + { "EXT_texture_compression_bptc"_string, { { "GL_EXT_texture_compression_bptc"sv }, nullptr } }, + { "EXT_texture_compression_rgtc"_string, { { "GL_EXT_texture_compression_rgtc"sv }, nullptr } }, + { "EXT_texture_mirror_clamp_to_edge"_string, { { "GL_EXT_texture_mirror_clamp_to_edge"sv }, nullptr } }, + { "EXT_texture_norm16"_string, { { "GL_EXT_texture_norm16"sv }, EXTTextureNorm16::create, OpenGLContext::WebGLVersion::WebGL2 } }, + { "KHR_parallel_shader_compile"_string, { { "GL_KHR_parallel_shader_compile"sv }, nullptr } }, + { "NV_shader_noperspective_interpolation"_string, { { "GL_NV_shader_noperspective_interpolation"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, + { "OES_draw_buffers_indexed"_string, { { "GL_OES_draw_buffers_indexed"sv }, nullptr } }, + { "OES_fbo_render_mipmap"_string, { { "GL_OES_fbo_render_mipmap"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, + { "OES_sample_variables"_string, { { "GL_OES_sample_variables"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, + { "OES_shader_multisample_interpolation"_string, { { "GL_OES_shader_multisample_interpolation"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, + { "OVR_multiview2"_string, { { "GL_OVR_multiview2"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, + { "WEBGL_blend_func_extended"_string, { { "GL_EXT_blend_func_extended"sv }, nullptr } }, + { "WEBGL_clip_cull_distance"_string, { { "GL_EXT_clip_cull_distance"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, + { "WEBGL_color_buffer_float"_string, { { "EXT_color_buffer_half_float"sv, "OES_texture_float"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL1 } }, + { "WEBGL_compressed_texture_astc"_string, { { "KHR_texture_compression_astc_hdr"sv, "KHR_texture_compression_astc_ldr"sv }, nullptr } }, + { "WEBGL_compressed_texture_etc"_string, { { "GL_ANGLE_compressed_texture_etc"sv }, nullptr } }, + { "WEBGL_compressed_texture_etc1"_string, { { "GL_OES_compressed_ETC1_RGB8_texture"sv }, nullptr } }, + { "WEBGL_compressed_texture_pvrtc"_string, { { "GL_IMG_texture_compression_pvrtc"sv }, nullptr } }, + { "WEBGL_compressed_texture_s3tc_srgb"_string, { { "GL_EXT_texture_compression_s3tc_srgb"sv }, WebGLCompressedTextureS3tcSrgb::create } }, + { "WEBGL_multi_draw"_string, { { "GL_ANGLE_multi_draw"sv }, nullptr } }, + { "WEBGL_polygon_mode"_string, { { "GL_ANGLE_polygon_mode"sv }, nullptr } }, + { "WEBGL_provoking_vertex"_string, { { "GL_ANGLE_provoking_vertex"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, + { "WEBGL_render_shared_exponent"_string, { { "GL_QCOM_render_shared_exponent"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, + { "WEBGL_stencil_texturing"_string, { { "GL_ANGLE_stencil_texturing"sv }, nullptr, OpenGLContext::WebGLVersion::WebGL2 } }, + }; + return extensions; +} Optional> WebGLRenderingContextBase::get_supported_extensions() { auto opengl_extensions = context().get_supported_opengl_extensions(); Vector webgl_extensions; - for (auto const& [available_extension_name, available_extension_info] : s_available_webgl_extensions) { + for (auto const& [available_extension_name, available_extension_info] : available_webgl_extensions()) { bool supported = !available_extension_info.only_for_webgl_version.has_value() || context().webgl_version() == available_extension_info.only_for_webgl_version; @@ -219,7 +223,7 @@ JS::Object* WebGLRenderingContextBase::get_extension(String const& name) return maybe_extension.release_value(); // If we pass the check above this will always return a value - auto const& extension_info = s_available_webgl_extensions.get(name).release_value(); + auto const& extension_info = available_webgl_extensions().get(name).release_value(); if (!extension_info.factory) return nullptr; diff --git a/Libraries/LibWeb/WebIDL/ExceptionOr.h b/Libraries/LibWeb/WebIDL/ExceptionOr.h index 7a73cb28fe..1fb9c3a4cc 100644 --- a/Libraries/LibWeb/WebIDL/ExceptionOr.h +++ b/Libraries/LibWeb/WebIDL/ExceptionOr.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -176,10 +177,10 @@ struct Formatter : Formatter { auto value = completion.value(); if (auto object = value.template as_if()) { - static JS::PropertyKey const message_property_key { "message"_utf16_fly_string }; - auto has_message_or_error = object->has_own_property(message_property_key); + static NeverDestroyed message_property_key { "message"_utf16_fly_string }; + auto has_message_or_error = object->has_own_property(*message_property_key); if (!has_message_or_error.is_error() && has_message_or_error.value()) { - auto message_object = object->get_without_side_effects(message_property_key); + auto message_object = object->get_without_side_effects(*message_property_key); return Formatter::format(builder, message_object.to_string_without_side_effects()); } } diff --git a/Libraries/LibWeb/XHR/EventNames.cpp b/Libraries/LibWeb/XHR/EventNames.cpp index da1b091bdc..f1a5665ca8 100644 --- a/Libraries/LibWeb/XHR/EventNames.cpp +++ b/Libraries/LibWeb/XHR/EventNames.cpp @@ -9,7 +9,7 @@ namespace Web::XHR::EventNames { #define __ENUMERATE_XHR_EVENT(name) \ - FlyString name = #name##_fly_string; + FlyString const& name = *new FlyString(#name##_fly_string); ENUMERATE_XHR_EVENTS #undef __ENUMERATE_XHR_EVENT diff --git a/Libraries/LibWeb/XHR/EventNames.h b/Libraries/LibWeb/XHR/EventNames.h index 5ef02af7b5..f0cab9220c 100644 --- a/Libraries/LibWeb/XHR/EventNames.h +++ b/Libraries/LibWeb/XHR/EventNames.h @@ -20,7 +20,7 @@ namespace Web::XHR::EventNames { __ENUMERATE_XHR_EVENT(readystatechange) \ __ENUMERATE_XHR_EVENT(timeout) -#define __ENUMERATE_XHR_EVENT(name) extern FlyString name; +#define __ENUMERATE_XHR_EVENT(name) extern FlyString const& name; ENUMERATE_XHR_EVENTS #undef __ENUMERATE_XHR_EVENT diff --git a/Libraries/LibWebView/BrowserProcess.cpp b/Libraries/LibWebView/BrowserProcess.cpp index 5c03999d85..c5fd1c4617 100644 --- a/Libraries/LibWebView/BrowserProcess.cpp +++ b/Libraries/LibWebView/BrowserProcess.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -20,7 +21,11 @@ namespace WebView { -static HashMap> s_connections; +static HashMap>& connections() +{ + static NeverDestroyed>> connections; + return *connections; +} class UIProcessClient final : public IPC::ConnectionToServer { @@ -172,12 +177,12 @@ UIProcessClient::UIProcessClient(NonnullOwnPtr transport) UIProcessConnectionFromClient::UIProcessConnectionFromClient(NonnullOwnPtr transport, int client_id) : IPC::ConnectionFromClient(*this, move(transport), client_id) { - s_connections.set(client_id, *this); + connections().set(client_id, *this); } void UIProcessConnectionFromClient::die() { - s_connections.remove(client_id()); + connections().remove(client_id()); } void UIProcessConnectionFromClient::create_new_tab(Vector urls) diff --git a/Libraries/LibWebView/SearchEngine.cpp b/Libraries/LibWebView/SearchEngine.cpp index 7f5d0d053d..141e28875c 100644 --- a/Libraries/LibWebView/SearchEngine.cpp +++ b/Libraries/LibWebView/SearchEngine.cpp @@ -9,7 +9,7 @@ namespace WebView { -static auto s_builtin_search_engines = to_array({ +static auto const& s_builtin_search_engines = *new auto(to_array({ { "Bing"_string, "https://www.bing.com/search?q=%s"_string }, { "Brave"_string, "https://search.brave.com/search?q=%s"_string }, { "DuckDuckGo"_string, "https://duckduckgo.com/?q=%s"_string }, @@ -20,7 +20,7 @@ static auto s_builtin_search_engines = to_array({ { "Startpage"_string, "https://startpage.com/search?q=%s"_string }, { "Yahoo"_string, "https://search.yahoo.com/search?p=%s"_string }, { "Yandex"_string, "https://yandex.com/search/?text=%s"_string }, -}); +})); ReadonlySpan builtin_search_engines() { diff --git a/Libraries/LibWebView/Settings.cpp b/Libraries/LibWebView/Settings.cpp index 174d7bcb4d..a7326f3556 100644 --- a/Libraries/LibWebView/Settings.cpp +++ b/Libraries/LibWebView/Settings.cpp @@ -69,7 +69,7 @@ static constexpr auto DNS_SETTINGS_KEY = "dnsSettings"sv; static constexpr auto CONFIG_VARIABLES_KEY = "configVariables"sv; -static Array(ConfigVariableID::Count)> const CONFIG_VARIABLE_DEFINITIONS { { +static auto const& CONFIG_VARIABLE_DEFINITIONS = *new Array(ConfigVariableID::Count)> { { { .id = ConfigVariableID::ShowWebContentProcessIDInTabTitle, .name = "debug.process.show_web_content_process_id"sv, diff --git a/Libraries/LibWebView/UserAgent.cpp b/Libraries/LibWebView/UserAgent.cpp index 087f99a1d2..b98594e2f9 100644 --- a/Libraries/LibWebView/UserAgent.cpp +++ b/Libraries/LibWebView/UserAgent.cpp @@ -8,7 +8,7 @@ namespace WebView { -OrderedHashMap const user_agents = { +OrderedHashMap const& user_agents = *new OrderedHashMap { { "Chrome Linux Desktop"sv, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"sv }, { "Chrome macOS Desktop"sv, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"sv }, { "Firefox Linux Desktop"sv, "Mozilla/5.0 (X11; Linux x86_64; rv:129.0) Gecko/20100101 Firefox/129.0"sv }, diff --git a/Libraries/LibWebView/UserAgent.h b/Libraries/LibWebView/UserAgent.h index 2dddd85f45..91d76aa67e 100644 --- a/Libraries/LibWebView/UserAgent.h +++ b/Libraries/LibWebView/UserAgent.h @@ -13,7 +13,7 @@ namespace WebView { -WEBVIEW_API extern OrderedHashMap const user_agents; +WEBVIEW_API extern OrderedHashMap const& user_agents; WEBVIEW_API Optional normalize_user_agent_name(StringView); diff --git a/Libraries/LibWebView/Utilities.cpp b/Libraries/LibWebView/Utilities.cpp index 2798e0301c..75703e570f 100644 --- a/Libraries/LibWebView/Utilities.cpp +++ b/Libraries/LibWebView/Utilities.cpp @@ -32,10 +32,10 @@ static constexpr auto libexec_path = STRINGIFY(LADYBIRD_LIBEXECDIR); static constexpr auto libexec_path = "libexec"sv; #endif -ByteString s_ladybird_resource_root; -static Optional s_ladybird_binary_path; +ByteString& s_ladybird_resource_root = *new ByteString; +static auto& s_ladybird_binary_path = *new Optional; -Optional s_mach_server_name; +Optional& s_mach_server_name = *new Optional; Optional mach_server_name() { diff --git a/Libraries/LibWebView/Utilities.h b/Libraries/LibWebView/Utilities.h index 089ef91a32..5162c0c032 100644 --- a/Libraries/LibWebView/Utilities.h +++ b/Libraries/LibWebView/Utilities.h @@ -21,7 +21,7 @@ WEBVIEW_API void platform_init(Optional ladybird_binary_path = {}); WEBVIEW_API void copy_default_config_files(StringView config_path); WEBVIEW_API ErrorOr> get_paths_for_helper_process(StringView process_name); -WEBVIEW_API extern ByteString s_ladybird_resource_root; +WEBVIEW_API extern ByteString& s_ladybird_resource_root; WEBVIEW_API Optional mach_server_name(); WEBVIEW_API void set_mach_server_name(ByteString name); WEBVIEW_API ByteString mach_server_name_for_process(StringView process_name, pid_t pid); diff --git a/Libraries/LibWebView/ViewImplementation.cpp b/Libraries/LibWebView/ViewImplementation.cpp index ffee106081..115a13dc03 100644 --- a/Libraries/LibWebView/ViewImplementation.cpp +++ b/Libraries/LibWebView/ViewImplementation.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -29,12 +30,16 @@ namespace WebView { -static HashMap s_all_views; +static HashMap& all_views() +{ + static NeverDestroyed> views; + return *views; +} static u64 s_view_count = 1; // This has to start at 1 for Firefox DevTools. void ViewImplementation::for_each_view(Function callback) { - for (auto& view : s_all_views) { + for (auto& view : all_views()) { if (callback(*view.value) == IterationDecision::Break) break; } @@ -42,7 +47,7 @@ void ViewImplementation::for_each_view(Function ViewImplementation::find_view_by_id(u64 id) { - if (auto view = s_all_views.get(id); view.has_value()) + if (auto view = all_views().get(id); view.has_value()) return *view.value(); return {}; } @@ -51,7 +56,7 @@ ViewImplementation::ViewImplementation() : m_document_cookie_version_buffer(Core::create_shared_version_buffer()) , m_view_id(s_view_count++) { - s_all_views.set(m_view_id, this); + all_views().set(m_view_id, this); initialize_context_menus(); @@ -73,7 +78,7 @@ ViewImplementation::ViewImplementation() ViewImplementation::~ViewImplementation() { - s_all_views.remove(m_view_id); + all_views().remove(m_view_id); if (m_client_state.client) m_client_state.client->unregister_view(m_client_state.page_index); @@ -1189,7 +1194,7 @@ void ViewImplementation::set_user_style_sheet(String const& source) void ViewImplementation::use_native_user_style_sheet() { - extern String native_stylesheet_source; + extern String const& native_stylesheet_source; set_user_style_sheet(native_stylesheet_source); } diff --git a/Libraries/LibWebView/WebContentClient.cpp b/Libraries/LibWebView/WebContentClient.cpp index fd6c3a6b70..652b2b49fb 100644 --- a/Libraries/LibWebView/WebContentClient.cpp +++ b/Libraries/LibWebView/WebContentClient.cpp @@ -28,7 +28,11 @@ namespace WebView { -HashTable WebContentClient::s_clients; +HashTable& WebContentClient::clients() +{ + static NeverDestroyed> clients; + return *clients; +} static constexpr auto detached_page_close_timeout_ms = 1000; static constexpr auto close_server_exit_timeout_ms = 5000; @@ -51,13 +55,13 @@ WebContentClient::WebContentClient(NonnullOwnPtr transport, u64 , m_initial_page_id(initial_page_id) { VERIFY(m_initial_page_id > 0); - s_clients.set(this); + clients().set(this); } WebContentClient::~WebContentClient() { WorkerProcessManager::the().remove_web_content_owner(*this); - s_clients.remove(this); + clients().remove(this); } Optional WebContentClient::client_for_compositor_context_id(Web::Compositor::CompositorContextId context_id) diff --git a/Libraries/LibWebView/WebContentClient.h b/Libraries/LibWebView/WebContentClient.h index becadc4eee..7e37e30078 100644 --- a/Libraries/LibWebView/WebContentClient.h +++ b/Libraries/LibWebView/WebContentClient.h @@ -51,7 +51,7 @@ public: template Callback> static void for_each_client(Callback callback); - static size_t client_count() { return s_clients.size(); } + static size_t client_count() { return clients().size(); } static Optional client_for_compositor_context_id(Web::Compositor::CompositorContextId); WebContentClient(NonnullOwnPtr, u64 initial_page_id); @@ -210,13 +210,13 @@ private: RefPtr m_web_ui; - static HashTable s_clients; + static HashTable& clients(); }; template Callback> void WebContentClient::for_each_client(Callback callback) { - for (auto& it : s_clients) { + for (auto& it : clients()) { if (callback(*it) == IterationDecision::Break) return; } diff --git a/Libraries/LibWebView/WebUI/VersionUI.cpp b/Libraries/LibWebView/WebUI/VersionUI.cpp index 87192a5027..0b30221835 100644 --- a/Libraries/LibWebView/WebUI/VersionUI.cpp +++ b/Libraries/LibWebView/WebUI/VersionUI.cpp @@ -22,12 +22,12 @@ void VersionUI::register_interfaces() void VersionUI::load_version_info() { - static auto browser_name = String::from_utf8_without_validation({ BROWSER_NAME, __builtin_strlen(BROWSER_NAME) }); - static auto browser_version = String::from_utf8_without_validation({ BROWSER_VERSION, __builtin_strlen(BROWSER_VERSION) }); - static auto arch = String::from_utf8_without_validation({ CPU_STRING, __builtin_strlen(CPU_STRING) }); - static auto platform_name = String::from_utf8_without_validation({ OS_STRING, __builtin_strlen(OS_STRING) }); - static auto command_line = MUST(String::join(' ', Application::the().command_line_arguments().strings)); - static auto executable_path = MUST(String::from_byte_string(MUST(Core::System::current_executable_path()))); + static auto& browser_name = *new String(String::from_utf8_without_validation({ BROWSER_NAME, __builtin_strlen(BROWSER_NAME) })); + static auto& browser_version = *new String(String::from_utf8_without_validation({ BROWSER_VERSION, __builtin_strlen(BROWSER_VERSION) })); + static auto& arch = *new String(String::from_utf8_without_validation({ CPU_STRING, __builtin_strlen(CPU_STRING) })); + static auto& platform_name = *new String(String::from_utf8_without_validation({ OS_STRING, __builtin_strlen(OS_STRING) })); + static auto& command_line = *new String(MUST(String::join(' ', Application::the().command_line_arguments().strings))); + static auto& executable_path = *new String(MUST(String::from_byte_string(MUST(Core::System::current_executable_path())))); JsonObject version_info; version_info.set("browserName"_string, browser_name); diff --git a/Libraries/LibWebView/WorkerProcessManager.cpp b/Libraries/LibWebView/WorkerProcessManager.cpp index d0d9daba79..5672fb2fda 100644 --- a/Libraries/LibWebView/WorkerProcessManager.cpp +++ b/Libraries/LibWebView/WorkerProcessManager.cpp @@ -16,7 +16,7 @@ namespace WebView { WorkerProcessManager& WorkerProcessManager::the() { - static WorkerProcessManager manager; + static auto& manager = *new WorkerProcessManager; return manager; } diff --git a/Meta/CMake/targets.cmake b/Meta/CMake/targets.cmake index f7495ba210..081896c0d8 100644 --- a/Meta/CMake/targets.cmake +++ b/Meta/CMake/targets.cmake @@ -101,6 +101,9 @@ function(ladybird_lib name fs_name) ) target_link_libraries(${name} PRIVATE ${LIBS}) target_link_libraries(${name} PUBLIC GenericClangPlugin) + if ((APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID)) + target_compile_options(${name} PRIVATE $<$:-Wexit-time-destructors>) + endif() if (NOT "${name}" STREQUAL "AK") target_link_libraries(${name} PRIVATE AK) diff --git a/Meta/Generators/embed_as_string.py b/Meta/Generators/embed_as_string.py index 8908e15978..5db4dc79fc 100644 --- a/Meta/Generators/embed_as_string.py +++ b/Meta/Generators/embed_as_string.py @@ -19,12 +19,12 @@ def main(): f.write("#include \n") if args.namespace: f.write(f"namespace {args.namespace} {{\n") - f.write(f"extern String {args.variable_name};\n") - f.write(f'String {args.variable_name} = R"~~~(') + f.write(f"extern String const& {args.variable_name};\n") + f.write(f'String const& {args.variable_name} = *new String(R"~~~(') with open(args.input, "r", encoding="utf-8") as input: for line in input.readlines(): f.write(f"{line}") - f.write(')~~~"_string;\n') + f.write(')~~~"_string);\n') if args.namespace: f.write("}\n") diff --git a/Meta/Generators/generate_dom_tree.py b/Meta/Generators/generate_dom_tree.py index c2232a53f2..4cdcad5b23 100644 --- a/Meta/Generators/generate_dom_tree.py +++ b/Meta/Generators/generate_dom_tree.py @@ -366,9 +366,9 @@ def generate( # Static stylesheet sources for source_var, css_content in parser.stylesheet_sources: - impl_lines.append(f'static String {source_var} = R"~~~(') + impl_lines.append(f'static String const& {source_var} = *new String(R"~~~(') impl_lines.append(css_content.strip()) - impl_lines.append(')~~~"_string;') + impl_lines.append(')~~~"_string);') impl_lines.append("") # Constructor diff --git a/Meta/Generators/generate_libweb_aria_roles.py b/Meta/Generators/generate_libweb_aria_roles.py index 150f332f1c..74be72b47e 100644 --- a/Meta/Generators/generate_libweb_aria_roles.py +++ b/Meta/Generators/generate_libweb_aria_roles.py @@ -148,8 +148,8 @@ def generate_hash_table_member( out.write(f""" HashTable<{enum_class}> const& {name}::{member_name}() const {{ - static HashTable<{enum_class}> {hash_table_name}; - return {hash_table_name}; + static NeverDestroyed> {hash_table_name}; + return *{hash_table_name}; }} """) return @@ -157,21 +157,22 @@ HashTable<{enum_class}> const& {name}::{member_name}() const out.write(f""" HashTable<{enum_class}> const& {name}::{member_name}() const {{ - static HashTable<{enum_class}> {hash_table_name}; - if ({hash_table_name}.is_empty()) {{ - {hash_table_name}.ensure_capacity({len(values)}); + static NeverDestroyed> {hash_table_name}; + if ({hash_table_name}->is_empty()) {{ + {hash_table_name}->ensure_capacity({len(values)}); """) for v in values: - out.write(f" {hash_table_name}.set({enum_class}::{v});\n") + out.write(f" {hash_table_name}->set({enum_class}::{v});\n") out.write(f""" }} - return {hash_table_name}; + return *{hash_table_name}; }} """) def write_implementation_file(out: TextIO, roles_data: dict) -> None: out.write(""" +#include #include namespace Web::ARIA { diff --git a/Meta/Generators/generate_libweb_css_descriptors.py b/Meta/Generators/generate_libweb_css_descriptors.py index 241816eef7..a8268bfcb2 100644 --- a/Meta/Generators/generate_libweb_css_descriptors.py +++ b/Meta/Generators/generate_libweb_css_descriptors.py @@ -162,6 +162,7 @@ def write_implementation_file(out: TextIO, at_rules_data: dict, all_descriptors: descriptor_count = len(all_descriptors) out.write(""" +#include #include #include #include @@ -277,8 +278,8 @@ RefPtr descriptor_initial_value(AtRuleID at_rule_id, Descripto if (!at_rule_supports_descriptor(at_rule_id, descriptor_id)) return nullptr; - static Array, {descriptor_count}>, {at_rule_count}> initial_values; - if (auto initial_value = initial_values[to_underlying(at_rule_id)][to_underlying(descriptor_id)]) + static NeverDestroyed, {descriptor_count}>, {at_rule_count}>> initial_values; + if (auto initial_value = (*initial_values)[to_underlying(at_rule_id)][to_underlying(descriptor_id)]) return initial_value.release_nonnull(); // Lazily parse initial values as needed. @@ -306,7 +307,7 @@ RefPtr descriptor_initial_value(AtRuleID at_rule_id, Descripto auto parsed_value = parse_css_descriptor(parsing_params, AtRuleID::{at_rule_titlecase}, DescriptorNameAndID::from_id(DescriptorID::{descriptor_titlecase}), "{initial_value}"sv); VERIFY(!parsed_value.is_null()); auto initial_value = parsed_value.release_nonnull(); - initial_values[to_underlying(at_rule_id)][to_underlying(descriptor_id)] = initial_value; + (*initial_values)[to_underlying(at_rule_id)][to_underlying(descriptor_id)] = initial_value; return initial_value; }} """) diff --git a/Meta/Generators/generate_libweb_css_keyword.py b/Meta/Generators/generate_libweb_css_keyword.py index 197888169e..f442aeef39 100644 --- a/Meta/Generators/generate_libweb_css_keyword.py +++ b/Meta/Generators/generate_libweb_css_keyword.py @@ -71,11 +71,14 @@ def write_implementation_file(out: TextIO, keyword_data: list) -> None: out.write(""" #include #include +#include #include namespace Web::CSS { -HashMap g_stringview_to_keyword_map { +static HashMap const& stringview_to_keyword_map() +{ + static auto const& map = *new HashMap { """) for name in keyword_data: @@ -84,11 +87,13 @@ HashMap g_stringv """) out.write(""" -}; + }; + return map; +} Optional keyword_from_string(StringView string) { - return g_stringview_to_keyword_map.get(string); + return stringview_to_keyword_map().get(string); } StringView string_from_keyword(Keyword keyword) { diff --git a/Meta/Generators/generate_libweb_css_property_id.py b/Meta/Generators/generate_libweb_css_property_id.py index 0a891a553c..cc18af95ab 100644 --- a/Meta/Generators/generate_libweb_css_property_id.py +++ b/Meta/Generators/generate_libweb_css_property_id.py @@ -351,6 +351,7 @@ struct Formatter : Formatter { def write_implementation_file(out: TextIO, properties: dict, logical_property_groups: dict, enum_names: list) -> None: out.write(""" #include +#include #include #include #include @@ -378,7 +379,7 @@ static auto generate_camel_case_property_table() return table; } -static HashMap const camel_case_properties_table = generate_camel_case_property_table(); +static auto const& camel_case_properties_table = *new HashMap(generate_camel_case_property_table()); Optional property_id_from_camel_case_string(StringView string) { @@ -401,7 +402,7 @@ static auto generate_properties_table() return table; } -static HashMap const properties_table = generate_properties_table(); +static auto const& properties_table = *new HashMap(generate_properties_table()); Optional property_id_from_string(StringView string) { @@ -420,14 +421,14 @@ FlyString const& string_from_property_id(PropertyID property_id) { continue out.write(f""" case PropertyID::{title_casify(name)}: {{ - static FlyString name = "{name}"_fly_string; + static FlyString const& name = *new FlyString("{name}"_fly_string); return name; }} """) out.write(""" default: { - static FlyString invalid_property_id_string = "(invalid CSS::PropertyID)"_fly_string; + static FlyString const& invalid_property_id_string = *new FlyString("(invalid CSS::PropertyID)"_fly_string); return invalid_property_id_string; } } @@ -442,14 +443,14 @@ FlyString const& camel_case_string_from_property_id(PropertyID property_id) { continue out.write(f""" case PropertyID::{title_casify(name)}: {{ - static FlyString name = "{camel_casify(name)}"_fly_string; + static FlyString const& name = *new FlyString("{camel_casify(name)}"_fly_string); return name; }} """) out.write(""" default: { - static FlyString invalid_property_id_string = "(invalid CSS::PropertyID)"_fly_string; + static FlyString const& invalid_property_id_string = *new FlyString("(invalid CSS::PropertyID)"_fly_string); return invalid_property_id_string; } } @@ -604,8 +605,8 @@ bool property_needs_layout_node_for_resolved_value(PropertyID property_id) NonnullRefPtr property_initial_value(PropertyID property_id) { - static Array, to_underlying(last_property_id) + 1> initial_values; - if (auto initial_value = initial_values[to_underlying(property_id)]) + static NeverDestroyed, to_underlying(last_property_id) + 1>> initial_values; + if (auto initial_value = (*initial_values)[to_underlying(property_id)]) return initial_value.release_nonnull(); // Lazily parse initial values as needed. @@ -629,7 +630,7 @@ NonnullRefPtr property_initial_value(PropertyID property_id) auto parsed_value = parse_css_value(parsing_params, "{initial_value_string}"sv, PropertyID::{title}); VERIFY(!parsed_value.is_null()); auto initial_value = parsed_value.release_nonnull(); - initial_values[to_underlying(PropertyID::{title})] = initial_value; + (*initial_values)[to_underlying(PropertyID::{title})] = initial_value; return initial_value; }} """) @@ -1018,13 +1019,13 @@ Vector const& longhands_for_shorthand(PropertyID property_id) longhands = ", ".join(f"PropertyID::{title_casify(lh)}" for lh in get_longhands(name)) out.write(f""" case PropertyID::{title_casify(name)}: {{ - static Vector longhands = {{ {longhands} }}; + static auto const& longhands = *new Vector {{ {longhands} }}; return longhands; }}""") out.write(""" default: - static Vector empty_longhands; + static auto const& empty_longhands = *new Vector; return empty_longhands; } } @@ -1051,13 +1052,13 @@ Vector const& expanded_longhands_for_shorthand(PropertyID property_i longhands = ", ".join(f"PropertyID::{title_casify(lh)}" for lh in get_expanded_longhands(name)) out.write(f""" case PropertyID::{title_casify(name)}: {{ - static Vector longhands = {{ {longhands} }}; + static auto const& longhands = *new Vector {{ {longhands} }}; return longhands; }}""") out.write(""" default: { - static Vector empty_longhands; + static auto const& empty_longhands = *new Vector; return empty_longhands; } } @@ -1131,13 +1132,13 @@ Vector const& shorthands_for_longhand(PropertyID property_id) shorthands = ", ".join(f"PropertyID::{title_casify(s)}" for s in get_shorthands_for_longhand(longhand)) out.write(f""" case PropertyID::{title_casify(longhand)}: {{ - static Vector shorthands = {{ {shorthands} }}; + static auto const& shorthands = *new Vector {{ {shorthands} }}; return shorthands; }}""") out.write(""" default: { - static Vector empty_shorthands; + static auto const& empty_shorthands = *new Vector; return empty_shorthands; } } @@ -1178,7 +1179,7 @@ Vector const& shorthands_for_longhand(PropertyID property_id) out.write(""" Vector const& property_computation_order() { - static Vector order = { + static auto const& order = *new Vector { """) for property_name in manually_specified_computation_order: out.write(f" PropertyID::{property_name},\n") diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index b52eb020f9..6055a59de9 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -3262,7 +3262,7 @@ static void generate_html_constructor(SourceGenerator& generator, IDL::Construct // 8. Otherwise (i.e., if definition is for a customized built-in element): else { // 1. Let valid local names be the list of local names for elements defined in this specification or in other applicable specifications that use the active function object as their element interface. - static auto valid_local_names = MUST(DOM::valid_local_names_for_given_html_element_interface("@name@"sv)); + static auto const& valid_local_names = *new auto(MUST(DOM::valid_local_names_for_given_html_element_interface("@name@"sv))); // 2. If valid local names does not contain definition's local name, then throw a TypeError. if (!valid_local_names.contains_slow(definition->local_name())) @@ -5053,7 +5053,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@) // 2. Run this's delete the content attribute. // 3. Return. attribute_generator.append(R"~~~( - static auto content_attribute = "@attribute.reflect_name@"_fly_string; + static auto const& content_attribute = *new FlyString("@attribute.reflect_name@"_fly_string); if (!cpp_value) { impl->set_@attribute.cpp_name@({}); @@ -5079,7 +5079,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@) // 2. Run this's delete the content attribute. // 3. Return. attribute_generator.append(R"~~~( - static auto content_attribute = "@attribute.reflect_name@"_fly_string; + static auto const& content_attribute = *new FlyString("@attribute.reflect_name@"_fly_string); if (!cpp_value.has_value()) { impl->set_@attribute.cpp_name@({}); @@ -5532,7 +5532,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.getter_callback@) else if (attribute.type->is_nullable() && attribute.type->name() == "Element") { // The getter steps are to return the result of running this's get the attr-associated element. attribute_generator.append(R"~~~( - static auto content_attribute = "@attribute.reflect_name@"_fly_string; + static auto const& content_attribute = *new FlyString("@attribute.reflect_name@"_fly_string); auto retval = impl->get_the_attribute_associated_element(content_attribute, TRY(throw_dom_exception_if_needed(vm, [&] { return impl->@attribute.cpp_name@(); }))); )~~~"); @@ -5545,7 +5545,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.getter_callback@) // 1. Let elements be the result of running this's get the attr-associated elements. attribute_generator.append(R"~~~( - static auto content_attribute = "@attribute.reflect_name@"_fly_string; + static auto const& content_attribute = *new FlyString("@attribute.reflect_name@"_fly_string); auto retval = impl->get_the_attribute_associated_elements(content_attribute, TRY(throw_dom_exception_if_needed(vm, [&] { return impl->@attribute.cpp_name@(); }))); )~~~");