summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-11-08 03:06:30 +0330
committerAndreas Kling <kling@serenityos.org>2021-11-11 09:20:04 +0100
commit2801323236066a823cd698513c02f079a021f472 (patch)
tree355ace29ad7522ced9bbcc0f649c641fdd5dafff
parent3680aa253d911d5084c4cd8c3aa10c1f8ba349bb (diff)
downloadserenity-2801323236066a823cd698513c02f079a021f472.zip
LibWeb: Implement WebAssembly::validate()
...and make sure to validate the module in WebAssembly::compile()
-rw-r--r--Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp33
1 files changed, 30 insertions, 3 deletions
diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp
index 18502d1f33..76d6b3cf7b 100644
--- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp
+++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp
@@ -18,6 +18,7 @@
#include <LibJS/Runtime/DataView.h>
#include <LibJS/Runtime/TypedArray.h>
#include <LibWasm/AbstractMachine/Interpreter.h>
+#include <LibWasm/AbstractMachine/Validator.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/WebAssembly/WebAssemblyInstanceConstructor.h>
#include <LibWeb/WebAssembly/WebAssemblyObject.h>
@@ -89,9 +90,30 @@ void WebAssemblyObject::visit_edges(Visitor& visitor)
JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::validate)
{
- // FIXME: Implement this once module validation is implemented in LibWasm.
- dbgln("Hit WebAssemblyObject::validate() stub!");
- return JS::Value { true };
+ // 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 buffer = TRY(vm.argument(0).to_object(global_object));
+
+ // 2. Compile stableBytes as a WebAssembly module and store the results as module.
+ auto maybe_module = parse_module(global_object, buffer);
+
+ // 3. If module is error, return false.
+ if (maybe_module.is_error())
+ return JS::Value(false);
+
+ // Drop the module from the cache, we're never going to refer to it.
+ ScopeGuard drop_from_cache {
+ [&] {
+ s_compiled_modules.take_last();
+ }
+ };
+
+ // 3 continued - our "compile" step is lazy with validation, explicitly do the validation.
+ if (s_abstract_machine.validate(s_compiled_modules[maybe_module.value()].module).is_error())
+ return JS::Value(false);
+
+ // 4. Return true.
+ return JS::Value(true);
}
JS::ThrowCompletionOr<size_t> parse_module(JS::GlobalObject& global_object, JS::Object* buffer_object)
@@ -123,6 +145,11 @@ JS::ThrowCompletionOr<size_t> parse_module(JS::GlobalObject& global_object, JS::
return vm.throw_completion<JS::TypeError>(global_object, Wasm::parse_error_to_string(module_result.error()));
}
+ if (auto validation_result = WebAssemblyObject::s_abstract_machine.validate(module_result.value()); validation_result.is_error()) {
+ // FIXME: Throw CompileError instead.
+ return vm.throw_completion<JS::TypeError>(global_object, validation_result.error().error_string);
+ }
+
WebAssemblyObject::s_compiled_modules.append(make<WebAssemblyObject::CompiledWebAssemblyModule>(module_result.release_value()));
return WebAssemblyObject::s_compiled_modules.size() - 1;
}