1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 22:27:42 +00:00

LibWeb: Implement WebAssembly::validate()

...and make sure to validate the module in WebAssembly::compile()
This commit is contained in:
Ali Mohammad Pur 2021-11-08 03:06:30 +03:30 committed by Andreas Kling
parent 3680aa253d
commit 2801323236

View file

@ -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;
}