ladybird/Libraries/LibWeb/WebAssembly/Instance.cpp
Konstantin Konstantin b03138cbff
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
LibWeb: Support creation of shared memory in WebAssembly API
Add support for shared memory creation in WebAssembly memory API.
This API is needed for WPT tests that use shared array buffers.

Import related WPT tests.
2024-12-08 22:10:45 +01:00

94 lines
3.4 KiB
C++

/*
* Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/FunctionObject.h>
#include <LibJS/Runtime/NativeFunction.h>
#include <LibJS/Runtime/Realm.h>
#include <LibJS/Runtime/VM.h>
#include <LibWeb/Bindings/InstancePrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/WebAssembly/Instance.h>
#include <LibWeb/WebAssembly/Memory.h>
#include <LibWeb/WebAssembly/Module.h>
#include <LibWeb/WebAssembly/Table.h>
#include <LibWeb/WebAssembly/WebAssembly.h>
namespace Web::WebAssembly {
GC_DEFINE_ALLOCATOR(Instance);
WebIDL::ExceptionOr<GC::Ref<Instance>> Instance::construct_impl(JS::Realm& realm, Module& module, Optional<GC::Root<JS::Object>>& import_object_handle)
{
GC::Ptr<JS::Object> import_object = import_object_handle.has_value() ? import_object_handle.value().ptr() : nullptr;
auto& vm = realm.vm();
auto module_instance = TRY(Detail::instantiate_module(vm, module.compiled_module()->module, import_object));
return realm.create<Instance>(realm, move(module_instance));
}
Instance::Instance(JS::Realm& realm, NonnullOwnPtr<Wasm::ModuleInstance> module_instance)
: Bindings::PlatformObject(realm)
, m_exports(Object::create(realm, nullptr))
, m_module_instance(move(module_instance))
{
}
void Instance::initialize(JS::Realm& realm)
{
auto& vm = this->vm();
Base::initialize(realm);
WEB_SET_PROTOTYPE_FOR_INTERFACE_WITH_CUSTOM_NAME(Instance, WebAssembly.Instance);
for (auto& export_ : m_module_instance->exports()) {
export_.value().visit(
[&](Wasm::FunctionAddress const& address) {
Optional<GC::Ptr<JS::FunctionObject>> object = m_function_instances.get(address);
if (!object.has_value()) {
object = Detail::create_native_function(vm, address, export_.name(), this);
m_function_instances.set(address, *object);
}
m_exports->define_direct_property(export_.name(), *object, JS::default_attributes);
},
[&](Wasm::MemoryAddress const& address) {
Optional<GC::Ptr<Memory>> object = m_memory_instances.get(address);
if (!object.has_value()) {
object = realm.create<Memory>(realm, address, Memory::Shared::No);
m_memory_instances.set(address, *object);
}
m_exports->define_direct_property(export_.name(), *object, JS::default_attributes);
},
[&](Wasm::TableAddress const& address) {
Optional<GC::Ptr<Table>> object = m_table_instances.get(address);
if (!object.has_value()) {
object = realm.create<Table>(realm, address);
m_table_instances.set(address, *object);
}
m_exports->define_direct_property(export_.name(), *object, JS::default_attributes);
},
[&](auto const&) {
// FIXME: Implement other exports!
});
}
MUST(m_exports->set_integrity_level(IntegrityLevel::Frozen));
}
void Instance::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_exports);
visitor.visit(m_function_instances);
visitor.visit(m_memory_instances);
visitor.visit(m_table_instances);
}
}