diff options
author | Timothy Flynn <trflynn89@pm.me> | 2023-03-15 14:47:54 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-03-16 13:54:16 +0100 |
commit | fb1f15774f1b850829c2785beae9cb875ea713f8 (patch) | |
tree | 13398d67f063176bc3657a750279ea67b38784d3 | |
parent | 5c97ffb94f372af7648141c093a2fb66f3010383 (diff) | |
download | serenity-fb1f15774f1b850829c2785beae9cb875ea713f8.zip |
LibWeb: Port WebAssembly.Module to IDL
15 files changed, 121 insertions, 171 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 218d2b9af1..67e9274178 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -37,6 +37,7 @@ static bool is_platform_object(Type const& type) "FileList"sv, "FormData"sv, "ImageData"sv, + "Module"sv, "MutationRecord"sv, "NamedNodeMap"sv, "Node"sv, diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp index 0b9b6fa7a4..b4743a5629 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp @@ -105,7 +105,6 @@ class @legacy_constructor_class@;)~~~"); auto gen = generator.fork(); add_interface(gen, "WebAssemblyMemoryPrototype"sv, "WebAssemblyMemoryConstructor"sv, {}); add_interface(gen, "WebAssemblyInstancePrototype"sv, "WebAssemblyInstanceConstructor"sv, {}); - add_interface(gen, "WebAssemblyModulePrototype"sv, "WebAssemblyModuleConstructor"sv, {}); add_interface(gen, "WebAssemblyTablePrototype"sv, "WebAssemblyTableConstructor"sv, {}); } @@ -159,8 +158,6 @@ static ErrorOr<void> generate_intrinsic_definitions(StringView output_path, Vect #include <LibWeb/WebAssembly/WebAssemblyMemoryPrototype.h> #include <LibWeb/WebAssembly/WebAssemblyInstanceConstructor.h> #include <LibWeb/WebAssembly/WebAssemblyInstanceObjectPrototype.h> -#include <LibWeb/WebAssembly/WebAssemblyModuleConstructor.h> -#include <LibWeb/WebAssembly/WebAssemblyModulePrototype.h> #include <LibWeb/WebAssembly/WebAssemblyTableConstructor.h> #include <LibWeb/WebAssembly/WebAssemblyTablePrototype.h>)~~~"); @@ -233,7 +230,6 @@ void Intrinsics::create_web_prototype_and_constructor<@prototype_class@>(JS::Rea auto gen = generator.fork(); add_interface(gen, "WebAssembly.Memory"sv, "WebAssemblyMemoryPrototype"sv, "WebAssemblyMemoryConstructor"sv, {}); add_interface(gen, "WebAssembly.Instance"sv, "WebAssemblyInstancePrototype"sv, "WebAssemblyInstanceConstructor"sv, {}); - add_interface(gen, "WebAssembly.Module"sv, "WebAssemblyModulePrototype"sv, "WebAssemblyModuleConstructor"sv, {}); add_interface(gen, "WebAssembly.Table"sv, "WebAssemblyTablePrototype"sv, "WebAssemblyTableConstructor"sv, {}); } diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index cdf5bcd2b8..8a0064252f 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -442,13 +442,12 @@ set(SOURCES URL/URL.cpp URL/URLSearchParams.cpp URL/URLSearchParamsIterator.cpp + WebAssembly/Module.cpp WebAssembly/WebAssemblyInstanceConstructor.cpp WebAssembly/WebAssemblyInstanceObject.cpp WebAssembly/WebAssemblyInstanceObjectPrototype.cpp WebAssembly/WebAssemblyMemoryConstructor.cpp WebAssembly/WebAssemblyMemoryPrototype.cpp - WebAssembly/WebAssemblyModuleConstructor.cpp - WebAssembly/WebAssemblyModuleObject.cpp WebAssembly/WebAssemblyObject.cpp WebAssembly/WebAssemblyTableConstructor.cpp WebAssembly/WebAssemblyTableObject.cpp diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 912c8a08e2..e19c5c0fc3 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -482,6 +482,7 @@ class ResourceLoader; } namespace Web::WebAssembly { +class Module; } namespace Web::WebGL { diff --git a/Userland/Libraries/LibWeb/WebAssembly/Module.cpp b/Userland/Libraries/LibWeb/WebAssembly/Module.cpp new file mode 100644 index 0000000000..efbafa5961 --- /dev/null +++ b/Userland/Libraries/LibWeb/WebAssembly/Module.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> + * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibJS/Runtime/Realm.h> +#include <LibJS/Runtime/VM.h> +#include <LibWeb/Bindings/Intrinsics.h> +#include <LibWeb/Bindings/ModulePrototype.h> +#include <LibWeb/WebAssembly/Module.h> +#include <LibWeb/WebAssembly/WebAssemblyObject.h> + +namespace Web::WebAssembly { + +WebIDL::ExceptionOr<JS::NonnullGCPtr<Module>> Module::construct_impl(JS::Realm& realm, JS::Handle<JS::Object>& bytes) +{ + auto& vm = realm.vm(); + + auto index = TRY(Bindings::parse_module(vm, bytes.cell())); + return MUST_OR_THROW_OOM(vm.heap().allocate<Module>(realm, realm, index)); +} + +Module::Module(JS::Realm& realm, size_t index) + : Bindings::PlatformObject(realm) + , m_index(index) +{ +} + +JS::ThrowCompletionOr<void> Module::initialize(JS::Realm& realm) +{ + MUST_OR_THROW_OOM(Base::initialize(realm)); + set_prototype(&Bindings::ensure_web_prototype<Bindings::ModulePrototype>(realm, "WebAssembly.Module"sv)); + + return {}; +} + +Wasm::Module const& Module::module() const +{ + return Bindings::WebAssemblyObject::s_compiled_modules.at(index())->module; +} + +} diff --git a/Userland/Libraries/LibWeb/WebAssembly/Module.h b/Userland/Libraries/LibWeb/WebAssembly/Module.h new file mode 100644 index 0000000000..701ecab4eb --- /dev/null +++ b/Userland/Libraries/LibWeb/WebAssembly/Module.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> + * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibJS/Forward.h> +#include <LibJS/Heap/GCPtr.h> +#include <LibJS/Heap/Handle.h> +#include <LibWasm/Types.h> +#include <LibWeb/Bindings/ExceptionOrUtils.h> +#include <LibWeb/Bindings/PlatformObject.h> + +namespace Web::WebAssembly { + +class Module : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(Module, Bindings::PlatformObject); + +public: + static WebIDL::ExceptionOr<JS::NonnullGCPtr<Module>> construct_impl(JS::Realm&, JS::Handle<JS::Object>& bytes); + + size_t index() const { return m_index; } + Wasm::Module const& module() const; + +private: + Module(JS::Realm&, size_t index); + + virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override; + + size_t m_index { 0 }; +}; + +} diff --git a/Userland/Libraries/LibWeb/WebAssembly/Module.idl b/Userland/Libraries/LibWeb/WebAssembly/Module.idl new file mode 100644 index 0000000000..eb03880b86 --- /dev/null +++ b/Userland/Libraries/LibWeb/WebAssembly/Module.idl @@ -0,0 +1,27 @@ +enum ImportExportKind { + "function", + "table", + "memory", + "global" +}; + +dictionary ModuleExportDescriptor { + required USVString name; + required ImportExportKind kind; +}; + +dictionary ModuleImportDescriptor { + required USVString module; + required USVString name; + required ImportExportKind kind; +}; + +// https://webassembly.github.io/spec/js-api/#modules +[LegacyNamespace=WebAssembly, Exposed=*] +interface Module { + constructor(BufferSource bytes); + + // FIXME: static sequence<ModuleExportDescriptor> exports(Module moduleObject); + // FIXME: static sequence<ModuleImportDescriptor> imports(Module moduleObject); + // FIXME: static sequence<ArrayBuffer> customSections(Module moduleObject, DOMString sectionName); +}; diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp index a733b94fa8..f7b5091d4d 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp @@ -6,10 +6,10 @@ #include <LibJS/Runtime/GlobalObject.h> #include <LibWeb/Bindings/Intrinsics.h> +#include <LibWeb/WebAssembly/Module.h> #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 { @@ -32,9 +32,9 @@ JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object>> WebAssemblyInstanceConstruct auto& realm = *vm.current_realm(); auto* module_argument = TRY(vm.argument(0).to_object(vm)); - if (!is<WebAssemblyModuleObject>(module_argument)) + if (!is<WebAssembly::Module>(module_argument)) return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "WebAssembly.Module"); - auto& module_object = static_cast<WebAssemblyModuleObject&>(*module_argument); + auto& module_object = static_cast<WebAssembly::Module&>(*module_argument); auto result = TRY(WebAssemblyObject::instantiate_module(vm, module_object.module())); return MUST_OR_THROW_OOM(heap().allocate<WebAssemblyInstanceObject>(realm, realm, result)); } diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.cpp deleted file mode 100644 index c8563f6ccf..0000000000 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include <LibJS/Runtime/TypedArray.h> -#include <LibWeb/Bindings/Intrinsics.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::Realm& realm) - : NativeFunction(*realm.intrinsics().function_prototype()) -{ -} - -WebAssemblyModuleConstructor::~WebAssemblyModuleConstructor() = default; - -JS::ThrowCompletionOr<JS::Value> WebAssemblyModuleConstructor::call() -{ - return vm().throw_completion<JS::TypeError>(JS::ErrorType::ConstructorWithoutNew, "WebAssembly.Module"); -} - -JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object>> WebAssemblyModuleConstructor::construct(FunctionObject&) -{ - auto& vm = this->vm(); - auto& realm = *vm.current_realm(); - - auto* buffer_object = TRY(vm.argument(0).to_object(vm)); - auto result = TRY(parse_module(vm, buffer_object)); - - return MUST_OR_THROW_OOM(heap().allocate<WebAssemblyModuleObject>(realm, realm, result)); -} - -JS::ThrowCompletionOr<void> WebAssemblyModuleConstructor::initialize(JS::Realm& realm) -{ - auto& vm = this->vm(); - - MUST_OR_THROW_OOM(NativeFunction::initialize(realm)); - define_direct_property(vm.names.prototype, &Bindings::ensure_web_prototype<WebAssemblyModulePrototype>(realm, "WebAssembly.Module"), 0); - define_direct_property(vm.names.length, JS::Value(1), JS::Attribute::Configurable); - - return {}; -} - -} diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.h deleted file mode 100644 index cfdfe0412f..0000000000 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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::Realm&); - virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override; - virtual ~WebAssemblyModuleConstructor() override; - - virtual JS::ThrowCompletionOr<JS::Value> call() override; - virtual JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Object>> 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 deleted file mode 100644 index a73b50d5ee..0000000000 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleObject.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include "WebAssemblyModulePrototype.h" -#include <LibWeb/Bindings/Intrinsics.h> -#include <LibWeb/WebAssembly/WebAssemblyModuleObject.h> - -namespace Web::Bindings { - -WebAssemblyModuleObject::WebAssemblyModuleObject(JS::Realm& realm, size_t index) - : Object(ConstructWithPrototypeTag::Tag, Bindings::ensure_web_prototype<WebAssemblyModulePrototype>(realm, "WebAssembly.Module")) - , m_index(index) -{ -} - -} diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleObject.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleObject.h deleted file mode 100644 index 5ed6c3c130..0000000000 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleObject.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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::Realm&, size_t index); - virtual ~WebAssemblyModuleObject() override = default; - - size_t index() const { return m_index; } - Wasm::Module const& 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 deleted file mode 100644 index 63155ae0d1..0000000000 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModulePrototype.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include "WebAssemblyModuleConstructor.h" -#include <LibJS/Runtime/Object.h> -#include <LibJS/Runtime/VM.h> -#include <LibWeb/Forward.h> - -namespace Web::Bindings { - -class WebAssemblyModulePrototype final : public JS::Object { - JS_OBJECT(WebAssemblyModulePrototype, JS::Object); - -public: - explicit WebAssemblyModulePrototype(JS::Realm& realm) - : JS::Object(ConstructWithPrototypeTag::Tag, *realm.intrinsics().object_prototype()) - { - } -}; - -} diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp index e2800c8624..55c717a66b 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyObject.cpp @@ -6,9 +6,6 @@ #include "WebAssemblyInstanceObject.h" #include "WebAssemblyMemoryPrototype.h" -#include "WebAssemblyModuleConstructor.h" -#include "WebAssemblyModuleObject.h" -#include "WebAssemblyModulePrototype.h" #include "WebAssemblyTableObject.h" #include "WebAssemblyTablePrototype.h" #include <AK/MemoryStream.h> @@ -23,6 +20,8 @@ #include <LibWasm/AbstractMachine/Interpreter.h> #include <LibWasm/AbstractMachine/Validator.h> #include <LibWeb/Bindings/Intrinsics.h> +#include <LibWeb/Bindings/ModulePrototype.h> +#include <LibWeb/WebAssembly/Module.h> #include <LibWeb/WebAssembly/WebAssemblyInstanceConstructor.h> #include <LibWeb/WebAssembly/WebAssemblyObject.h> @@ -49,7 +48,7 @@ JS::ThrowCompletionOr<void> WebAssemblyObject::initialize(JS::Realm& realm) auto& instance_constructor = Bindings::ensure_web_constructor<WebAssemblyInstancePrototype>(realm, "WebAssembly.Instance"sv); define_direct_property("Instance", &instance_constructor, JS::Attribute::Writable | JS::Attribute::Configurable); - auto& module_constructor = Bindings::ensure_web_constructor<WebAssemblyModulePrototype>(realm, "WebAssembly.Module"sv); + auto& module_constructor = Bindings::ensure_web_constructor<ModulePrototype>(realm, "WebAssembly.Module"sv); define_direct_property("Module", &module_constructor, JS::Attribute::Writable | JS::Attribute::Configurable); auto& table_constructor = Bindings::ensure_web_constructor<WebAssemblyTablePrototype>(realm, "WebAssembly.Table"sv); @@ -159,7 +158,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::compile) if (result.is_error()) promise->reject(*result.release_error().value()); else - promise->fulfill(MUST_OR_THROW_OOM(vm.heap().allocate<WebAssemblyModuleObject>(realm, realm, result.release_value()))); + promise->fulfill(MUST_OR_THROW_OOM(vm.heap().allocate<WebAssembly::Module>(realm, realm, result.release_value()))); return promise; } @@ -333,8 +332,8 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate) } module = &WebAssemblyObject::s_compiled_modules.at(result.release_value())->module; should_return_module = true; - } else if (is<WebAssemblyModuleObject>(buffer)) { - module = &static_cast<WebAssemblyModuleObject*>(buffer)->module(); + } else if (is<WebAssembly::Module>(buffer)) { + module = &static_cast<WebAssembly::Module*>(buffer)->module(); } else { auto error = JS::TypeError::create(realm, TRY_OR_THROW_OOM(vm, String::formatted("{} is not an ArrayBuffer or a Module", buffer->class_name()))); promise->reject(error); @@ -349,7 +348,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyObject::instantiate) auto instance_object = MUST_OR_THROW_OOM(vm.heap().allocate<WebAssemblyInstanceObject>(realm, realm, result.release_value())); if (should_return_module) { auto object = JS::Object::create(realm, nullptr); - object->define_direct_property("module", MUST_OR_THROW_OOM(vm.heap().allocate<WebAssemblyModuleObject>(realm, realm, s_compiled_modules.size() - 1)), JS::default_attributes); + object->define_direct_property("module", MUST_OR_THROW_OOM(vm.heap().allocate<WebAssembly::Module>(realm, realm, s_compiled_modules.size() - 1)), JS::default_attributes); object->define_direct_property("instance", instance_object, JS::default_attributes); promise->fulfill(object); } else { diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index bbb10269a9..45e70a2276 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -200,6 +200,7 @@ libweb_js_bindings(UIEvents/UIEvent) libweb_js_bindings(UIEvents/WheelEvent) libweb_js_bindings(URL/URL) libweb_js_bindings(URL/URLSearchParams ITERABLE) +libweb_js_bindings(WebAssembly/Module) libweb_js_bindings(WebGL/WebGLContextEvent) libweb_js_bindings(WebGL/WebGLRenderingContext) libweb_js_bindings(WebIDL/DOMException) |