summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2023-02-25 23:26:48 +0330
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2023-02-26 10:54:23 +0330
commit8a36d8826fff0ed13d5d8d62ad93b9c9355113c9 (patch)
treeb5243d5a7cfdafe8337f2b620a9d1234ef8fde49 /Userland
parent6b50f232426742fcf9e71420c37bf4831bca2e31 (diff)
downloadserenity-8a36d8826fff0ed13d5d8d62ad93b9c9355113c9.zip
LibWeb: Implement the js-api portion of Wasm multi-value
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp28
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);