From 1fa528b19fb4551ebc6b4d33b408e456ba367acc Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Wed, 31 Jul 2024 12:34:55 +0200 Subject: [PATCH] LibWeb: Keep Wasm-imported functions alive The user is not required to keep the object alive, this commit makes it so the lifetime of these functions is extended to match the Wasm module it is imported into. Fixes the crash in #907. --- Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp | 2 ++ Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp index bd52bb34e32..ca0e969011d 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp @@ -45,6 +45,7 @@ void visit_edges(JS::Object& object, JS::Cell::Visitor& visitor) if (auto maybe_cache = Detail::s_caches.get(global_object); maybe_cache.has_value()) { auto& cache = maybe_cache.release_value(); visitor.visit(cache.function_instances()); + visitor.visit(cache.imported_objects()); } } @@ -186,6 +187,7 @@ JS::ThrowCompletionOr> instantiate_module(JS if (!import_.is_function()) return {}; auto& function = import_.as_function(); + cache.add_imported_object(function); // FIXME: If this is a function created by create_native_function(), // just extract its address and resolve to that. Wasm::HostFunction host_function { diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h index 3eab3a0f079..47782f9f031 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h @@ -41,15 +41,18 @@ class WebAssemblyCache { public: void add_compiled_module(NonnullRefPtr module) { m_compiled_modules.append(module); } void add_function_instance(Wasm::FunctionAddress address, JS::GCPtr function) { m_function_instances.set(address, function); } + void add_imported_object(JS::GCPtr object) { m_imported_objects.set(object); } Optional> get_function_instance(Wasm::FunctionAddress address) { return m_function_instances.get(address); } HashMap> function_instances() const { return m_function_instances; } + HashTable> imported_objects() const { return m_imported_objects; } Wasm::AbstractMachine& abstract_machine() { return m_abstract_machine; } private: HashMap> m_function_instances; Vector> m_compiled_modules; + HashTable> m_imported_objects; Wasm::AbstractMachine m_abstract_machine; };