diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2023-02-25 23:26:48 +0330 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2023-02-26 10:54:23 +0330 |
commit | 8a36d8826fff0ed13d5d8d62ad93b9c9355113c9 (patch) | |
tree | b5243d5a7cfdafe8337f2b620a9d1234ef8fde49 /Userland | |
parent | 6b50f232426742fcf9e71420c37bf4831bca2e31 (diff) | |
download | serenity-8a36d8826fff0ed13d5d8d62ad93b9c9355113c9.zip |
LibWeb: Implement the js-api portion of Wasm multi-value
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp index 212f0e8204..7a28c17d15 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp @@ -17,6 +17,7 @@ #include <LibJS/Runtime/ArrayBuffer.h> #include <LibJS/Runtime/BigInt.h> #include <LibJS/Runtime/DataView.h> +#include <LibJS/Runtime/IteratorOperations.h> #include <LibJS/Runtime/ThrowableStringBuilder.h> #include <LibJS/Runtime/TypedArray.h> #include <LibWasm/AbstractMachine/Interpreter.h> @@ -207,8 +208,23 @@ JS::ThrowCompletionOr<size_t> WebAssemblyObject::instantiate_module(JS::VM& vm, if (type.results().size() == 1) return Wasm::Result { Vector<Wasm::Value> { TRY(to_webassembly_value(vm, result, type.results().first())) } }; - // FIXME: Multiple returns - TODO(); + auto method = TRY(result.get_method(vm, vm.names.iterator)); + if (method == JS::js_undefined()) + return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotIterable, TRY_OR_THROW_OOM(vm, result.to_string_without_side_effects())); + + auto values = TRY(JS::iterable_to_list(vm, result, method)); + + if (values.size() != type.results().size()) + return vm.throw_completion<JS::TypeError>(DeprecatedString::formatted("Invalid number of return values for multi-value wasm return of {} objects", type.results().size())); + + Vector<Wasm::Value> wasm_values; + TRY_OR_THROW_OOM(vm, wasm_values.try_ensure_capacity(values.size())); + + size_t i = 0; + for (auto& value : values) + wasm_values.append(TRY(to_webassembly_value(vm, value, type.results()[i++]))); + + return Wasm::Result { move(wasm_values) }; }, type }; @@ -448,11 +464,9 @@ JS::NativeFunction* create_native_function(JS::VM& vm, Wasm::FunctionAddress add if (result.values().size() == 1) return to_js_value(vm, result.values().first()); - Vector<JS::Value> result_values; - for (auto& entry : result.values()) - result_values.append(to_js_value(vm, entry)); - - return JS::Value(JS::Array::create_from(realm, result_values)); + return JS::Value(JS::Array::create_from<Wasm::Value>(realm, result.values(), [&](Wasm::Value value) { + return to_js_value(vm, value); + })); }); WebAssemblyObject::s_global_cache.function_instances.set(address, function); |