diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-11-08 03:06:30 +0330 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-11-11 09:20:04 +0100 |
commit | 2801323236066a823cd698513c02f079a021f472 (patch) | |
tree | 355ace29ad7522ced9bbcc0f649c641fdd5dafff /Userland/Libraries/LibWeb/WebAssembly | |
parent | 3680aa253d911d5084c4cd8c3aa10c1f8ba349bb (diff) | |
download | serenity-2801323236066a823cd698513c02f079a021f472.zip |
LibWeb: Implement WebAssembly::validate()
...and make sure to validate the module in WebAssembly::compile()
Diffstat (limited to 'Userland/Libraries/LibWeb/WebAssembly')
-rw-r--r-- | Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp | 33 |
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; } |