diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-07-01 15:14:05 +0430 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-07-02 04:53:01 +0430 |
commit | 321db0159e8d004ef963bb4aa6b23990df1cc304 (patch) | |
tree | 3eca5245f15ac246e393c72f237da88019c3807c /Userland/Libraries | |
parent | 8acc8339d19aa76f839d21190d908a43a081d93a (diff) | |
download | serenity-321db0159e8d004ef963bb4aa6b23990df1cc304.zip |
LibWeb: Add the WebAssembly.Module constructor
Diffstat (limited to 'Userland/Libraries')
9 files changed, 193 insertions, 30 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 9e53c09f6d..03b0cfac54 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -227,6 +227,8 @@ set(SOURCES WebAssembly/WebAssemblyInstanceObjectPrototype.cpp WebAssembly/WebAssemblyMemoryConstructor.cpp WebAssembly/WebAssemblyMemoryPrototype.cpp + WebAssembly/WebAssemblyModuleConstructor.cpp + WebAssembly/WebAssemblyModuleObject.cpp WebAssembly/WebAssemblyObject.cpp WebContentClient.cpp XHR/EventNames.cpp diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp index 5dafdd35ac..7ec16d6862 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp @@ -10,6 +10,7 @@ #include <LibWeb/WebAssembly/WebAssemblyInstanceConstructor.h> #include <LibWeb/WebAssembly/WebAssemblyInstanceObject.h> #include <LibWeb/WebAssembly/WebAssemblyInstanceObjectPrototype.h> +#include <LibWeb/WebAssembly/WebAssemblyModuleObject.h> #include <LibWeb/WebAssembly/WebAssemblyObject.h> namespace Web::Bindings { diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.cpp new file mode 100644 index 0000000000..f787f63ea7 --- /dev/null +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibJS/Heap/Heap.h> +#include <LibJS/Runtime/GlobalObject.h> +#include <LibJS/Runtime/TypedArray.h> +#include <LibWeb/Bindings/WindowObject.h> +#include <LibWeb/WebAssembly/WebAssemblyModuleConstructor.h> +#include <LibWeb/WebAssembly/WebAssemblyModuleObject.h> +#include <LibWeb/WebAssembly/WebAssemblyModulePrototype.h> +#include <LibWeb/WebAssembly/WebAssemblyObject.h> + +namespace Web::Bindings { + +WebAssemblyModuleConstructor::WebAssemblyModuleConstructor(JS::GlobalObject& global_object) + : NativeFunction(*global_object.function_prototype()) +{ +} + +WebAssemblyModuleConstructor::~WebAssemblyModuleConstructor() +{ +} + +JS::Value WebAssemblyModuleConstructor::call() +{ + vm().throw_exception<JS::TypeError>(global_object(), JS::ErrorType::ConstructorWithoutNew, "WebAssemblyModule"); + return {}; +} + +JS::Value WebAssemblyModuleConstructor::construct(FunctionObject&) +{ + auto& vm = this->vm(); + auto& global_object = this->global_object(); + + auto buffer_object = vm.argument(0).to_object(global_object); + if (vm.exception()) + return {}; + + auto result = parse_module(global_object, buffer_object); + if (result.is_error()) { + vm.throw_exception(global_object, result.error()); + return {}; + } + + return heap().allocate<WebAssemblyModuleObject>(global_object, global_object, result.release_value()); +} + +void WebAssemblyModuleConstructor::initialize(JS::GlobalObject& global_object) +{ + auto& vm = this->vm(); + auto& window = static_cast<WindowObject&>(global_object); + + NativeFunction::initialize(global_object); + define_property(vm.names.prototype, &window.ensure_web_prototype<WebAssemblyModulePrototype>("WebAssemblyModulePrototype")); + define_property(vm.names.length, JS::Value(1), JS::Attribute::Configurable); +} + +} diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.h new file mode 100644 index 0000000000..9df31c2a2a --- /dev/null +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibJS/Runtime/NativeFunction.h> + +namespace Web::Bindings { + +class WebAssemblyModuleConstructor : public JS::NativeFunction { + JS_OBJECT(WebAssemblyModuleConstructor, JS::NativeFunction); + +public: + explicit WebAssemblyModuleConstructor(JS::GlobalObject&); + virtual void initialize(JS::GlobalObject&) override; + virtual ~WebAssemblyModuleConstructor() override; + + virtual JS::Value call() override; + virtual JS::Value construct(JS::FunctionObject& new_target) override; + +private: + virtual bool has_constructor() const override { return true; } +}; + +} diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleObject.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleObject.cpp new file mode 100644 index 0000000000..27e5340197 --- /dev/null +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleObject.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "WebAssemblyModulePrototype.h" +#include <LibWeb/WebAssembly/WebAssemblyModuleObject.h> + +namespace Web::Bindings { + +WebAssemblyModuleObject::WebAssemblyModuleObject(JS::GlobalObject& global_object, size_t index) + : Object(static_cast<WindowObject&>(global_object).ensure_web_prototype<WebAssemblyModulePrototype>("WebAssemblyModulePrototype")) + , m_index(index) +{ +} + +} diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleObject.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleObject.h new file mode 100644 index 0000000000..b865fab521 --- /dev/null +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleObject.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibJS/Runtime/Object.h> +#include <LibWasm/AbstractMachine/AbstractMachine.h> +#include <LibWeb/Forward.h> +#include <LibWeb/WebAssembly/WebAssemblyInstanceObjectPrototype.h> +#include <LibWeb/WebAssembly/WebAssemblyObject.h> + +namespace Web::Bindings { + +class WebAssemblyModuleObject final : public JS::Object { + JS_OBJECT(WebAssemblyModuleObject, Object); + +public: + explicit WebAssemblyModuleObject(JS::GlobalObject&, size_t index); + virtual ~WebAssemblyModuleObject() override = default; + + size_t index() const { return m_index; } + const Wasm::Module& module() const { return WebAssemblyObject::s_compiled_modules.at(m_index).module; } + +private: + size_t m_index { 0 }; +}; + +} diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModulePrototype.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModulePrototype.h new file mode 100644 index 0000000000..d0b6b953fe --- /dev/null +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModulePrototype.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "WebAssemblyModuleConstructor.h" +#include <LibJS/Runtime/GlobalObject.h> +#include <LibJS/Runtime/Object.h> +#include <LibJS/Runtime/VM.h> +#include <LibWeb/Bindings/WindowObject.h> +#include <LibWeb/Forward.h> + +namespace Web::Bindings { + +class WebAssemblyModulePrototype final : public JS::Object { + JS_OBJECT(WebAssemblyModulePrototype, JS::Object); + +public: + explicit WebAssemblyModulePrototype(JS::GlobalObject& global_object) + : JS::Object(global_object) + { + } +}; + +} diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp index 065697534d..c21dd3daf6 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp @@ -6,10 +6,14 @@ #include "WebAssemblyInstanceObject.h" #include "WebAssemblyMemoryPrototype.h" +#include "WebAssemblyModuleConstructor.h" +#include "WebAssemblyModuleObject.h" +#include "WebAssemblyModulePrototype.h" #include <AK/ScopeGuard.h> #include <LibJS/Runtime/Array.h> #include <LibJS/Runtime/ArrayBuffer.h> #include <LibJS/Runtime/BigInt.h> +#include <LibJS/Runtime/DataView.h> #include <LibJS/Runtime/TypedArray.h> #include <LibWasm/AbstractMachine/Interpreter.h> #include <LibWeb/Bindings/WindowObject.h> @@ -45,6 +49,12 @@ void WebAssemblyObject::initialize(JS::GlobalObject& global_object) auto& instance_prototype = window.ensure_web_prototype<WebAssemblyInstancePrototype>("WebAssemblyInstancePrototype"); instance_prototype.define_property(vm.names.constructor, &instance_constructor, JS::Attribute::Writable | JS::Attribute::Configurable); define_property("Instance", &instance_constructor); + + auto& module_constructor = window.ensure_web_constructor<WebAssemblyModuleConstructor>("WebAssembly.Module"); + module_constructor.define_property(vm.names.name, js_string(vm, "WebAssembly.Module"), JS::Attribute::Configurable); + auto& module_prototype = window.ensure_web_prototype<WebAssemblyModulePrototype>("WebAssemblyModulePrototype"); + module_prototype.define_property(vm.names.constructor, &module_constructor, JS::Attribute::Writable | JS::Attribute::Configurable); + define_property("Module", &module_constructor); } NonnullOwnPtrVector<WebAssemblyObject::CompiledWebAssemblyModule> WebAssemblyObject::s_compiled_modules; @@ -74,20 +84,23 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::validate) return JS::Value { true }; } -static Result<size_t, JS::Value> parse_module(JS::GlobalObject& global_object, JS::Object* buffer) +Result<size_t, JS::Value> parse_module(JS::GlobalObject& global_object, JS::Object* buffer_object) { - ByteBuffer* bytes; - if (is<JS::ArrayBuffer>(buffer)) { - auto array_buffer = static_cast<JS::ArrayBuffer*>(buffer); - bytes = &array_buffer->buffer(); - } else if (is<JS::TypedArrayBase>(buffer)) { - auto array = static_cast<JS::TypedArrayBase*>(buffer); - bytes = &array->viewed_array_buffer()->buffer(); + ReadonlyBytes data; + if (is<JS::ArrayBuffer>(buffer_object)) { + auto& buffer = static_cast<JS::ArrayBuffer&>(*buffer_object); + data = buffer.buffer(); + } else if (is<JS::TypedArrayBase>(buffer_object)) { + auto& buffer = static_cast<JS::TypedArrayBase&>(*buffer_object); + data = buffer.viewed_array_buffer()->buffer().span().slice(buffer.byte_offset(), buffer.byte_length()); + } else if (is<JS::DataView>(buffer_object)) { + auto& buffer = static_cast<JS::DataView&>(*buffer_object); + data = buffer.viewed_array_buffer()->buffer().span().slice(buffer.byte_offset(), buffer.byte_length()); } else { - auto error = JS::TypeError::create(global_object, String::formatted("{} is not an ArrayBuffer", buffer->class_name())); + auto error = JS::TypeError::create(global_object, "Not a BufferSource"); return JS::Value { error }; } - InputMemoryStream stream { *bytes }; + InputMemoryStream stream { data }; auto module_result = Wasm::Module::parse(stream); ScopeGuard drain_errors { [&] { @@ -325,12 +338,6 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate) return promise; } -WebAssemblyModuleObject::WebAssemblyModuleObject(JS::GlobalObject& global_object, size_t index) - : Object(*global_object.object_prototype()) - , m_index(index) -{ -} - JS::Value to_js_value(Wasm::Value& wasm_value, JS::GlobalObject& global_object) { switch (wasm_value.type().kind()) { diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.h index 4713f25b1d..2c0eae4349 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.h +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.h @@ -14,6 +14,7 @@ namespace Web::Bindings { class WebAssemblyMemoryObject; +Result<size_t, JS::Value> parse_module(JS::GlobalObject& global_object, JS::Object* buffer); JS::NativeFunction* create_native_function(Wasm::FunctionAddress address, String name, JS::GlobalObject& global_object); JS::Value to_js_value(Wasm::Value& wasm_value, JS::GlobalObject& global_object); Optional<Wasm::Value> to_webassembly_value(JS::Value value, const Wasm::ValueType& type, JS::GlobalObject& global_object); @@ -64,20 +65,6 @@ private: JS_DECLARE_NATIVE_FUNCTION(instantiate); }; -class WebAssemblyModuleObject final : public JS::Object { - JS_OBJECT(WebAssemblyModuleObject, JS::Object); - -public: - explicit WebAssemblyModuleObject(JS::GlobalObject&, size_t index); - virtual ~WebAssemblyModuleObject() override = default; - - size_t index() const { return m_index; } - const Wasm::Module& module() const { return WebAssemblyObject::s_compiled_modules.at(m_index).module; } - -private: - size_t m_index { 0 }; -}; - class WebAssemblyMemoryObject final : public JS::Object { JS_OBJECT(WebAssemblyMemoryObject, JS::Object); |