diff options
author | Linus Groh <mail@linusgroh.de> | 2021-10-20 21:16:30 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-10-21 09:02:23 +0100 |
commit | 5832de62fe5e2de4f9a65485246df6550aece33f (patch) | |
tree | 485f847a4dedebdcb2b11902bbe0256fa98518ed /Userland/Libraries/LibWeb/WebAssembly | |
parent | 0881f8160fd81d8e25b7cc2eff2d64f2aed7ed53 (diff) | |
download | serenity-5832de62fe5e2de4f9a65485246df6550aece33f.zip |
LibJS: Convert NativeFunction::{call,construct}() to ThrowCompletionOr
Both at the same time because many of them call construct() in call()
and I'm not keen on adding a bunch of temporary plumbing to turn
exceptions into throw completions.
Also changes the return value of construct() to Object* instead of Value
as it always needs to return an object; allowing an arbitrary Value is a
massive foot gun.
Diffstat (limited to 'Userland/Libraries/LibWeb/WebAssembly')
8 files changed, 53 insertions, 72 deletions
diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp index aa33ca5916..d6d034ea82 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.cpp @@ -23,27 +23,23 @@ WebAssemblyInstanceConstructor::~WebAssemblyInstanceConstructor() { } -JS::Value WebAssemblyInstanceConstructor::call() +JS::ThrowCompletionOr<JS::Value> WebAssemblyInstanceConstructor::call() { - vm().throw_exception<JS::TypeError>(global_object(), JS::ErrorType::ConstructorWithoutNew, "WebAssembly.Instance"); - return {}; + return vm().throw_completion<JS::TypeError>(global_object(), JS::ErrorType::ConstructorWithoutNew, "WebAssembly.Instance"); } -JS::Value WebAssemblyInstanceConstructor::construct(FunctionObject&) +JS::ThrowCompletionOr<JS::Object*> WebAssemblyInstanceConstructor::construct(FunctionObject&) { auto& vm = this->vm(); auto& global_object = this->global_object(); - auto* module_argument = TRY_OR_DISCARD(vm.argument(0).to_object(global_object)); - if (!is<WebAssemblyModuleObject>(module_argument)) { - vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Module"); - return {}; - } - + auto* module_argument = TRY(vm.argument(0).to_object(global_object)); + if (!is<WebAssemblyModuleObject>(module_argument)) + return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "WebAssembly.Module"); auto& module_object = static_cast<WebAssemblyModuleObject&>(*module_argument); auto result = WebAssemblyObject::instantiate_module(module_object.module(), vm, global_object); if (result.is_error()) { - vm.throw_exception(global_object, result.release_error()); - return {}; + vm.throw_exception(global_object, result.error()); + return JS::throw_completion(result.error()); } return heap().allocate<WebAssemblyInstanceObject>(global_object, global_object, result.value()); } diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.h index 309ab550a6..90bdcb92a7 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.h +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyInstanceConstructor.h @@ -18,8 +18,8 @@ public: virtual void initialize(JS::GlobalObject&) override; virtual ~WebAssemblyInstanceConstructor() override; - virtual JS::Value call() override; - virtual JS::Value construct(JS::FunctionObject& new_target) override; + virtual JS::ThrowCompletionOr<JS::Value> call() override; + virtual JS::ThrowCompletionOr<JS::Object*> construct(JS::FunctionObject& new_target) override; private: virtual bool has_constructor() const override { return true; } diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.cpp index 25bf3cbc5a..bc5fbc20ab 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.cpp @@ -21,38 +21,33 @@ WebAssemblyMemoryConstructor::~WebAssemblyMemoryConstructor() { } -JS::Value WebAssemblyMemoryConstructor::call() +JS::ThrowCompletionOr<JS::Value> WebAssemblyMemoryConstructor::call() { - vm().throw_exception<JS::TypeError>(global_object(), JS::ErrorType::ConstructorWithoutNew, "WebAssembly.Memory"); - return {}; + return vm().throw_completion<JS::TypeError>(global_object(), JS::ErrorType::ConstructorWithoutNew, "WebAssembly.Memory"); } -JS::Value WebAssemblyMemoryConstructor::construct(FunctionObject&) +JS::ThrowCompletionOr<JS::Object*> WebAssemblyMemoryConstructor::construct(FunctionObject&) { auto& vm = this->vm(); auto& global_object = this->global_object(); - auto descriptor = TRY_OR_DISCARD(vm.argument(0).to_object(global_object)); - auto initial_value = TRY_OR_DISCARD(descriptor->get("initial")); - auto maximum_value = TRY_OR_DISCARD(descriptor->get("maximum")); + auto descriptor = TRY(vm.argument(0).to_object(global_object)); + auto initial_value = TRY(descriptor->get("initial")); + auto maximum_value = TRY(descriptor->get("maximum")); - if (initial_value.is_empty()) { - vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "Number"); - return {}; - } + if (initial_value.is_empty()) + return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::NotAnObjectOfType, "Number"); - auto initial = TRY_OR_DISCARD(initial_value.to_u32(global_object)); + auto initial = TRY(initial_value.to_u32(global_object)); Optional<u32> maximum; if (!maximum_value.is_empty()) - maximum = TRY_OR_DISCARD(maximum_value.to_u32(global_object)); + maximum = TRY(maximum_value.to_u32(global_object)); auto address = WebAssemblyObject::s_abstract_machine.store().allocate(Wasm::MemoryType { Wasm::Limits { initial, maximum } }); - if (!address.has_value()) { - vm.throw_exception<JS::TypeError>(global_object, "Wasm Memory allocation failed"); - return {}; - } + if (!address.has_value()) + return vm.throw_completion<JS::TypeError>(global_object, "Wasm Memory allocation failed"); return vm.heap().allocate<WebAssemblyMemoryObject>(global_object, global_object, *address); } diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.h index c14f127871..9391ec7b03 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.h +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyMemoryConstructor.h @@ -18,8 +18,8 @@ public: virtual void initialize(JS::GlobalObject&) override; virtual ~WebAssemblyMemoryConstructor() override; - virtual JS::Value call() override; - virtual JS::Value construct(JS::FunctionObject& new_target) override; + virtual JS::ThrowCompletionOr<JS::Value> call() override; + virtual JS::ThrowCompletionOr<JS::Object*> construct(JS::FunctionObject& new_target) override; private: virtual bool has_constructor() const override { return true; } diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.cpp index 2d8e188f54..da86d1d29d 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.cpp @@ -23,22 +23,21 @@ WebAssemblyModuleConstructor::~WebAssemblyModuleConstructor() { } -JS::Value WebAssemblyModuleConstructor::call() +JS::ThrowCompletionOr<JS::Value> WebAssemblyModuleConstructor::call() { - vm().throw_exception<JS::TypeError>(global_object(), JS::ErrorType::ConstructorWithoutNew, "WebAssembly.Module"); - return {}; + return vm().throw_completion<JS::TypeError>(global_object(), JS::ErrorType::ConstructorWithoutNew, "WebAssembly.Module"); } -JS::Value WebAssemblyModuleConstructor::construct(FunctionObject&) +JS::ThrowCompletionOr<JS::Object*> WebAssemblyModuleConstructor::construct(FunctionObject&) { auto& vm = this->vm(); auto& global_object = this->global_object(); - auto* buffer_object = TRY_OR_DISCARD(vm.argument(0).to_object(global_object)); + auto* buffer_object = TRY(vm.argument(0).to_object(global_object)); auto result = parse_module(global_object, buffer_object); if (result.is_error()) { vm.throw_exception(global_object, result.error()); - return {}; + return JS::throw_completion(result.error()); } return heap().allocate<WebAssemblyModuleObject>(global_object, global_object, result.release_value()); diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.h index 9df31c2a2a..a77815343d 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.h +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyModuleConstructor.h @@ -18,8 +18,8 @@ public: virtual void initialize(JS::GlobalObject&) override; virtual ~WebAssemblyModuleConstructor() override; - virtual JS::Value call() override; - virtual JS::Value construct(JS::FunctionObject& new_target) override; + virtual JS::ThrowCompletionOr<JS::Value> call() override; + virtual JS::ThrowCompletionOr<JS::Object*> construct(JS::FunctionObject& new_target) override; private: virtual bool has_constructor() const override { return true; } diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.cpp index 6399af78f9..83647680c2 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.cpp @@ -23,23 +23,20 @@ WebAssemblyTableConstructor::~WebAssemblyTableConstructor() { } -JS::Value WebAssemblyTableConstructor::call() +JS::ThrowCompletionOr<JS::Value> WebAssemblyTableConstructor::call() { - vm().throw_exception<JS::TypeError>(global_object(), JS::ErrorType::ConstructorWithoutNew, "WebAssembly.Table"); - return {}; + return vm().throw_completion<JS::TypeError>(global_object(), JS::ErrorType::ConstructorWithoutNew, "WebAssembly.Table"); } -JS::Value WebAssemblyTableConstructor::construct(FunctionObject&) +JS::ThrowCompletionOr<JS::Object*> WebAssemblyTableConstructor::construct(FunctionObject&) { auto& vm = this->vm(); auto& global_object = this->global_object(); - auto descriptor = TRY_OR_DISCARD(vm.argument(0).to_object(global_object)); - auto element_value = TRY_OR_DISCARD(descriptor->get("element")); - if (!element_value.is_string()) { - vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::InvalidHint, element_value.to_string_without_side_effects()); - return {}; - } + auto descriptor = TRY(vm.argument(0).to_object(global_object)); + auto element_value = TRY(descriptor->get("element")); + if (!element_value.is_string()) + return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::InvalidHint, element_value.to_string_without_side_effects()); auto& element = element_value.as_string().string(); Optional<Wasm::ValueType> reference_type; @@ -48,27 +45,23 @@ JS::Value WebAssemblyTableConstructor::construct(FunctionObject&) else if (element == "externref"sv) reference_type = Wasm::ValueType(Wasm::ValueType::ExternReference); - if (!reference_type.has_value()) { - vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::InvalidHint, element); - return {}; - } + if (!reference_type.has_value()) + return vm.throw_completion<JS::TypeError>(global_object, JS::ErrorType::InvalidHint, element); - auto initial_value = TRY_OR_DISCARD(descriptor->get("initial")); - auto maximum_value = TRY_OR_DISCARD(descriptor->get("maximum")); + auto initial_value = TRY(descriptor->get("initial")); + auto maximum_value = TRY(descriptor->get("maximum")); - auto initial = TRY_OR_DISCARD(initial_value.to_u32(global_object)); + auto initial = TRY(initial_value.to_u32(global_object)); Optional<u32> maximum; if (!maximum_value.is_undefined()) - maximum = TRY_OR_DISCARD(maximum_value.to_u32(global_object)); + maximum = TRY(maximum_value.to_u32(global_object)); - if (maximum.has_value() && maximum.value() < initial) { - vm.throw_exception<JS::RangeError>(global_object, "maximum should be larger than or equal to initial"); - return {}; - } + if (maximum.has_value() && maximum.value() < initial) + return vm.throw_completion<JS::RangeError>(global_object, "maximum should be larger than or equal to initial"); - auto value_value = TRY_OR_DISCARD(descriptor->get("value")); + auto value_value = TRY(descriptor->get("value")); auto reference_value = [&]() -> Optional<Wasm::Value> { if (value_value.is_undefined()) return Wasm::Value(*reference_type, 0ull); @@ -76,16 +69,14 @@ JS::Value WebAssemblyTableConstructor::construct(FunctionObject&) return to_webassembly_value(value_value, *reference_type, global_object); }(); - if (!reference_value.has_value()) - return {}; + if (auto* exception = vm.exception()) + return JS::throw_completion(exception->value()); auto& reference = reference_value->value().get<Wasm::Reference>(); auto address = WebAssemblyObject::s_abstract_machine.store().allocate(Wasm::TableType { *reference_type, Wasm::Limits { initial, maximum } }); - if (!address.has_value()) { - vm.throw_exception<JS::TypeError>(global_object, "Wasm Table allocation failed"); - return {}; - } + if (!address.has_value()) + return vm.throw_completion<JS::TypeError>(global_object, "Wasm Table allocation failed"); auto& table = *WebAssemblyObject::s_abstract_machine.store().get(*address); for (auto& element : table.elements()) diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.h index 56536a4d58..c6aad1424a 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.h +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssemblyTableConstructor.h @@ -18,8 +18,8 @@ public: virtual void initialize(JS::GlobalObject&) override; virtual ~WebAssemblyTableConstructor() override; - virtual JS::Value call() override; - virtual JS::Value construct(JS::FunctionObject& new_target) override; + virtual JS::ThrowCompletionOr<JS::Value> call() override; + virtual JS::ThrowCompletionOr<JS::Object*> construct(JS::FunctionObject& new_target) override; private: virtual bool has_constructor() const override { return true; } |