diff --git a/Tests/LibWeb/Text/expected/Wasm/WebAssembly-instantiate.txt b/Tests/LibWeb/Text/expected/Wasm/WebAssembly-instantiate.txt index 2302b8b2238..c1b9d253546 100644 --- a/Tests/LibWeb/Text/expected/Wasm/WebAssembly-instantiate.txt +++ b/Tests/LibWeb/Text/expected/Wasm/WebAssembly-instantiate.txt @@ -2,15 +2,51 @@ ArrayBuffer ------------- Hello from wasm!!!!!! -FIXME: Run test for Uint8Array. Not running due to flakiness. -FIXME: Run test for Uint8ClampedArray. Not running due to flakiness. -FIXME: Run test for Uint16Array. Not running due to flakiness. -FIXME: Run test for Uint32Array. Not running due to flakiness. -FIXME: Run test for Int8Array. Not running due to flakiness. -FIXME: Run test for Int16Array. Not running due to flakiness. -FIXME: Run test for Float32Array. Not running due to flakiness. -FIXME: Run test for Float64Array. Not running due to flakiness. -FIXME: Run test for BigUint64Array. Not running due to flakiness. -FIXME: Run test for BigInt64Array. Not running due to flakiness. -FIXME: Run test for DataView. Not running due to flakiness. -FIXME: Run test for WebAssembly.Module. Not running due to flakiness. +------------- +Uint8Array +------------- +Hello from wasm!!!!!! +------------- +Uint8ClampedArray +------------- +Hello from wasm!!!!!! +------------- +Uint16Array +------------- +Hello from wasm!!!!!! +------------- +Uint32Array +------------- +Hello from wasm!!!!!! +------------- +Int8Array +------------- +Hello from wasm!!!!!! +------------- +Int16Array +------------- +Hello from wasm!!!!!! +------------- +Float32Array +------------- +Hello from wasm!!!!!! +------------- +Float64Array +------------- +Hello from wasm!!!!!! +------------- +BigUint64Array +------------- +Hello from wasm!!!!!! +------------- +BigInt64Array +------------- +Hello from wasm!!!!!! +------------- +DataView +------------- +Hello from wasm!!!!!! +------------- +WebAssembly.Module +------------- +Hello from wasm!!!!!! diff --git a/Tests/LibWeb/Text/input/Wasm/WebAssembly-instantiate.html b/Tests/LibWeb/Text/input/Wasm/WebAssembly-instantiate.html index 7015f87bb90..70a26d769d8 100644 --- a/Tests/LibWeb/Text/input/Wasm/WebAssembly-instantiate.html +++ b/Tests/LibWeb/Text/input/Wasm/WebAssembly-instantiate.html @@ -9,13 +9,8 @@ cachedTextDecoder.decode(); - let cachedUint8Memory0 = null; - function getUint8Memory0() { - if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { - cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); - } - return cachedUint8Memory0; + return new Uint8Array(wasm.memory.buffer); } function getStringFromWasm0(ptr, len) { @@ -58,24 +53,30 @@ ]).buffer; const BUFFER_SOURCES = [ - { constructor: Uint8Array, flaky: true }, - { constructor: Uint8ClampedArray, flaky: true }, - { constructor: Uint16Array, flaky: true }, - { constructor: Uint32Array, flaky: true }, - { constructor: Int8Array, flaky: true }, - { constructor: Int16Array, flaky: true }, - { constructor: Float32Array, flaky: true }, - { constructor: Float64Array, flaky: true }, - { constructor: BigUint64Array, flaky: true }, - { constructor: BigInt64Array, flaky: true }, - { constructor: DataView, flaky: true }, + { constructor: Uint8Array}, + { constructor: Uint8ClampedArray }, + { constructor: Uint16Array }, + { constructor: Uint32Array }, + { constructor: Int8Array }, + { constructor: Int16Array }, + { constructor: Float32Array }, + { constructor: Float64Array }, + { constructor: BigUint64Array }, + { constructor: BigInt64Array }, + { constructor: DataView }, ]; - + async function runTest(buffer) { println("-------------") println(buffer.constructor.name); println("-------------") - const module = await WebAssembly.instantiate(buffer, exports); + const module = await WebAssembly.instantiate(buffer, exports).catch(e => { + println(`FIXME: Failed to instantiate with ${buffer.constructor.name}: ${e.name}: ${e.message}`); + return Promise.resolve(); + }); + if (!module) { + return Promise.resolve(); + } wasm = module.instance?.exports ?? module.exports; try { wasm.greet(); @@ -87,23 +88,16 @@ await runTest(arrayBuffer); - for (const { constructor, flaky } of BUFFER_SOURCES) { - if (!flaky) { - await runTest(new constructor(arrayBuffer)); - } else { - // The flakiness is the runtime either trapping with a RangeError, or the printed string being complete garbage, - // which more prominently happens with DataView and the arrays bigger than u8. However, the RangeError flake is - // still possible with u8. - println(`FIXME: Run test for ${constructor.name}. Not running due to flakiness.`); - } + for (const { constructor } of BUFFER_SOURCES) { + await runTest(new constructor(arrayBuffer)); } - if (false) { - const compiledModule = await WebAssembly.compile(arrayBuffer); + const compiledModule = await WebAssembly.compile(arrayBuffer).catch(() => { + println(`FIXME: Failed to compile with ArrayBuffer`); + return Promise.resolve() + }); + if (compiledModule) { await runTest(compiledModule); - } else { - // Same issues as above. - println(`FIXME: Run test for WebAssembly.Module. Not running due to flakiness.`); } done(); diff --git a/Userland/Libraries/LibWeb/WebAssembly/Instance.cpp b/Userland/Libraries/LibWeb/WebAssembly/Instance.cpp index 11bc256e871..c23756a9796 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/Instance.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/Instance.cpp @@ -21,14 +21,13 @@ namespace Web::WebAssembly { JS_DEFINE_ALLOCATOR(Instance); -WebIDL::ExceptionOr> Instance::construct_impl(JS::Realm& realm, Module& module, Optional>& import_object) +WebIDL::ExceptionOr> Instance::construct_impl(JS::Realm& realm, Module& module, Optional>& import_object_handle) { - // FIXME: Implement the importObject parameter. - (void)import_object; + JS::GCPtr 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)); + auto module_instance = TRY(Detail::instantiate_module(vm, module.compiled_module()->module, import_object)); return vm.heap().allocate(realm, realm, move(module_instance)); } diff --git a/Userland/Libraries/LibWeb/WebAssembly/Module.cpp b/Userland/Libraries/LibWeb/WebAssembly/Module.cpp index 086ed2f38f0..5e13d55c055 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/Module.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/Module.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace Web::WebAssembly { @@ -21,7 +22,14 @@ WebIDL::ExceptionOr> Module::construct_impl(JS::Realm& { auto& vm = realm.vm(); - auto compiled_module = TRY(Detail::parse_module(vm, bytes->raw_object())); + auto stable_bytes_or_error = WebIDL::get_buffer_source_copy(bytes->raw_object()); + if (stable_bytes_or_error.is_error()) { + VERIFY(stable_bytes_or_error.error().code() == ENOMEM); + return vm.throw_completion(vm.error_message(JS::VM::ErrorMessage::OutOfMemory)); + } + auto stable_bytes = stable_bytes_or_error.release_value(); + + auto compiled_module = TRY(Detail::compile_a_webassembly_module(vm, move(stable_bytes))); return vm.heap().allocate(realm, realm, move(compiled_module)); } diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp index 7e9047ec14e..ea73bda19a0 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp @@ -19,17 +19,23 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include namespace Web::WebAssembly { +static JS::NonnullGCPtr asynchronously_compile_webassembly_module(JS::VM&, ByteBuffer, HTML::Task::Source = HTML::Task::Source::Unspecified); +static JS::NonnullGCPtr instantiate_promise_of_module(JS::VM&, JS::NonnullGCPtr, JS::GCPtr import_object); +static JS::NonnullGCPtr asynchronously_instantiate_webassembly_module(JS::VM&, JS::NonnullGCPtr, JS::GCPtr import_object); + namespace Detail { HashMap, WebAssemblyCache> s_caches; @@ -62,21 +68,19 @@ void finalize(JS::Object& object) bool validate(JS::VM& vm, JS::Handle& bytes) { // 1. Let stableBytes be a copy of the bytes held by the buffer bytes. - // Note: There's no need to copy the bytes here as the buffer data cannot change while we're compiling the module. + auto stable_bytes = WebIDL::get_buffer_source_copy(*bytes->raw_object()); + if (stable_bytes.is_error()) { + VERIFY(stable_bytes.error().code() == ENOMEM); + return false; + } // 2. Compile stableBytes as a WebAssembly module and store the results as module. - auto module_or_error = Detail::parse_module(vm, bytes->raw_object()); + auto module_or_error = Detail::compile_a_webassembly_module(vm, stable_bytes.release_value()); // 3. If module is error, return false. if (module_or_error.is_error()) return false; - // 3 continued - our "compile" step is lazy with validation, explicitly do the validation. - auto compiled_module = module_or_error.release_value(); - auto& cache = Detail::get_cache(*vm.current_realm()); - if (cache.abstract_machine().validate(compiled_module->module).is_error()) - return false; - // 4. Return true. return true; } @@ -86,87 +90,54 @@ WebIDL::ExceptionOr> compile(JS::VM& vm, JS::H { auto& realm = *vm.current_realm(); - // FIXME: This shouldn't block! - auto compiled_module_or_error = Detail::parse_module(vm, bytes->raw_object()); - auto promise = WebIDL::create_promise(realm); - if (compiled_module_or_error.is_error()) { - WebIDL::reject_promise(realm, promise, compiled_module_or_error.error_value()); - } else { - auto module_object = vm.heap().allocate(realm, realm, compiled_module_or_error.release_value()); - WebIDL::resolve_promise(realm, promise, module_object); + // 1. Let stableBytes be a copy of the bytes held by the buffer bytes. + auto stable_bytes = WebIDL::get_buffer_source_copy(*bytes->raw_object()); + if (stable_bytes.is_error()) { + VERIFY(stable_bytes.error().code() == ENOMEM); + return WebIDL::create_rejected_promise_from_exception(realm, vm.throw_completion(vm.error_message(JS::VM::ErrorMessage::OutOfMemory))); } - return promise; + // 2. Asynchronously compile a WebAssembly module from stableBytes and return the result. + return asynchronously_compile_webassembly_module(vm, stable_bytes.release_value()); } // https://webassembly.github.io/spec/js-api/#dom-webassembly-instantiate -WebIDL::ExceptionOr> instantiate(JS::VM& vm, JS::Handle& bytes, Optional>& import_object) +WebIDL::ExceptionOr> instantiate(JS::VM& vm, JS::Handle& bytes, Optional>& import_object_handle) { - // FIXME: Implement the importObject parameter. - (void)import_object; - auto& realm = *vm.current_realm(); - // FIXME: This shouldn't block! - auto compiled_module_or_error = Detail::parse_module(vm, bytes->raw_object()); - auto promise = WebIDL::create_promise(realm); - - if (compiled_module_or_error.is_error()) { - WebIDL::reject_promise(realm, promise, compiled_module_or_error.error_value()); - return promise; + // 1. Let stableBytes be a copy of the bytes held by the buffer bytes. + auto stable_bytes = WebIDL::get_buffer_source_copy(*bytes->raw_object()); + if (stable_bytes.is_error()) { + VERIFY(stable_bytes.error().code() == ENOMEM); + return WebIDL::create_rejected_promise_from_exception(realm, vm.throw_completion(vm.error_message(JS::VM::ErrorMessage::OutOfMemory))); } - auto compiled_module = compiled_module_or_error.release_value(); - auto result = Detail::instantiate_module(vm, compiled_module->module); + // 2. Asynchronously compile a WebAssembly module from stableBytes and let promiseOfModule be the result. + auto promise_of_module = asynchronously_compile_webassembly_module(vm, stable_bytes.release_value()); - if (result.is_error()) { - WebIDL::reject_promise(realm, promise, result.error_value()); - } else { - auto module_object = vm.heap().allocate(realm, realm, move(compiled_module)); - auto instance_object = vm.heap().allocate(realm, realm, result.release_value()); - - auto object = JS::Object::create(realm, nullptr); - object->define_direct_property("module", module_object, JS::default_attributes); - object->define_direct_property("instance", instance_object, JS::default_attributes); - WebIDL::resolve_promise(realm, promise, object); - } - - return promise; + // 3. Instantiate promiseOfModule with imports importObject and return the result. + JS::GCPtr const import_object = import_object_handle.has_value() ? import_object_handle.value().ptr() : nullptr; + return instantiate_promise_of_module(vm, promise_of_module, import_object); } // https://webassembly.github.io/spec/js-api/#dom-webassembly-instantiate-moduleobject-importobject WebIDL::ExceptionOr> instantiate(JS::VM& vm, Module const& module_object, Optional>& import_object) { - // FIXME: Implement the importObject parameter. - (void)import_object; - - auto& realm = *vm.current_realm(); - auto promise = WebIDL::create_promise(realm); - - // FIXME: This shouldn't block! - auto const& compiled_module = module_object.compiled_module(); - auto result = Detail::instantiate_module(vm, compiled_module->module); - - if (result.is_error()) { - WebIDL::reject_promise(realm, promise, result.error_value()); - } else { - auto instance_object = vm.heap().allocate(realm, realm, result.release_value()); - WebIDL::resolve_promise(realm, promise, instance_object); - } - - return promise; + // 1. Asynchronously instantiate the WebAssembly module moduleObject importing importObject, and return the result. + JS::NonnullGCPtr module { const_cast(module_object) }; + JS::GCPtr const imports = import_object.has_value() ? import_object.value().ptr() : nullptr; + return asynchronously_instantiate_webassembly_module(vm, module, imports); } namespace Detail { -JS::ThrowCompletionOr> instantiate_module(JS::VM& vm, Wasm::Module const& module) +JS::ThrowCompletionOr> instantiate_module(JS::VM& vm, Wasm::Module const& module, JS::GCPtr import_object) { Wasm::Linker linker { module }; HashMap resolved_imports; - auto import_argument = vm.argument(1); auto& cache = get_cache(*vm.current_realm()); - if (!import_argument.is_undefined()) { - auto import_object = TRY(import_argument.to_object(vm)); + if (import_object) { dbgln_if(LIBWEB_WASM_DEBUG, "Trying to resolve stuff because import object was specified"); for (Wasm::Linker::Name const& import_name : linker.unresolved_imports()) { dbgln_if(LIBWEB_WASM_DEBUG, "Trying to resolve {}::{}", import_name.module, import_name.name); @@ -309,32 +280,10 @@ JS::ThrowCompletionOr> instantiate_module(JS return instance_result.release_value(); } -JS::ThrowCompletionOr> parse_module(JS::VM& vm, JS::Object* buffer_object) +// // https://webassembly.github.io/spec/js-api/#compile-a-webassembly-module +JS::ThrowCompletionOr> compile_a_webassembly_module(JS::VM& vm, ByteBuffer data) { - ReadonlyBytes data; - if (is(buffer_object)) { - auto& buffer = static_cast(*buffer_object); - data = buffer.buffer(); - } else if (is(buffer_object)) { - auto& buffer = static_cast(*buffer_object); - - auto typed_array_record = JS::make_typed_array_with_buffer_witness_record(buffer, JS::ArrayBuffer::Order::SeqCst); - if (JS::is_typed_array_out_of_bounds(typed_array_record)) - return vm.throw_completion(JS::ErrorType::BufferOutOfBounds, "TypedArray"sv); - - data = buffer.viewed_array_buffer()->buffer().span().slice(buffer.byte_offset(), JS::typed_array_byte_length(typed_array_record)); - } else if (is(buffer_object)) { - auto& buffer = static_cast(*buffer_object); - - auto view_record = JS::make_data_view_with_buffer_witness_record(buffer, JS::ArrayBuffer::Order::SeqCst); - if (JS::is_view_out_of_bounds(view_record)) - return vm.throw_completion(JS::ErrorType::BufferOutOfBounds, "DataView"sv); - - data = buffer.viewed_array_buffer()->buffer().span().slice(buffer.byte_offset(), JS::get_view_byte_length(view_record)); - } else { - return vm.throw_completion("Not a BufferSource"sv); - } - FixedMemoryStream stream { data }; + FixedMemoryStream stream { data.bytes() }; auto module_result = Wasm::Module::parse(stream); if (module_result.is_error()) { // FIXME: Throw CompileError instead. @@ -525,4 +474,154 @@ JS::Value to_js_value(JS::VM& vm, Wasm::Value& wasm_value, Wasm::ValueType type) } +// https://webassembly.github.io/spec/js-api/#asynchronously-compile-a-webassembly-module +JS::NonnullGCPtr asynchronously_compile_webassembly_module(JS::VM& vm, ByteBuffer bytes, HTML::Task::Source task_source) +{ + auto& realm = *vm.current_realm(); + + // 1. Let promise be a new Promise. + auto promise = WebIDL::create_promise(realm); + + // 2. Run the following steps in parallel: + Platform::EventLoopPlugin::the().deferred_invoke([&vm, bytes = move(bytes), promise, task_source]() mutable { + HTML::TemporaryExecutionContext context(HTML::relevant_settings_object(*promise->promise()), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); + // 1. Compile the WebAssembly module bytes and store the result as module. + auto module_or_error = Detail::compile_a_webassembly_module(vm, move(bytes)); + + // 2. Queue a task to perform the following steps. If taskSource was provided, queue the task on that task source. + HTML::queue_a_task(task_source, nullptr, nullptr, JS::create_heap_function(vm.heap(), [&vm, promise, module_or_error = move(module_or_error)]() mutable { + HTML::TemporaryExecutionContext context(HTML::relevant_settings_object(*promise->promise()), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); + auto& realm = HTML::relevant_realm(*promise->promise()); + + // 1. If module is error, reject promise with a CompileError exception. + if (module_or_error.is_error()) { + WebIDL::reject_promise(realm, promise, module_or_error.error_value()); + } + + // 2. Otherwise, + else { + // 1. Construct a WebAssembly module object from module and bytes, and let moduleObject be the result. + // FIXME: Save bytes to the Module instance instead of moving into compile_a_webassembly_module + auto module_object = vm.heap().allocate(realm, realm, module_or_error.release_value()); + + // 2. Resolve promise with moduleObject. + WebIDL::resolve_promise(*vm.current_realm(), promise, module_object); + } + })); + }); + + // 3. Return promise. + return promise; +} + +// https://webassembly.github.io/spec/js-api/#asynchronously-instantiate-a-webassembly-module +JS::NonnullGCPtr asynchronously_instantiate_webassembly_module(JS::VM& vm, JS::NonnullGCPtr module_object, JS::GCPtr import_object) +{ + auto& realm = *vm.current_realm(); + + // 1. Let promise be a new promise. + auto promise = WebIDL::create_promise(realm); + + // 2. Let module be moduleObject.[[Module]]. + auto module = module_object->compiled_module(); + + // 3. Read the imports of module with imports importObject, and let imports be the result. + // If this operation throws an exception, catch it, reject promise with the exception, and return promise. + // Note: We do this at the same time as instantiation in instantiate_module. + + // 4. Run the following steps in parallel: + // 1. Queue a task to perform the following steps: Note: Implementation-specific work may be performed here. + HTML::queue_a_task(HTML::Task::Source::Unspecified, nullptr, nullptr, JS::create_heap_function(vm.heap(), [&vm, promise, module, import_object]() { + HTML::TemporaryExecutionContext context(HTML::relevant_settings_object(*promise->promise()), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); + auto& realm = HTML::relevant_realm(*promise->promise()); + + // 1. Instantiate the core of a WebAssembly module module with imports, and let instance be the result. + // If this throws an exception, catch it, reject promise with the exception, and terminate these substeps. + auto result = Detail::instantiate_module(vm, module->module, import_object); + if (result.is_error()) { + WebIDL::reject_promise(realm, promise, result.error_value()); + return; + } + auto instance = result.release_value(); + + // 2. Let instanceObject be a new Instance. + // 3. Initialize instanceObject from module and instance. If this throws an exception, catch it, reject promise with the exception, and terminate these substeps. + // FIXME: Investigate whether we are doing all the proper steps for "initialize an instance object" + auto instance_object = vm.heap().allocate(realm, realm, move(instance)); + + // 4. Resolve promise with instanceObject. + WebIDL::resolve_promise(realm, promise, instance_object); + })); + + // 5. Return promise. + return promise; +} + +// https://webassembly.github.io/spec/js-api/#instantiate-a-promise-of-a-module +JS::NonnullGCPtr instantiate_promise_of_module(JS::VM& vm, JS::NonnullGCPtr promise_of_module, JS::GCPtr import_object) +{ + auto& realm = *vm.current_realm(); + + // 1. Let promise be a new Promise. + auto promise = WebIDL::create_promise(realm); + + // FIXME: Spec should use react to promise here instead of separate upon fulfillment and upon rejection steps + + // 2. Upon fulfillment of promiseOfModule with value module: + auto fulfillment_steps = JS::create_heap_function(vm.heap(), [&vm, promise, import_object](JS::Value module_value) -> WebIDL::ExceptionOr { + VERIFY(module_value.is_object() && is(module_value.as_object())); + auto module = JS::NonnullGCPtr { static_cast(module_value.as_object()) }; + + // 1. Instantiate the WebAssembly module module importing importObject, and let innerPromise be the result. + auto inner_promise = asynchronously_instantiate_webassembly_module(vm, module, import_object); + + // 2. Upon fulfillment of innerPromise with value instance. + auto instantiate_fulfillment_steps = JS::create_heap_function(vm.heap(), [promise, module](JS::Value instance_value) -> WebIDL::ExceptionOr { + auto& realm = HTML::relevant_realm(*promise->promise()); + + VERIFY(instance_value.is_object() && is(instance_value.as_object())); + auto instance = JS::NonnullGCPtr { static_cast(instance_value.as_object()) }; + + // 1. Let result be the WebAssemblyInstantiatedSource value «[ "module" → module, "instance" → instance ]». + auto result = JS::Object::create(realm, nullptr); + result->define_direct_property("module", module, JS::default_attributes); + result->define_direct_property("instance", instance, JS::default_attributes); + + // 2. Resolve promise with result. + WebIDL::resolve_promise(realm, promise, result); + + return JS::js_undefined(); + }); + + // 3. Upon rejection of innerPromise with reason reason. + auto instantiate_rejection_steps = JS::create_heap_function(vm.heap(), [promise](JS::Value reason) -> WebIDL::ExceptionOr { + auto& realm = HTML::relevant_realm(*promise->promise()); + + // 1. Reject promise with reason. + WebIDL::reject_promise(realm, promise, reason); + + return JS::js_undefined(); + }); + + WebIDL::react_to_promise(inner_promise, instantiate_fulfillment_steps, instantiate_rejection_steps); + + return JS::js_undefined(); + }); + + // 3. Upon rejection of promiseOfModule with reason reason: + auto rejection_steps = JS::create_heap_function(vm.heap(), [promise](JS::Value reason) -> WebIDL::ExceptionOr { + auto& realm = HTML::relevant_realm(*promise->promise()); + + // 1. Reject promise with reason. + WebIDL::reject_promise(realm, promise, reason); + + return JS::js_undefined(); + }); + + WebIDL::react_to_promise(promise_of_module, fulfillment_steps, rejection_steps); + + // 4. Return promise. + return promise; +} + } diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h index 9d92baa5cc3..9783d9d69c9 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h @@ -62,8 +62,8 @@ private: WebAssemblyCache& get_cache(JS::Realm&); -JS::ThrowCompletionOr> instantiate_module(JS::VM&, Wasm::Module const&); -JS::ThrowCompletionOr> parse_module(JS::VM&, JS::Object* buffer); +JS::ThrowCompletionOr> instantiate_module(JS::VM&, Wasm::Module const&, JS::GCPtr import_object); +JS::ThrowCompletionOr> compile_a_webassembly_module(JS::VM&, ByteBuffer); JS::NativeFunction* create_native_function(JS::VM&, Wasm::FunctionAddress address, ByteString const& name, Instance* instance = nullptr); JS::ThrowCompletionOr to_webassembly_value(JS::VM&, JS::Value value, Wasm::ValueType const& type); Wasm::Value default_webassembly_value(JS::VM&, Wasm::ValueType type);