diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 3fd931666d5..a0dc6e4f4b3 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -665,16 +665,17 @@ static void generate_to_cpp(SourceGenerator& generator, ParameterType& parameter } } } else if (parameter.type->name() == "Promise") { - // NOTE: It's not clear to me where the implicit wrapping of non-Promise values in a resolved - // Promise is defined in the spec; https://webidl.spec.whatwg.org/#idl-promise doesn't say - // anything of this sort. Both Gecko and Blink do it, however, so I'm sure it's correct. + // https://webidl.spec.whatwg.org/#js-promise scoped_generator.append(R"~~~( - if (!@js_name@@js_suffix@.is_object() || !is(@js_name@@js_suffix@.as_object())) { - auto new_promise = JS::Promise::create(realm); - new_promise->fulfill(@js_name@@js_suffix@); - @js_name@@js_suffix@ = new_promise; + if (!@js_name@@js_suffix@.is_cell() || !is(@js_name@@js_suffix@.as_cell())) { + // 1. Let promiseCapability be ? NewPromiseCapability(%Promise%). + auto promise_capability = TRY(JS::new_promise_capability(vm, realm.intrinsics().promise_constructor())); + // 2. Perform ? Call(promiseCapability.[[Resolve]], undefined, « V »). + TRY(JS::call(vm, *promise_capability->resolve(), JS::js_undefined(), @js_name@@js_suffix@)); + // 3. Return promiseCapability. + @js_name@@js_suffix@ = promise_capability; } - auto @cpp_name@ = JS::make_handle(&static_cast(@js_name@@js_suffix@.as_object())); + auto @cpp_name@ = JS::make_handle(static_cast(@js_name@@js_suffix@.as_cell())); )~~~"); } else if (parameter.type->name() == "object") { if (parameter.type->is_nullable()) { @@ -1794,9 +1795,13 @@ static void generate_wrap_statement(SourceGenerator& generator, ByteString const } } else if (type.is_integer()) { generate_from_integral(scoped_generator, type); - } else if (type.name() == "Location" || type.name() == "Promise" || type.name() == "Uint8Array" || type.name() == "Uint8ClampedArray" || type.name() == "any") { + } else if (type.name() == "Location" || type.name() == "Uint8Array" || type.name() == "Uint8ClampedArray" || type.name() == "any") { scoped_generator.append(R"~~~( @result_expression@ @value@; +)~~~"); + } else if (type.name() == "Promise") { + scoped_generator.append(R"~~~( + @result_expression@ JS::NonnullGCPtr { verify_cast(*@value@->promise()) }; )~~~"); } else if (type.name() == "ArrayBufferView" || type.name() == "BufferSource") { scoped_generator.append(R"~~~( @@ -4243,6 +4248,7 @@ void generate_namespace_implementation(IDL::Interface const& interface, StringBu #include #include #include +#include #include #include #include @@ -4254,6 +4260,7 @@ void generate_namespace_implementation(IDL::Interface const& interface, StringBu #include #include #include +#include #include #include @@ -4663,6 +4670,7 @@ void generate_prototype_implementation(IDL::Interface const& interface, StringBu #include #include #include +#include #include #include #include @@ -4682,8 +4690,9 @@ void generate_prototype_implementation(IDL::Interface const& interface, StringBu #include #include #include -#include #include +#include +#include #include #if __has_include() diff --git a/Userland/Libraries/LibWeb/Animations/Animation.h b/Userland/Libraries/LibWeb/Animations/Animation.h index 41be019afc1..860628a6843 100644 --- a/Userland/Libraries/LibWeb/Animations/Animation.h +++ b/Userland/Libraries/LibWeb/Animations/Animation.h @@ -60,10 +60,10 @@ public: bool pending() const { return m_pending_play_task == TaskState::Scheduled || m_pending_pause_task == TaskState::Scheduled; } // https://www.w3.org/TR/web-animations-1/#dom-animation-ready - JS::NonnullGCPtr ready() const { return *current_ready_promise()->promise(); } + JS::NonnullGCPtr ready() const { return current_ready_promise(); } // https://www.w3.org/TR/web-animations-1/#dom-animation-finished - JS::NonnullGCPtr finished() const { return *current_finished_promise()->promise(); } + JS::NonnullGCPtr finished() const { return current_finished_promise(); } bool is_finished() const { return m_is_finished; } JS::GCPtr onfinish(); diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index 04ad50f3c48..d33fda45083 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -186,19 +187,21 @@ WebIDL::ExceptionOr CSSStyleSheet::delete_rule(unsigned index) } // https://drafts.csswg.org/cssom/#dom-cssstylesheet-replace -JS::NonnullGCPtr CSSStyleSheet::replace(String text) +JS::NonnullGCPtr CSSStyleSheet::replace(String text) { + auto& realm = this->realm(); + // 1. Let promise be a promise - auto promise = JS::Promise::create(realm()); + auto promise = WebIDL::create_promise(realm); // 2. If the constructed flag is not set, or the disallow modification flag is set, reject promise with a NotAllowedError DOMException and return promise. if (!constructed()) { - promise->reject(WebIDL::NotAllowedError::create(realm(), "Can't call replace() on non-constructed stylesheets"_string)); + WebIDL::reject_promise(realm, promise, WebIDL::NotAllowedError::create(realm, "Can't call replace() on non-constructed stylesheets"_string)); return promise; } if (disallow_modification()) { - promise->reject(WebIDL::NotAllowedError::create(realm(), "Can't call replace() on non-modifiable stylesheets"_string)); + WebIDL::reject_promise(realm, promise, WebIDL::NotAllowedError::create(realm, "Can't call replace() on non-modifiable stylesheets"_string)); return promise; } @@ -206,14 +209,16 @@ JS::NonnullGCPtr CSSStyleSheet::replace(String text) set_disallow_modification(true); // 4. In parallel, do these steps: - Platform::EventLoopPlugin::the().deferred_invoke([this, text = move(text), promise] { + Platform::EventLoopPlugin::the().deferred_invoke([&realm, this, text = move(text), promise = JS::Handle(promise)] { + HTML::TemporaryExecutionContext execution_context { HTML::relevant_settings_object(*this), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; + // 1. Let rules be the result of running parse a stylesheet’s contents from text. - auto context = m_style_sheet_list ? CSS::Parser::ParsingContext { m_style_sheet_list->document() } : CSS::Parser::ParsingContext { realm() }; + auto context = m_style_sheet_list ? CSS::Parser::ParsingContext { m_style_sheet_list->document() } : CSS::Parser::ParsingContext { realm }; auto* parsed_stylesheet = parse_css_stylesheet(context, text); auto& rules = parsed_stylesheet->rules(); // 2. If rules contains one or more @import rules, remove those rules from rules. - JS::MarkedVector> rules_without_import(realm().heap()); + JS::MarkedVector> rules_without_import(realm.heap()); for (auto rule : rules) { if (rule->type() != CSSRule::Type::Import) rules_without_import.append(rule); @@ -226,7 +231,7 @@ JS::NonnullGCPtr CSSStyleSheet::replace(String text) set_disallow_modification(false); // 5. Resolve promise with sheet. - promise->fulfill(this); + WebIDL::resolve_promise(realm, *promise, this); }); return promise; diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h index 86f91a3b0f4..eaac750dec5 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.h @@ -53,7 +53,7 @@ public: WebIDL::ExceptionOr remove_rule(Optional index); WebIDL::ExceptionOr delete_rule(unsigned index); - JS::NonnullGCPtr replace(String text); + JS::NonnullGCPtr replace(String text); WebIDL::ExceptionOr replace_sync(StringView text); void for_each_effective_rule(TraversalOrder, Function const& callback) const; diff --git a/Userland/Libraries/LibWeb/CSS/FontFace.cpp b/Userland/Libraries/LibWeb/CSS/FontFace.cpp index 635cb5ed554..0a090ebc0cc 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFace.cpp +++ b/Userland/Libraries/LibWeb/CSS/FontFace.cpp @@ -205,9 +205,9 @@ void FontFace::visit_edges(JS::Cell::Visitor& visitor) visitor.visit(m_font_status_promise); } -JS::NonnullGCPtr FontFace::loaded() const +JS::NonnullGCPtr FontFace::loaded() const { - return verify_cast(*m_font_status_promise->promise()); + return m_font_status_promise; } // https://drafts.csswg.org/css-font-loading/#dom-fontface-family @@ -320,7 +320,7 @@ WebIDL::ExceptionOr FontFace::set_line_gap_override(String const&) } // https://drafts.csswg.org/css-font-loading/#dom-fontface-load -JS::NonnullGCPtr FontFace::load() +JS::NonnullGCPtr FontFace::load() { // 1. Let font face be the FontFace object on which this method was called. auto& font_face = *this; diff --git a/Userland/Libraries/LibWeb/CSS/FontFace.h b/Userland/Libraries/LibWeb/CSS/FontFace.h index 3e577feea22..c074ebb8400 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFace.h +++ b/Userland/Libraries/LibWeb/CSS/FontFace.h @@ -74,8 +74,8 @@ public: Bindings::FontFaceLoadStatus status() const { return m_status; } - JS::NonnullGCPtr load(); - JS::NonnullGCPtr loaded() const; + JS::NonnullGCPtr load(); + JS::NonnullGCPtr loaded() const; void load_font_source(); diff --git a/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp b/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp index 4b7d061f5a5..3cd3dd19cf9 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp +++ b/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp @@ -227,7 +227,7 @@ static WebIDL::ExceptionOr> find_matching_font_faces(J } // https://drafts.csswg.org/css-font-loading/#dom-fontfaceset-load -JS::ThrowCompletionOr> FontFaceSet::load(String const& font, String const& text) +JS::ThrowCompletionOr> FontFaceSet::load(String const& font, String const& text) { auto& realm = this->realm(); @@ -278,18 +278,18 @@ JS::ThrowCompletionOr> FontFaceSet::load(String co }); // 2. Return promise. Complete the rest of these steps asynchronously. - return JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + return promise; } // https://drafts.csswg.org/css-font-loading/#font-face-set-ready -JS::NonnullGCPtr FontFaceSet::ready() const +JS::NonnullGCPtr FontFaceSet::ready() const { - return verify_cast(*m_ready_promise->promise()); + return m_ready_promise; } void FontFaceSet::resolve_ready_promise() { - WebIDL::resolve_promise(realm(), *m_ready_promise); + WebIDL::resolve_promise(realm(), m_ready_promise); } } diff --git a/Userland/Libraries/LibWeb/CSS/FontFaceSet.h b/Userland/Libraries/LibWeb/CSS/FontFaceSet.h index 2b9a4d170be..9cd6e5c34cc 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFaceSet.h +++ b/Userland/Libraries/LibWeb/CSS/FontFaceSet.h @@ -38,9 +38,9 @@ public: void set_onloadingerror(WebIDL::CallbackType*); WebIDL::CallbackType* onloadingerror(); - JS::ThrowCompletionOr> load(String const& font, String const& text); + JS::ThrowCompletionOr> load(String const& font, String const& text); - JS::NonnullGCPtr ready() const; + JS::NonnullGCPtr ready() const; Bindings::FontFaceSetLoadStatus status() const { return m_status; } void resolve_ready_promise(); @@ -52,7 +52,7 @@ private: virtual void visit_edges(Cell::Visitor&) override; JS::NonnullGCPtr m_set_entries; - JS::GCPtr m_ready_promise; // [[ReadyPromise]] + JS::NonnullGCPtr m_ready_promise; // [[ReadyPromise]] Vector> m_loading_fonts {}; // [[LoadingFonts]] Vector> m_loaded_fonts {}; // [[LoadedFonts]] diff --git a/Userland/Libraries/LibWeb/CSS/ScreenOrientation.cpp b/Userland/Libraries/LibWeb/CSS/ScreenOrientation.cpp index 4d641059eaa..c0b0ed04af2 100644 --- a/Userland/Libraries/LibWeb/CSS/ScreenOrientation.cpp +++ b/Userland/Libraries/LibWeb/CSS/ScreenOrientation.cpp @@ -30,7 +30,7 @@ JS::NonnullGCPtr ScreenOrientation::create(JS::Realm& realm) } // https://w3c.github.io/screen-orientation/#lock-method -WebIDL::ExceptionOr> ScreenOrientation::lock(Bindings::OrientationLockType) +WebIDL::ExceptionOr> ScreenOrientation::lock(Bindings::OrientationLockType) { return WebIDL::NotSupportedError::create(realm(), "FIXME: ScreenOrientation::lock() is not implemented"_string); } diff --git a/Userland/Libraries/LibWeb/CSS/ScreenOrientation.h b/Userland/Libraries/LibWeb/CSS/ScreenOrientation.h index 9c839ddc7cc..263dfa0365b 100644 --- a/Userland/Libraries/LibWeb/CSS/ScreenOrientation.h +++ b/Userland/Libraries/LibWeb/CSS/ScreenOrientation.h @@ -20,7 +20,7 @@ class ScreenOrientation final : public DOM::EventTarget { public: [[nodiscard]] static JS::NonnullGCPtr create(JS::Realm&); - WebIDL::ExceptionOr> lock(Bindings::OrientationLockType); + WebIDL::ExceptionOr> lock(Bindings::OrientationLockType); void unlock(); Bindings::OrientationType type() const; WebIDL::UnsignedShort angle() const; diff --git a/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp b/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp index 8aa4191e373..92162ff415b 100644 --- a/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp +++ b/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp @@ -142,7 +142,7 @@ static bool check_clipboard_write_permission(JS::Realm& realm) } // https://w3c.github.io/clipboard-apis/#dom-clipboard-writetext -JS::NonnullGCPtr Clipboard::write_text(String data) +JS::NonnullGCPtr Clipboard::write_text(String data) { // 1. Let realm be this's relevant realm. auto& realm = HTML::relevant_realm(*this); @@ -194,7 +194,7 @@ JS::NonnullGCPtr Clipboard::write_text(String data) }); // 4. Return p. - return JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + return promise; } } diff --git a/Userland/Libraries/LibWeb/Clipboard/Clipboard.h b/Userland/Libraries/LibWeb/Clipboard/Clipboard.h index 761379e487c..4efa1de3ba0 100644 --- a/Userland/Libraries/LibWeb/Clipboard/Clipboard.h +++ b/Userland/Libraries/LibWeb/Clipboard/Clipboard.h @@ -23,7 +23,7 @@ public: static WebIDL::ExceptionOr> construct_impl(JS::Realm&); virtual ~Clipboard() override; - JS::NonnullGCPtr write_text(String); + JS::NonnullGCPtr write_text(String); private: Clipboard(JS::Realm&); diff --git a/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp b/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp index bc03d3fd8b3..8e218153db7 100644 --- a/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp +++ b/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.cpp @@ -121,7 +121,7 @@ WebIDL::ExceptionOr normalize_an_algorithm(JS:: } // https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-encrypt -JS::NonnullGCPtr SubtleCrypto::encrypt(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter) +JS::NonnullGCPtr SubtleCrypto::encrypt(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter) { auto& realm = this->realm(); auto& vm = this->vm(); @@ -174,11 +174,11 @@ JS::NonnullGCPtr SubtleCrypto::encrypt(AlgorithmIdentifier const& a WebIDL::resolve_promise(realm, promise, cipher_text.release_value()); }); - return verify_cast(*promise->promise()); + return promise; } // https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-decrypt -JS::NonnullGCPtr SubtleCrypto::decrypt(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter) +JS::NonnullGCPtr SubtleCrypto::decrypt(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter) { auto& realm = this->realm(); auto& vm = this->vm(); @@ -231,11 +231,11 @@ JS::NonnullGCPtr SubtleCrypto::decrypt(AlgorithmIdentifier const& a WebIDL::resolve_promise(realm, promise, plain_text.release_value()); }); - return verify_cast(*promise->promise()); + return promise; } // https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-digest -JS::NonnullGCPtr SubtleCrypto::digest(AlgorithmIdentifier const& algorithm, JS::Handle const& data) +JS::NonnullGCPtr SubtleCrypto::digest(AlgorithmIdentifier const& algorithm, JS::Handle const& data) { auto& realm = this->realm(); auto& vm = this->vm(); @@ -279,11 +279,11 @@ JS::NonnullGCPtr SubtleCrypto::digest(AlgorithmIdentifier const& al WebIDL::resolve_promise(realm, promise, result.release_value()); }); - return verify_cast(*promise->promise()); + return promise; } // https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-generateKey -JS::ThrowCompletionOr> SubtleCrypto::generate_key(AlgorithmIdentifier algorithm, bool extractable, Vector key_usages) +JS::ThrowCompletionOr> SubtleCrypto::generate_key(AlgorithmIdentifier algorithm, bool extractable, Vector key_usages) { auto& realm = this->realm(); @@ -339,11 +339,11 @@ JS::ThrowCompletionOr> SubtleCrypto::generate_key( }); }); - return verify_cast(*promise->promise()); + return promise; } // https://w3c.github.io/webcrypto/#SubtleCrypto-method-importKey -JS::ThrowCompletionOr> SubtleCrypto::import_key(Bindings::KeyFormat format, KeyDataType key_data, AlgorithmIdentifier algorithm, bool extractable, Vector key_usages) +JS::ThrowCompletionOr> SubtleCrypto::import_key(Bindings::KeyFormat format, KeyDataType key_data, AlgorithmIdentifier algorithm, bool extractable, Vector key_usages) { auto& realm = this->realm(); @@ -415,11 +415,11 @@ JS::ThrowCompletionOr> SubtleCrypto::import_key(Bi WebIDL::resolve_promise(realm, promise, result); }); - return verify_cast(*promise->promise()); + return promise; } // https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-exportKey -JS::ThrowCompletionOr> SubtleCrypto::export_key(Bindings::KeyFormat format, JS::NonnullGCPtr key) +JS::ThrowCompletionOr> SubtleCrypto::export_key(Bindings::KeyFormat format, JS::NonnullGCPtr key) { auto& realm = this->realm(); // 1. Let format and key be the format and key parameters passed to the exportKey() method, respectively. @@ -461,11 +461,11 @@ JS::ThrowCompletionOr> SubtleCrypto::export_key(Bi WebIDL::resolve_promise(realm, promise, result_or_error.release_value()); }); - return verify_cast(*promise->promise()); + return promise; } // https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-sign -JS::ThrowCompletionOr> SubtleCrypto::sign(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter) +JS::ThrowCompletionOr> SubtleCrypto::sign(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter) { auto& realm = this->realm(); auto& vm = this->vm(); @@ -518,11 +518,11 @@ JS::ThrowCompletionOr> SubtleCrypto::sign(Algorith WebIDL::resolve_promise(realm, promise, result.release_value()); }); - return verify_cast(*promise->promise()); + return promise; } // https://w3c.github.io/webcrypto/#dfn-SubtleCrypto-method-verify -JS::ThrowCompletionOr> SubtleCrypto::verify(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& signature_data, JS::Handle const& data_parameter) +JS::ThrowCompletionOr> SubtleCrypto::verify(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& signature_data, JS::Handle const& data_parameter) { auto& realm = this->realm(); auto& vm = this->vm(); @@ -582,11 +582,11 @@ JS::ThrowCompletionOr> SubtleCrypto::verify(Algori WebIDL::resolve_promise(realm, promise, result.release_value()); }); - return verify_cast(*promise->promise()); + return promise; } // https://w3c.github.io/webcrypto/#SubtleCrypto-method-deriveBits -JS::ThrowCompletionOr> SubtleCrypto::derive_bits(AlgorithmIdentifier algorithm, JS::NonnullGCPtr base_key, u32 length) +JS::ThrowCompletionOr> SubtleCrypto::derive_bits(AlgorithmIdentifier algorithm, JS::NonnullGCPtr base_key, u32 length) { auto& realm = this->realm(); // 1. Let algorithm, baseKey and length, be the algorithm, baseKey and length parameters passed to the deriveBits() method, respectively. @@ -629,10 +629,10 @@ JS::ThrowCompletionOr> SubtleCrypto::derive_bits(A WebIDL::resolve_promise(realm, promise, result.release_value()); }); - return verify_cast(*promise->promise()); + return promise; } -JS::ThrowCompletionOr> SubtleCrypto::derive_key(AlgorithmIdentifier algorithm, JS::NonnullGCPtr base_key, AlgorithmIdentifier derived_key_type, bool extractable, Vector key_usages) +JS::ThrowCompletionOr> SubtleCrypto::derive_key(AlgorithmIdentifier algorithm, JS::NonnullGCPtr base_key, AlgorithmIdentifier derived_key_type, bool extractable, Vector key_usages) { auto& realm = this->realm(); auto& vm = this->vm(); @@ -722,7 +722,7 @@ JS::ThrowCompletionOr> SubtleCrypto::derive_key(Al WebIDL::resolve_promise(realm, promise, result.release_value()); }); - return verify_cast(*promise->promise()); + return promise; } SupportedAlgorithmsMap& supported_algorithms_internal() diff --git a/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.h b/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.h index 5109e7cd24d..5c83a1101a9 100644 --- a/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.h +++ b/Userland/Libraries/LibWeb/Crypto/SubtleCrypto.h @@ -27,19 +27,19 @@ public: virtual ~SubtleCrypto() override; - JS::NonnullGCPtr encrypt(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter); - JS::NonnullGCPtr decrypt(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter); - JS::ThrowCompletionOr> sign(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter); - JS::ThrowCompletionOr> verify(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& signature, JS::Handle const& data_parameter); + JS::NonnullGCPtr encrypt(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter); + JS::NonnullGCPtr decrypt(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter); + JS::ThrowCompletionOr> sign(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& data_parameter); + JS::ThrowCompletionOr> verify(AlgorithmIdentifier const& algorithm, JS::NonnullGCPtr key, JS::Handle const& signature, JS::Handle const& data_parameter); - JS::NonnullGCPtr digest(AlgorithmIdentifier const& algorithm, JS::Handle const& data); + JS::NonnullGCPtr digest(AlgorithmIdentifier const& algorithm, JS::Handle const& data); - JS::ThrowCompletionOr> generate_key(AlgorithmIdentifier algorithm, bool extractable, Vector key_usages); - JS::ThrowCompletionOr> derive_bits(AlgorithmIdentifier algorithm, JS::NonnullGCPtr base_key, u32 length); - JS::ThrowCompletionOr> derive_key(AlgorithmIdentifier algorithm, JS::NonnullGCPtr base_key, AlgorithmIdentifier derived_key_type, bool extractable, Vector key_usages); + JS::ThrowCompletionOr> generate_key(AlgorithmIdentifier algorithm, bool extractable, Vector key_usages); + JS::ThrowCompletionOr> derive_bits(AlgorithmIdentifier algorithm, JS::NonnullGCPtr base_key, u32 length); + JS::ThrowCompletionOr> derive_key(AlgorithmIdentifier algorithm, JS::NonnullGCPtr base_key, AlgorithmIdentifier derived_key_type, bool extractable, Vector key_usages); - JS::ThrowCompletionOr> import_key(Bindings::KeyFormat format, KeyDataType key_data, AlgorithmIdentifier algorithm, bool extractable, Vector key_usages); - JS::ThrowCompletionOr> export_key(Bindings::KeyFormat format, JS::NonnullGCPtr key); + JS::ThrowCompletionOr> import_key(Bindings::KeyFormat format, KeyDataType key_data, AlgorithmIdentifier algorithm, bool extractable, Vector key_usages); + JS::ThrowCompletionOr> export_key(Bindings::KeyFormat format, JS::NonnullGCPtr key); private: explicit SubtleCrypto(JS::Realm&); diff --git a/Userland/Libraries/LibWeb/Fetch/Body.cpp b/Userland/Libraries/LibWeb/Fetch/Body.cpp index fd11cfc1638..55227dba128 100644 --- a/Userland/Libraries/LibWeb/Fetch/Body.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Body.cpp @@ -55,7 +55,7 @@ bool BodyMixin::body_used() const } // https://fetch.spec.whatwg.org/#dom-body-arraybuffer -WebIDL::ExceptionOr> BodyMixin::array_buffer() const +WebIDL::ExceptionOr> BodyMixin::array_buffer() const { auto& vm = Bindings::main_thread_vm(); auto& realm = *vm.current_realm(); @@ -65,7 +65,7 @@ WebIDL::ExceptionOr> BodyMixin::array_buffer() con } // https://fetch.spec.whatwg.org/#dom-body-blob -WebIDL::ExceptionOr> BodyMixin::blob() const +WebIDL::ExceptionOr> BodyMixin::blob() const { auto& vm = Bindings::main_thread_vm(); auto& realm = *vm.current_realm(); @@ -75,7 +75,7 @@ WebIDL::ExceptionOr> BodyMixin::blob() const } // https://fetch.spec.whatwg.org/#dom-body-bytes -WebIDL::ExceptionOr> BodyMixin::bytes() const +WebIDL::ExceptionOr> BodyMixin::bytes() const { auto& vm = Bindings::main_thread_vm(); auto& realm = *vm.current_realm(); @@ -85,7 +85,7 @@ WebIDL::ExceptionOr> BodyMixin::bytes() const } // https://fetch.spec.whatwg.org/#dom-body-formdata -WebIDL::ExceptionOr> BodyMixin::form_data() const +WebIDL::ExceptionOr> BodyMixin::form_data() const { auto& vm = Bindings::main_thread_vm(); auto& realm = *vm.current_realm(); @@ -95,7 +95,7 @@ WebIDL::ExceptionOr> BodyMixin::form_data() const } // https://fetch.spec.whatwg.org/#dom-body-json -WebIDL::ExceptionOr> BodyMixin::json() const +WebIDL::ExceptionOr> BodyMixin::json() const { auto& vm = Bindings::main_thread_vm(); auto& realm = *vm.current_realm(); @@ -105,7 +105,7 @@ WebIDL::ExceptionOr> BodyMixin::json() const } // https://fetch.spec.whatwg.org/#dom-body-text -WebIDL::ExceptionOr> BodyMixin::text() const +WebIDL::ExceptionOr> BodyMixin::text() const { auto& vm = Bindings::main_thread_vm(); auto& realm = *vm.current_realm(); @@ -175,7 +175,7 @@ WebIDL::ExceptionOr package_data(JS::Realm& realm, ByteBuffer bytes, } // https://fetch.spec.whatwg.org/#concept-body-consume-body -WebIDL::ExceptionOr> consume_body(JS::Realm& realm, BodyMixin const& object, PackageDataType type) +WebIDL::ExceptionOr> consume_body(JS::Realm& realm, BodyMixin const& object, PackageDataType type) { // 1. If object is unusable, then return a promise rejected with a TypeError. if (object.is_unusable()) { @@ -229,7 +229,7 @@ WebIDL::ExceptionOr> consume_body(JS::Realm& realm } // 7. Return promise. - return JS::NonnullGCPtr { verify_cast(*promise->promise().ptr()) }; + return promise; } } diff --git a/Userland/Libraries/LibWeb/Fetch/Body.h b/Userland/Libraries/LibWeb/Fetch/Body.h index c33256f22c1..f78a35c903e 100644 --- a/Userland/Libraries/LibWeb/Fetch/Body.h +++ b/Userland/Libraries/LibWeb/Fetch/Body.h @@ -39,15 +39,15 @@ public: [[nodiscard]] bool body_used() const; // JS API functions - [[nodiscard]] WebIDL::ExceptionOr> array_buffer() const; - [[nodiscard]] WebIDL::ExceptionOr> blob() const; - [[nodiscard]] WebIDL::ExceptionOr> bytes() const; - [[nodiscard]] WebIDL::ExceptionOr> form_data() const; - [[nodiscard]] WebIDL::ExceptionOr> json() const; - [[nodiscard]] WebIDL::ExceptionOr> text() const; + [[nodiscard]] WebIDL::ExceptionOr> array_buffer() const; + [[nodiscard]] WebIDL::ExceptionOr> blob() const; + [[nodiscard]] WebIDL::ExceptionOr> bytes() const; + [[nodiscard]] WebIDL::ExceptionOr> form_data() const; + [[nodiscard]] WebIDL::ExceptionOr> json() const; + [[nodiscard]] WebIDL::ExceptionOr> text() const; }; [[nodiscard]] WebIDL::ExceptionOr package_data(JS::Realm&, ByteBuffer, PackageDataType, Optional const&); -[[nodiscard]] WebIDL::ExceptionOr> consume_body(JS::Realm&, BodyMixin const&, PackageDataType); +[[nodiscard]] WebIDL::ExceptionOr> consume_body(JS::Realm&, BodyMixin const&, PackageDataType); } diff --git a/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp b/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp index 70eb6be1fc9..e3b7f6bc216 100644 --- a/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp +++ b/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp @@ -26,7 +26,7 @@ namespace Web::Fetch { // https://fetch.spec.whatwg.org/#dom-global-fetch -JS::NonnullGCPtr fetch(JS::VM& vm, RequestInfo const& input, RequestInit const& init) +JS::NonnullGCPtr fetch(JS::VM& vm, RequestInfo const& input, RequestInit const& init) { auto& realm = *vm.current_realm(); @@ -39,7 +39,7 @@ JS::NonnullGCPtr fetch(JS::VM& vm, RequestInfo const& input, Reques if (exception_or_request_object.is_exception()) { auto throw_completion = Bindings::dom_exception_to_throw_completion(vm, exception_or_request_object.exception()); WebIDL::reject_promise(realm, promise_capability, *throw_completion.value()); - return verify_cast(*promise_capability->promise().ptr()); + return promise_capability; } auto request_object = exception_or_request_object.release_value(); @@ -52,7 +52,7 @@ JS::NonnullGCPtr fetch(JS::VM& vm, RequestInfo const& input, Reques abort_fetch(realm, promise_capability, request, nullptr, request_object->signal()->reason()); // 2. Return p. - return verify_cast(*promise_capability->promise().ptr()); + return promise_capability; } // 5. Let globalObject be request’s client’s global object. @@ -150,7 +150,7 @@ JS::NonnullGCPtr fetch(JS::VM& vm, RequestInfo const& input, Reques }); // 13. Return p. - return verify_cast(*promise_capability->promise().ptr()); + return promise_capability; } // https://fetch.spec.whatwg.org/#abort-fetch diff --git a/Userland/Libraries/LibWeb/Fetch/FetchMethod.h b/Userland/Libraries/LibWeb/Fetch/FetchMethod.h index 77b906426cf..f6e27dd614c 100644 --- a/Userland/Libraries/LibWeb/Fetch/FetchMethod.h +++ b/Userland/Libraries/LibWeb/Fetch/FetchMethod.h @@ -14,7 +14,7 @@ namespace Web::Fetch { -JS::NonnullGCPtr fetch(JS::VM&, RequestInfo const& input, RequestInit const& init = {}); +JS::NonnullGCPtr fetch(JS::VM&, RequestInfo const& input, RequestInit const& init = {}); void abort_fetch(JS::Realm&, WebIDL::Promise const&, JS::NonnullGCPtr, JS::GCPtr, JS::Value error); } diff --git a/Userland/Libraries/LibWeb/FileAPI/Blob.cpp b/Userland/Libraries/LibWeb/FileAPI/Blob.cpp index 0c6aad5c1d3..e9fd67127ac 100644 --- a/Userland/Libraries/LibWeb/FileAPI/Blob.cpp +++ b/Userland/Libraries/LibWeb/FileAPI/Blob.cpp @@ -377,7 +377,7 @@ JS::NonnullGCPtr Blob::get_stream() } // https://w3c.github.io/FileAPI/#dom-blob-text -JS::NonnullGCPtr Blob::text() +JS::NonnullGCPtr Blob::text() { auto& realm = this->realm(); auto& vm = realm.vm(); @@ -407,7 +407,7 @@ JS::NonnullGCPtr Blob::text() } // https://w3c.github.io/FileAPI/#dom-blob-arraybuffer -JS::NonnullGCPtr Blob::array_buffer() +JS::NonnullGCPtr Blob::array_buffer() { auto& realm = this->realm(); @@ -434,7 +434,7 @@ JS::NonnullGCPtr Blob::array_buffer() } // https://w3c.github.io/FileAPI/#dom-blob-bytes -JS::NonnullGCPtr Blob::bytes() +JS::NonnullGCPtr Blob::bytes() { auto& realm = this->realm(); diff --git a/Userland/Libraries/LibWeb/FileAPI/Blob.h b/Userland/Libraries/LibWeb/FileAPI/Blob.h index 7746ea185c9..c7f240e280e 100644 --- a/Userland/Libraries/LibWeb/FileAPI/Blob.h +++ b/Userland/Libraries/LibWeb/FileAPI/Blob.h @@ -48,9 +48,9 @@ public: WebIDL::ExceptionOr> slice(Optional start = {}, Optional end = {}, Optional const& content_type = {}); JS::NonnullGCPtr stream(); - JS::NonnullGCPtr text(); - JS::NonnullGCPtr array_buffer(); - JS::NonnullGCPtr bytes(); + JS::NonnullGCPtr text(); + JS::NonnullGCPtr array_buffer(); + JS::NonnullGCPtr bytes(); ReadonlyBytes raw_bytes() const { return m_byte_buffer.bytes(); } diff --git a/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp b/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp index a74154ac7fc..f856495e7f9 100644 --- a/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp +++ b/Userland/Libraries/LibWeb/FileAPI/FileReader.cpp @@ -147,20 +147,23 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti // 10. In parallel, while true: Platform::EventLoopPlugin::the().deferred_invoke([this, chunk_promise, reader, bytes, is_first_chunk, &realm, type, encoding_name, blobs_type]() mutable { - HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm) }; + HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(realm), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; Optional progress_timer; while (true) { auto& vm = realm.vm(); + // FIXME: Try harder to not reach into the [[Promise]] slot of chunkPromise + auto promise = JS::NonnullGCPtr { verify_cast(*chunk_promise->promise()) }; // 1. Wait for chunkPromise to be fulfilled or rejected. + // FIXME: Create spec issue to use WebIDL react to promise steps here instead of this custom logic Platform::EventLoopPlugin::the().spin_until([&]() { - return chunk_promise->state() == JS::Promise::State::Fulfilled || chunk_promise->state() == JS::Promise::State::Rejected; + return promise->state() == JS::Promise::State::Fulfilled || promise->state() == JS::Promise::State::Rejected; }); // 2. If chunkPromise is fulfilled, and isFirstChunk is true, queue a task to fire a progress event called loadstart at fr. // NOTE: ISSUE 2 We might change loadstart to be dispatched synchronously, to align with XMLHttpRequest behavior. [Issue #119] - if (chunk_promise->state() == JS::Promise::State::Fulfilled && is_first_chunk) { + if (promise->state() == JS::Promise::State::Fulfilled && is_first_chunk) { HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), JS::create_heap_function(heap(), [this, &realm]() { dispatch_event(DOM::Event::create(realm, HTML::EventNames::loadstart)); })); @@ -169,14 +172,14 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti // 3. Set isFirstChunk to false. is_first_chunk = false; - VERIFY(chunk_promise->result().is_object()); - auto& result = chunk_promise->result().as_object(); + VERIFY(promise->result().is_object()); + auto& result = promise->result().as_object(); auto value = MUST(result.get(vm.names.value)); auto done = MUST(result.get(vm.names.done)); // 4. If chunkPromise is fulfilled with an object whose done property is false and whose value property is a Uint8Array object, run these steps: - if (chunk_promise->state() == JS::Promise::State::Fulfilled && !done.as_bool() && is(value.as_object())) { + if (promise->state() == JS::Promise::State::Fulfilled && !done.as_bool() && is(value.as_object())) { // 1. Let bs be the byte sequence represented by the Uint8Array object. auto const& byte_sequence = verify_cast(value.as_object()); @@ -200,7 +203,7 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti chunk_promise = reader->read(); } // 5. Otherwise, if chunkPromise is fulfilled with an object whose done property is true, queue a task to run the following steps and abort this algorithm: - else if (chunk_promise->state() == JS::Promise::State::Fulfilled && done.as_bool()) { + else if (promise->state() == JS::Promise::State::Fulfilled && done.as_bool()) { HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), JS::create_heap_function(heap(), [this, bytes, type, &realm, encoding_name, blobs_type]() { // 1. Set fr’s state to "done". m_state = State::Done; @@ -234,7 +237,7 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti return; } // 6. Otherwise, if chunkPromise is rejected with an error error, queue a task to run the following steps and abort this algorithm: - else if (chunk_promise->state() == JS::Promise::State::Rejected) { + else if (promise->state() == JS::Promise::State::Rejected) { HTML::queue_global_task(HTML::Task::Source::FileReading, realm.global_object(), JS::create_heap_function(heap(), [this, &realm]() { // 1. Set fr’s state to "done". m_state = State::Done; @@ -250,6 +253,8 @@ WebIDL::ExceptionOr FileReader::read_operation(Blob& blob, Type type, Opti // 5. Note: Event handler for the error event could have started another load, if that happens the loadend event for this load is not fired. })); + + return; } } }); diff --git a/Userland/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp b/Userland/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp index 327b0d48ab7..2a336572fa4 100644 --- a/Userland/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp +++ b/Userland/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.cpp @@ -313,7 +313,7 @@ JS::ThrowCompletionOr CustomElementRegistry::define(String const& name, We auto promise = promise_when_defined_iterator->value; // 2. Resolve promise with constructor. - promise->fulfill(constructor->callback); + WebIDL::resolve_promise(realm, promise, constructor->callback); // 3. Delete the entry with key name from this CustomElementRegistry's when-defined promise map. m_when_defined_promise_map.remove(name); @@ -353,40 +353,34 @@ Optional CustomElementRegistry::get_name(JS::Handle> CustomElementRegistry::when_defined(String const& name) +WebIDL::ExceptionOr> CustomElementRegistry::when_defined(String const& name) { auto& realm = this->realm(); // 1. If name is not a valid custom element name, then return a new promise rejected with a "SyntaxError" DOMException. - if (!is_valid_custom_element_name(name)) { - auto promise = JS::Promise::create(realm); - promise->reject(WebIDL::SyntaxError::create(realm, MUST(String::formatted("'{}' is not a valid custom element name"sv, name)))); - return promise; - } + if (!is_valid_custom_element_name(name)) + return WebIDL::create_rejected_promise(realm, WebIDL::SyntaxError::create(realm, MUST(String::formatted("'{}' is not a valid custom element name"sv, name)))); // 2. If this CustomElementRegistry contains an entry with name name, then return a new promise resolved with that entry's constructor. auto existing_definition_iterator = m_custom_element_definitions.find_if([&name](JS::Handle const& definition) { return definition->name() == name; }); - if (existing_definition_iterator != m_custom_element_definitions.end()) { - auto promise = JS::Promise::create(realm); - promise->fulfill((*existing_definition_iterator)->constructor().callback); - return promise; - } + if (existing_definition_iterator != m_custom_element_definitions.end()) + return WebIDL::create_resolved_promise(realm, (*existing_definition_iterator)->constructor().callback); // 3. Let map be this CustomElementRegistry's when-defined promise map. // NOTE: Not necessary. // 4. If map does not contain an entry with key name, create an entry in map with key name and whose value is a new promise. // 5. Let promise be the value of the entry in map with key name. - JS::GCPtr promise; + JS::GCPtr promise; auto existing_promise_iterator = m_when_defined_promise_map.find(name); if (existing_promise_iterator != m_when_defined_promise_map.end()) { promise = existing_promise_iterator->value; } else { - promise = JS::Promise::create(realm); + promise = WebIDL::create_promise(realm); m_when_defined_promise_map.set(name, *promise); } diff --git a/Userland/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.h b/Userland/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.h index a20785e012a..a6fc34c68bf 100644 --- a/Userland/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.h +++ b/Userland/Libraries/LibWeb/HTML/CustomElements/CustomElementRegistry.h @@ -27,7 +27,7 @@ public: JS::ThrowCompletionOr define(String const& name, WebIDL::CallbackType* constructor, ElementDefinitionOptions options); Variant, JS::Value> get(String const& name) const; Optional get_name(JS::Handle const& constructor) const; - WebIDL::ExceptionOr> when_defined(String const& name); + WebIDL::ExceptionOr> when_defined(String const& name); void upgrade(JS::NonnullGCPtr root) const; JS::GCPtr get_definition_with_name_and_local_name(String const& name, String const& local_name) const; @@ -48,7 +48,7 @@ private: // https://html.spec.whatwg.org/multipage/custom-elements.html#when-defined-promise-map // Every CustomElementRegistry also has a when-defined promise map, mapping valid custom element names to promises. It is used to implement the whenDefined() method. - OrderedHashMap> m_when_defined_promise_map; + OrderedHashMap> m_when_defined_promise_map; }; } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp index 1dcbc1ec183..1ac132a94ef 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -282,7 +282,7 @@ String HTMLImageElement::current_src() const } // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-decode -WebIDL::ExceptionOr> HTMLImageElement::decode() const +WebIDL::ExceptionOr> HTMLImageElement::decode() const { auto& realm = this->realm(); @@ -360,7 +360,7 @@ WebIDL::ExceptionOr> HTMLImageElement::decode() co }); })); - return JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + return promise; } Optional HTMLImageElement::default_role() const diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h index c02b4d363a4..baed3ad5e38 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h @@ -61,7 +61,7 @@ public: String current_src() const; // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-decode - [[nodiscard]] WebIDL::ExceptionOr> decode() const; + [[nodiscard]] WebIDL::ExceptionOr> decode() const; virtual Optional default_role() const override; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp index 230a4df06e2..cdf25b1d17b 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.cpp @@ -334,7 +334,7 @@ void HTMLMediaElement::set_duration(double duration) paintable->set_needs_display(); } -WebIDL::ExceptionOr> HTMLMediaElement::play() +WebIDL::ExceptionOr> HTMLMediaElement::play() { auto& realm = this->realm(); @@ -355,7 +355,7 @@ WebIDL::ExceptionOr> HTMLMediaElement::play() TRY(play_element()); // 5. Return promise. - return JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + return promise; } // https://html.spec.whatwg.org/multipage/media.html#dom-media-pause diff --git a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h index 82e3949688a..92b0e7d6c2a 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLMediaElement.h @@ -89,7 +89,7 @@ public: bool paused() const { return m_paused; } bool ended() const; bool potentially_playing() const; - WebIDL::ExceptionOr> play(); + WebIDL::ExceptionOr> play(); WebIDL::ExceptionOr pause(); WebIDL::ExceptionOr toggle_playback(); diff --git a/Userland/Libraries/LibWeb/HTML/Navigation.cpp b/Userland/Libraries/LibWeb/HTML/Navigation.cpp index a97144331b9..68719f53dd2 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigation.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigation.cpp @@ -495,14 +495,13 @@ i64 Navigation::get_the_navigation_api_entry_index(SessionHistoryEntry const& sh // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigation-api-early-error-result NavigationResult Navigation::early_error_result(AnyException e) { - auto& vm = this->vm(); + auto& realm = this->realm(); // An early error result for an exception e is a NavigationResult dictionary instance given by // «[ "committed" → a promise rejected with e, "finished" → a promise rejected with e ]». - auto throw_completion = Bindings::dom_exception_to_throw_completion(vm, e); return { - .committed = WebIDL::create_rejected_promise(realm(), *throw_completion.value())->promise(), - .finished = WebIDL::create_rejected_promise(realm(), *throw_completion.value())->promise(), + .committed = WebIDL::create_rejected_promise_from_exception(realm, e), + .finished = WebIDL::create_rejected_promise_from_exception(realm, e), }; } @@ -512,8 +511,8 @@ NavigationResult navigation_api_method_tracker_derived_result(JS::NonnullGCPtrcommitted_promise->promise(), - api_method_tracker->finished_promise->promise(), + api_method_tracker->committed_promise, + api_method_tracker->finished_promise, }; } @@ -639,8 +638,8 @@ WebIDL::ExceptionOr Navigation::perform_a_navigation_api_trave // «[ "committed" → a promise resolved with current, "finished" → a promise resolved with current ]». if (key == current->session_history_entry().navigation_api_key()) { return NavigationResult { - .committed = WebIDL::create_resolved_promise(realm, current)->promise(), - .finished = WebIDL::create_resolved_promise(realm, current)->promise() + .committed = WebIDL::create_resolved_promise(realm, current), + .finished = WebIDL::create_resolved_promise(realm, current) }; } @@ -788,7 +787,7 @@ void Navigation::abort_the_ongoing_navigation(JS::GCPtr er // 11. If navigation's transition is not null, then: if (m_transition != nullptr) { // 1. Reject navigation's transition's finished promise with error. - m_transition->finished()->reject(error); + WebIDL::reject_promise(realm, m_transition->finished(), error); // 2. Set navigation's transition to null. m_transition = nullptr; @@ -1105,10 +1104,10 @@ bool Navigation::inner_navigate_event_firing_algorithm( // 4. Set navigation's transition to a new NavigationTransition created in navigation's relevant realm, // whose navigation type is navigationType, from entry is fromNHE, and whose finished promise is a new promise // created in navigation's relevant realm. - m_transition = NavigationTransition::create(realm, navigation_type, *from_nhe, JS::Promise::create(realm)); + m_transition = NavigationTransition::create(realm, navigation_type, *from_nhe, WebIDL::create_promise(realm)); // 5. Mark as handled navigation's transition's finished promise. - m_transition->finished()->set_is_handled(); + WebIDL::mark_promise_as_handled(*m_transition->finished()); // 6. If navigationType is "traverse", then set navigation's suppress normal scroll restoration during ongoing navigation to true. // NOTE: If event's scroll behavior was set to "after-transition", then scroll restoration will happen as part of finishing @@ -1187,7 +1186,7 @@ bool Navigation::inner_navigate_event_firing_algorithm( // 8. If navigation's transition is not null, then resolve navigation's transition's finished promise with undefined. if (m_transition != nullptr) - m_transition->finished()->fulfill(JS::js_undefined()); + WebIDL::resolve_promise(realm, m_transition->finished(), JS::js_undefined()); // 9. Set navigation's transition to null. m_transition = nullptr; }, @@ -1231,7 +1230,7 @@ bool Navigation::inner_navigate_event_firing_algorithm( // 9. If navigation's transition is not null, then reject navigation's transition's finished promise with rejectionReason. if (m_transition) - m_transition->finished()->reject(rejection_reason); + WebIDL::reject_promise(realm, m_transition->finished(), rejection_reason); // 10. Set navigation's transition to null. m_transition = nullptr; diff --git a/Userland/Libraries/LibWeb/HTML/Navigation.h b/Userland/Libraries/LibWeb/HTML/Navigation.h index 25319147e18..1246b6ebcd4 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigation.h +++ b/Userland/Libraries/LibWeb/HTML/Navigation.h @@ -39,9 +39,8 @@ struct NavigationReloadOptions : public NavigationOptions { // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigationresult struct NavigationResult { - // FIXME: Are we supposed to return a PromiseCapability (WebIDL::Promise) here? - JS::NonnullGCPtr committed; - JS::NonnullGCPtr finished; + JS::NonnullGCPtr committed; + JS::NonnullGCPtr finished; }; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigation-api-method-tracker diff --git a/Userland/Libraries/LibWeb/HTML/NavigationTransition.cpp b/Userland/Libraries/LibWeb/HTML/NavigationTransition.cpp index 9d953116b14..43373240858 100644 --- a/Userland/Libraries/LibWeb/HTML/NavigationTransition.cpp +++ b/Userland/Libraries/LibWeb/HTML/NavigationTransition.cpp @@ -5,23 +5,23 @@ */ #include -#include #include #include #include #include #include +#include namespace Web::HTML { JS_DEFINE_ALLOCATOR(NavigationTransition); -JS::NonnullGCPtr NavigationTransition::create(JS::Realm& realm, Bindings::NavigationType navigation_type, JS::NonnullGCPtr from_entry, JS::GCPtr finished_promise) +JS::NonnullGCPtr NavigationTransition::create(JS::Realm& realm, Bindings::NavigationType navigation_type, JS::NonnullGCPtr from_entry, JS::NonnullGCPtr finished_promise) { return realm.heap().allocate(realm, realm, navigation_type, from_entry, finished_promise); } -NavigationTransition::NavigationTransition(JS::Realm& realm, Bindings::NavigationType navigation_type, JS::NonnullGCPtr from_entry, JS::GCPtr finished_promise) +NavigationTransition::NavigationTransition(JS::Realm& realm, Bindings::NavigationType navigation_type, JS::NonnullGCPtr from_entry, JS::NonnullGCPtr finished_promise) : Bindings::PlatformObject(realm) , m_navigation_type(navigation_type) , m_from_entry(from_entry) diff --git a/Userland/Libraries/LibWeb/HTML/NavigationTransition.h b/Userland/Libraries/LibWeb/HTML/NavigationTransition.h index b049b8b8386..6fdec435679 100644 --- a/Userland/Libraries/LibWeb/HTML/NavigationTransition.h +++ b/Userland/Libraries/LibWeb/HTML/NavigationTransition.h @@ -17,7 +17,7 @@ class NavigationTransition : public Bindings::PlatformObject { JS_DECLARE_ALLOCATOR(NavigationTransition); public: - [[nodiscard]] static JS::NonnullGCPtr create(JS::Realm&, Bindings::NavigationType, JS::NonnullGCPtr, JS::GCPtr); + [[nodiscard]] static JS::NonnullGCPtr create(JS::Realm&, Bindings::NavigationType, JS::NonnullGCPtr, JS::NonnullGCPtr); // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigationtransition-navigationtype Bindings::NavigationType navigation_type() const { return m_navigation_type; } @@ -26,12 +26,12 @@ public: JS::NonnullGCPtr from() const { return m_from_entry; } // https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-navigationtransition-finished - JS::GCPtr finished() const { return m_finished_promise; } + JS::NonnullGCPtr finished() const { return m_finished_promise; } virtual ~NavigationTransition() override; private: - NavigationTransition(JS::Realm&, Bindings::NavigationType, JS::NonnullGCPtr, JS::GCPtr); + NavigationTransition(JS::Realm&, Bindings::NavigationType, JS::NonnullGCPtr, JS::NonnullGCPtr); virtual void initialize(JS::Realm&) override; virtual void visit_edges(JS::Cell::Visitor&) override; @@ -43,7 +43,7 @@ private: JS::NonnullGCPtr m_from_entry; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigationtransition-finished - JS::GCPtr m_finished_promise; + JS::NonnullGCPtr m_finished_promise; }; } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.h b/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.h index 88dc90f7c4e..dc260b26c5a 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.h @@ -6,6 +6,7 @@ #pragma once +#include #include namespace Web::HTML { diff --git a/Userland/Libraries/LibWeb/HTML/ServiceWorkerContainer.cpp b/Userland/Libraries/LibWeb/HTML/ServiceWorkerContainer.cpp index aeb6f0cf714..57a0e9f4663 100644 --- a/Userland/Libraries/LibWeb/HTML/ServiceWorkerContainer.cpp +++ b/Userland/Libraries/LibWeb/HTML/ServiceWorkerContainer.cpp @@ -44,7 +44,7 @@ JS::NonnullGCPtr ServiceWorkerContainer::create(JS::Real } // https://w3c.github.io/ServiceWorker/#navigator-service-worker-register -JS::NonnullGCPtr ServiceWorkerContainer::register_(String script_url, RegistrationOptions const& options) +JS::NonnullGCPtr ServiceWorkerContainer::register_(String script_url, RegistrationOptions const& options) { auto& realm = this->realm(); // Note: The register(scriptURL, options) method creates or updates a service worker registration for the given scope url. @@ -76,7 +76,7 @@ JS::NonnullGCPtr ServiceWorkerContainer::register_(String script_ur start_register(scope_url, parsed_script_url, p, client, client->creation_url, options.type, options.update_via_cache); // 8. Return p. - return verify_cast(*p->promise()); + return p; } // https://w3c.github.io/ServiceWorker/#start-register-algorithm diff --git a/Userland/Libraries/LibWeb/HTML/ServiceWorkerContainer.h b/Userland/Libraries/LibWeb/HTML/ServiceWorkerContainer.h index 18dc26ed418..707a9db1979 100644 --- a/Userland/Libraries/LibWeb/HTML/ServiceWorkerContainer.h +++ b/Userland/Libraries/LibWeb/HTML/ServiceWorkerContainer.h @@ -34,7 +34,7 @@ public: [[nodiscard]] static JS::NonnullGCPtr create(JS::Realm& realm); virtual ~ServiceWorkerContainer() override; - JS::NonnullGCPtr register_(String script_url, RegistrationOptions const& options); + JS::NonnullGCPtr register_(String script_url, RegistrationOptions const& options); #undef __ENUMERATE #define __ENUMERATE(attribute_name, event_name) \ diff --git a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp index bee9b77ff64..b9b975afa11 100644 --- a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp +++ b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -166,25 +167,26 @@ void WindowOrWorkerGlobalScopeMixin::queue_microtask(WebIDL::CallbackType& callb } // https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap -JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, Optional options) const +JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, Optional options) const { return create_image_bitmap_impl(image, {}, {}, {}, {}, options); } // https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap -JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, WebIDL::Long sx, WebIDL::Long sy, WebIDL::Long sw, WebIDL::Long sh, Optional options) const +JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, WebIDL::Long sx, WebIDL::Long sy, WebIDL::Long sw, WebIDL::Long sh, Optional options) const { return create_image_bitmap_impl(image, sx, sy, sw, sh, options); } -JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_bitmap_impl(ImageBitmapSource& image, Optional sx, Optional sy, Optional sw, Optional sh, Optional& options) const +JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_bitmap_impl(ImageBitmapSource& image, Optional sx, Optional sy, Optional sw, Optional sh, Optional& options) const { + auto& realm = this_impl().realm(); + // 1. If either sw or sh is given and is 0, then return a promise rejected with a RangeError. if (sw == 0 || sh == 0) { - auto promise = JS::Promise::create(this_impl().realm()); auto error_message = MUST(String::formatted("{} is an invalid value for {}", sw == 0 ? *sw : *sh, sw == 0 ? "sw"sv : "sh"sv)); - promise->reject(JS::RangeError::create(this_impl().realm(), move(error_message))); - return promise; + auto error = JS::RangeError::create(realm, move(error_message)); + return WebIDL::create_rejected_promise(realm, move(error)); } // FIXME: @@ -195,14 +197,13 @@ JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_bitma // FIXME: "Check the usability of the image argument" is only defined for CanvasImageSource, let's skip it for other types if (image.has()) { if (auto usability = check_usability_of_image(image.get()); usability.is_error() or usability.value() == CanvasImageSourceUsability::Bad) { - auto promise = JS::Promise::create(this_impl().realm()); - promise->reject(WebIDL::InvalidStateError::create(this_impl().realm(), "image argument is not usable"_string)); - return promise; + auto error = WebIDL::InvalidStateError::create(this_impl().realm(), "image argument is not usable"_string); + return WebIDL::create_rejected_promise_from_exception(realm, error); } } // 4. Let p be a new promise. - auto p = JS::Promise::create(this_impl().realm()); + auto p = WebIDL::create_promise(realm); // 5. Let imageBitmap be a new ImageBitmap object. auto image_bitmap = ImageBitmap::create(this_impl().realm()); @@ -226,7 +227,9 @@ JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_bitma // imageData is corrupted in some fatal way such that the image dimensions cannot be obtained // (e.g., a vector graphic with no natural size), then reject p with an "InvalidStateError" DOMException // and abort these steps. - p->reject(WebIDL::InvalidStateError::create(relevant_realm(*p), "image does not contain a supported image format"_string)); + auto& realm = relevant_realm(p->promise()); + TemporaryExecutionContext context { relevant_settings_object(p->promise()), TemporaryExecutionContext::CallbacksEnabled::Yes }; + WebIDL::reject_promise(realm, *p, WebIDL::InvalidStateError::create(realm, "image does not contain a supported image format"_string)); }; auto on_successful_decode = [image_bitmap = JS::Handle(*image_bitmap), p = JS::Handle(*p)](Web::Platform::DecodedImage& result) -> ErrorOr { @@ -236,8 +239,11 @@ JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_bitma // or is disabled), or, if there is no such image, the first frame of the animation. image_bitmap->set_bitmap(result.frames.take_first().bitmap); + auto& realm = relevant_realm(p->promise()); + // 5. Resolve p with imageBitmap. - p->fulfill(image_bitmap); + TemporaryExecutionContext context { relevant_settings_object(*image_bitmap), TemporaryExecutionContext::CallbacksEnabled::Yes }; + WebIDL::resolve_promise(realm, *p, image_bitmap); return {}; }; @@ -248,7 +254,9 @@ JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::create_image_bitma dbgln("(STUBBED) createImageBitmap() for non-blob types"); (void)sx; (void)sy; - p->reject(JS::Error::create(relevant_realm(*p), "Not Implemented: createImageBitmap() for non-blob types"sv)); + auto error = JS::Error::create(realm, "Not Implemented: createImageBitmap() for non-blob types"sv); + TemporaryExecutionContext context { relevant_settings_object(p->promise()), TemporaryExecutionContext::CallbacksEnabled::Yes }; + WebIDL::reject_promise(realm, *p, error); }); // 7. Return p. @@ -273,7 +281,7 @@ WebIDL::ExceptionOr WindowOrWorkerGlobalScopeMixin::structured_clone( return deserialized; } -JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::fetch(Fetch::RequestInfo const& input, Fetch::RequestInit const& init) const +JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::fetch(Fetch::RequestInfo const& input, Fetch::RequestInit const& init) const { auto& vm = this_impl().vm(); return Fetch::fetch(vm, input, init); @@ -926,7 +934,7 @@ void WindowOrWorkerGlobalScopeMixin::notify_about_rejected_promises(Badgeresult(), }; diff --git a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h index 5414c0b1163..ca387655013 100644 --- a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h +++ b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h @@ -39,10 +39,10 @@ public: WebIDL::ExceptionOr btoa(String const& data) const; WebIDL::ExceptionOr atob(String const& data) const; void queue_microtask(WebIDL::CallbackType&); - JS::NonnullGCPtr create_image_bitmap(ImageBitmapSource image, Optional options = {}) const; - JS::NonnullGCPtr create_image_bitmap(ImageBitmapSource image, WebIDL::Long sx, WebIDL::Long sy, WebIDL::Long sw, WebIDL::Long sh, Optional options = {}) const; + JS::NonnullGCPtr create_image_bitmap(ImageBitmapSource image, Optional options = {}) const; + JS::NonnullGCPtr create_image_bitmap(ImageBitmapSource image, WebIDL::Long sx, WebIDL::Long sy, WebIDL::Long sw, WebIDL::Long sh, Optional options = {}) const; WebIDL::ExceptionOr structured_clone(JS::Value, StructuredSerializeOptions const&) const; - JS::NonnullGCPtr fetch(Fetch::RequestInfo const&, Fetch::RequestInit const&) const; + JS::NonnullGCPtr fetch(Fetch::RequestInfo const&, Fetch::RequestInit const&) const; i32 set_timeout(TimerHandler, i32 timeout, JS::MarkedVector arguments); i32 set_interval(TimerHandler, i32 timeout, JS::MarkedVector arguments); @@ -105,7 +105,7 @@ private: i32 run_timer_initialization_steps(TimerHandler handler, i32 timeout, JS::MarkedVector arguments, Repeat repeat, Optional previous_id = {}); void run_steps_after_a_timeout_impl(i32 timeout, Function completion_step, Optional timer_key = {}); - JS::NonnullGCPtr create_image_bitmap_impl(ImageBitmapSource& image, Optional sx, Optional sy, Optional sw, Optional sh, Optional& options) const; + JS::NonnullGCPtr create_image_bitmap_impl(ImageBitmapSource& image, Optional sx, Optional sy, Optional sw, Optional sh, Optional& options) const; IDAllocator m_timer_id_allocator; HashMap> m_timers; diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp index 97174cd619e..589cb1f609d 100644 --- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -131,7 +131,7 @@ JS::NonnullGCPtr readable_stream_cancel(ReadableStream& stream, JS::create_heap_function(stream.heap(), [](JS::Value) -> WebIDL::ExceptionOr { return JS::js_undefined(); }), {}); - return WebIDL::create_resolved_promise(realm, react_result); + return react_result; } // https://streams.spec.whatwg.org/#readable-stream-fulfill-read-into-request @@ -431,9 +431,9 @@ public: // 3. Resolve cancelPromise with ! ReadableStreamCancel(stream, cloneResult.[[Value]]). auto cancel_result = readable_stream_cancel(m_stream, completion.value().value()); - JS::NonnullGCPtr cancel_value = verify_cast(*cancel_result->promise().ptr()); - WebIDL::resolve_promise(m_realm, m_cancel_promise, cancel_value); + // Note: We need to manually convert the result to an ECMAScript value here, by extracting its [[Promise]] slot. + WebIDL::resolve_promise(m_realm, m_cancel_promise, cancel_result->promise()); // 4. Return. return; @@ -584,8 +584,7 @@ WebIDL::ExceptionOr readable_stream_default_tee(JS::Realm& r auto cancel_result = readable_stream_cancel(stream, composite_reason); // 3. Resolve cancelPromise with cancelResult. - JS::NonnullGCPtr cancel_value = verify_cast(*cancel_result->promise().ptr()); - WebIDL::resolve_promise(realm, cancel_promise, cancel_value); + WebIDL::resolve_promise(realm, cancel_promise, cancel_result->promise()); } // 4. Return cancelPromise. @@ -609,8 +608,7 @@ WebIDL::ExceptionOr readable_stream_default_tee(JS::Realm& r auto cancel_result = readable_stream_cancel(stream, composite_reason); // 3. Resolve cancelPromise with cancelResult. - JS::NonnullGCPtr cancel_value = verify_cast(*cancel_result->promise().ptr()); - WebIDL::resolve_promise(realm, cancel_promise, cancel_value); + WebIDL::resolve_promise(realm, cancel_promise, cancel_result->promise()); } // 4. Return cancelPromise. @@ -744,9 +742,8 @@ public: // 3. Resolve cancelPromise with ! ReadableStreamCancel(stream, cloneResult.[[Value]]). auto cancel_result = readable_stream_cancel(m_stream, completion.value().value()); - JS::NonnullGCPtr cancel_value = verify_cast(*cancel_result->promise().ptr()); - WebIDL::resolve_promise(m_realm, m_cancel_promise, cancel_value); + WebIDL::resolve_promise(m_realm, m_cancel_promise, cancel_result->promise()); // 4. Return. return; @@ -909,9 +906,8 @@ public: // 3. Resolve cancelPromise with ! ReadableStreamCancel(stream, cloneResult.[[Value]]). auto cancel_result = readable_stream_cancel(m_stream, completion.value().value()); - JS::NonnullGCPtr cancel_value = verify_cast(*cancel_result->promise().ptr()); - WebIDL::resolve_promise(m_realm, m_cancel_promise, cancel_value); + WebIDL::resolve_promise(m_realm, m_cancel_promise, cancel_result->promise()); // 4. Return. return; @@ -1221,8 +1217,7 @@ WebIDL::ExceptionOr readable_byte_stream_tee(JS::Realm& real auto cancel_result = readable_stream_cancel(stream, composite_reason); // 3. Resolve cancelPromise with cancelResult. - JS::NonnullGCPtr cancel_value = verify_cast(*cancel_result->promise().ptr()); - WebIDL::resolve_promise(realm, cancel_promise, cancel_value); + WebIDL::resolve_promise(realm, cancel_promise, cancel_result->promise()); } // 4. Return cancelPromise. @@ -1246,8 +1241,7 @@ WebIDL::ExceptionOr readable_byte_stream_tee(JS::Realm& real auto cancel_result = readable_stream_cancel(stream, composite_reason); // 3. Resolve cancelPromise with cancelResult. - JS::NonnullGCPtr cancel_value = verify_cast(*cancel_result->promise().ptr()); - WebIDL::resolve_promise(realm, cancel_promise, cancel_value); + WebIDL::resolve_promise(realm, cancel_promise, cancel_result->promise()); } // 4. Return cancelPromise. @@ -1442,7 +1436,7 @@ WebIDL::ExceptionOr> readable_stream_from_itera }), {}); - return WebIDL::create_resolved_promise(realm, react_result); + return react_result; }); // 5. Let cancelAlgorithm be the following steps, given reason: @@ -1483,7 +1477,7 @@ WebIDL::ExceptionOr> readable_stream_from_itera }), {}); - return WebIDL::create_resolved_promise(realm, react_result); + return react_result; }); // 6. Set stream to ! CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, 0). @@ -4711,7 +4705,7 @@ void writable_stream_default_controller_write(WritableStreamDefaultController& c } // https://streams.spec.whatwg.org/#initialize-transform-stream -void initialize_transform_stream(TransformStream& stream, JS::NonnullGCPtr start_promise, double writable_high_water_mark, JS::NonnullGCPtr writable_size_algorithm, double readable_high_water_mark, JS::NonnullGCPtr readable_size_algorithm) +void initialize_transform_stream(TransformStream& stream, JS::NonnullGCPtr start_promise, double writable_high_water_mark, JS::NonnullGCPtr writable_size_algorithm, double readable_high_water_mark, JS::NonnullGCPtr readable_size_algorithm) { auto& realm = stream.realm(); @@ -4970,7 +4964,7 @@ JS::NonnullGCPtr transform_stream_default_controller_perform_tr return JS::throw_completion(reason); })); - return WebIDL::create_resolved_promise(realm, react_result); + return react_result; } // https://streams.spec.whatwg.org/#transform-stream-default-sink-abort-algorithm @@ -5031,7 +5025,7 @@ JS::NonnullGCPtr transform_stream_default_sink_abort_algorithm( })); // 8. Return controller.[[finishPromise]]. - return JS::NonnullGCPtr { *controller->finish_promise() }; + return *controller->finish_promise(); } // https://streams.spec.whatwg.org/#transform-stream-default-sink-close-algorithm @@ -5075,7 +5069,7 @@ JS::NonnullGCPtr transform_stream_default_sink_close_algorithm( return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, readable->stored_error().as_string().utf8_string() }; })); - return WebIDL::create_resolved_promise(realm, react_result); + return react_result; } // https://streams.spec.whatwg.org/#transform-stream-default-sink-write-algorithm @@ -5118,7 +5112,7 @@ JS::NonnullGCPtr transform_stream_default_sink_write_algorithm( }), {}); - return WebIDL::create_resolved_promise(realm, react_result); + return react_result; } // 4. Return ! TransformStreamDefaultControllerPerformTransform(controller, chunk). @@ -5196,7 +5190,7 @@ JS::NonnullGCPtr transform_stream_default_source_cancel_algorit })); // 8. Return controller.[[finishPromise]]. - return JS::NonnullGCPtr { *controller->finish_promise() }; + return *controller->finish_promise(); } // https://streams.spec.whatwg.org/#transform-stream-error diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.h b/Userland/Libraries/LibWeb/Streams/AbstractOperations.h index 30ca7ed6e38..437edb5c9b5 100644 --- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.h +++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.h @@ -168,7 +168,7 @@ void writable_stream_default_controller_process_close(WritableStreamDefaultContr void writable_stream_default_controller_process_write(WritableStreamDefaultController&, JS::Value chunk); void writable_stream_default_controller_write(WritableStreamDefaultController&, JS::Value chunk, JS::Value chunk_size); -void initialize_transform_stream(TransformStream&, JS::NonnullGCPtr start_promise, double writable_high_water_mark, JS::NonnullGCPtr writable_size_algorithm, double readable_high_water_mark, JS::NonnullGCPtr readable_size_algorithm); +void initialize_transform_stream(TransformStream&, JS::NonnullGCPtr start_promise, double writable_high_water_mark, JS::NonnullGCPtr writable_size_algorithm, double readable_high_water_mark, JS::NonnullGCPtr readable_size_algorithm); void set_up_transform_stream_default_controller(TransformStream&, TransformStreamDefaultController&, JS::NonnullGCPtr, JS::NonnullGCPtr, JS::NonnullGCPtr); void set_up_transform_stream_default_controller_from_transformer(TransformStream&, JS::Value transformer, Transformer&); void transform_stream_default_controller_clear_algorithms(TransformStreamDefaultController&); diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStream.cpp b/Userland/Libraries/LibWeb/Streams/ReadableStream.cpp index a5dc13cd196..748aeae8fbb 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStream.cpp +++ b/Userland/Libraries/LibWeb/Streams/ReadableStream.cpp @@ -90,18 +90,18 @@ bool ReadableStream::locked() const } // https://streams.spec.whatwg.org/#rs-cancel -JS::NonnullGCPtr ReadableStream::cancel(JS::Value reason) +JS::NonnullGCPtr ReadableStream::cancel(JS::Value reason) { auto& realm = this->realm(); // 1. If ! IsReadableStreamLocked(this) is true, return a promise rejected with a TypeError exception. if (is_readable_stream_locked(*this)) { auto exception = JS::TypeError::create(realm, "Cannot cancel a locked stream"sv); - return WebIDL::create_rejected_promise(realm, JS::Value { exception })->promise(); + return WebIDL::create_rejected_promise(realm, exception); } // 2. Return ! ReadableStreamCancel(this, reason). - return readable_stream_cancel(*this, reason)->promise(); + return readable_stream_cancel(*this, reason); } // https://streams.spec.whatwg.org/#rs-get-reader @@ -141,29 +141,26 @@ WebIDL::ExceptionOr> ReadableStream::pipe_throu return JS::NonnullGCPtr { *transform.readable }; } -JS::NonnullGCPtr ReadableStream::pipe_to(WritableStream& destination, StreamPipeOptions const& options) +JS::NonnullGCPtr ReadableStream::pipe_to(WritableStream& destination, StreamPipeOptions const& options) { auto& realm = this->realm(); + auto& vm = realm.vm(); // 1. If ! IsReadableStreamLocked(this) is true, return a promise rejected with a TypeError exception. if (is_readable_stream_locked(*this)) { - auto promise = WebIDL::create_promise(realm); - WebIDL::reject_promise(realm, promise, JS::TypeError::create(realm, "Failed to execute 'pipeTo' on 'ReadableStream': Cannot pipe a locked stream"sv)); - return promise->promise(); + return WebIDL::create_rejected_promise_from_exception(realm, vm.throw_completion("Failed to execute 'pipeTo' on 'ReadableStream': Cannot pipe a locked stream"sv)); } // 2. If ! IsWritableStreamLocked(destination) is true, return a promise rejected with a TypeError exception. if (is_writable_stream_locked(destination)) { - auto promise = WebIDL::create_promise(realm); - WebIDL::reject_promise(realm, promise, JS::TypeError::create(realm, "Failed to execute 'pipeTo' on 'ReadableStream': Cannot pipe to a locked stream"sv)); - return promise->promise(); + return WebIDL::create_rejected_promise_from_exception(realm, vm.throw_completion("Failed to execute 'pipeTo' on 'ReadableStream': Cannot pipe to a locked stream"sv)); } // 3. Let signal be options["signal"] if it exists, or undefined otherwise. auto signal = options.signal ? JS::Value(options.signal) : JS::js_undefined(); // 4. Return ! ReadableStreamPipeTo(this, destination, options["preventClose"], options["preventAbort"], options["preventCancel"], signal). - return readable_stream_pipe_to(*this, destination, options.prevent_close, options.prevent_abort, options.prevent_cancel, signal)->promise(); + return readable_stream_pipe_to(*this, destination, options.prevent_close, options.prevent_abort, options.prevent_cancel, signal); } // https://streams.spec.whatwg.org/#readablestream-tee diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStream.h b/Userland/Libraries/LibWeb/Streams/ReadableStream.h index ff9bcc0b573..621af87a3b1 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStream.h +++ b/Userland/Libraries/LibWeb/Streams/ReadableStream.h @@ -75,10 +75,10 @@ public: virtual ~ReadableStream() override; bool locked() const; - JS::NonnullGCPtr cancel(JS::Value reason); + JS::NonnullGCPtr cancel(JS::Value reason); WebIDL::ExceptionOr get_reader(ReadableStreamGetReaderOptions const& = {}); WebIDL::ExceptionOr> pipe_through(ReadableWritablePair transform, StreamPipeOptions const& = {}); - JS::NonnullGCPtr pipe_to(WritableStream& destination, StreamPipeOptions const& = {}); + JS::NonnullGCPtr pipe_to(WritableStream& destination, StreamPipeOptions const& = {}); WebIDL::ExceptionOr tee(); void close(); diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStreamBYOBReader.cpp b/Userland/Libraries/LibWeb/Streams/ReadableStreamBYOBReader.cpp index 3861c1f5926..8e2dc7f5a5b 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStreamBYOBReader.cpp +++ b/Userland/Libraries/LibWeb/Streams/ReadableStreamBYOBReader.cpp @@ -107,7 +107,7 @@ private: JS_DEFINE_ALLOCATOR(BYOBReaderReadIntoRequest); // https://streams.spec.whatwg.org/#byob-reader-read -JS::NonnullGCPtr ReadableStreamBYOBReader::read(JS::Handle& view, ReadableStreamBYOBReaderReadOptions options) +JS::NonnullGCPtr ReadableStreamBYOBReader::read(JS::Handle& view, ReadableStreamBYOBReaderReadOptions options) { auto& realm = this->realm(); @@ -177,6 +177,6 @@ JS::NonnullGCPtr ReadableStreamBYOBReader::read(JS::Handle(*promise_capability->promise()) }; + return promise_capability; } } diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStreamBYOBReader.h b/Userland/Libraries/LibWeb/Streams/ReadableStreamBYOBReader.h index 264ef5437f8..0cccd7f4795 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStreamBYOBReader.h +++ b/Userland/Libraries/LibWeb/Streams/ReadableStreamBYOBReader.h @@ -51,7 +51,7 @@ public: virtual ~ReadableStreamBYOBReader() override = default; - JS::NonnullGCPtr read(JS::Handle&, ReadableStreamBYOBReaderReadOptions options = {}); + JS::NonnullGCPtr read(JS::Handle&, ReadableStreamBYOBReaderReadOptions options = {}); void release_lock(); diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStreamDefaultReader.cpp b/Userland/Libraries/LibWeb/Streams/ReadableStreamDefaultReader.cpp index cd5ff70a3fc..40e455a19f5 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStreamDefaultReader.cpp +++ b/Userland/Libraries/LibWeb/Streams/ReadableStreamDefaultReader.cpp @@ -162,7 +162,7 @@ private: JS_DEFINE_ALLOCATOR(DefaultReaderReadRequest); // https://streams.spec.whatwg.org/#default-reader-read -JS::NonnullGCPtr ReadableStreamDefaultReader::read() +JS::NonnullGCPtr ReadableStreamDefaultReader::read() { auto& realm = this->realm(); @@ -188,7 +188,7 @@ JS::NonnullGCPtr ReadableStreamDefaultReader::read() readable_stream_default_reader_read(*this, read_request); // 5. Return promise. - return JS::NonnullGCPtr { verify_cast(*promise_capability->promise()) }; + return promise_capability; } void ReadableStreamDefaultReader::read_a_chunk(Fetch::Infrastructure::IncrementalReadLoopReadRequest& read_request) diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStreamDefaultReader.h b/Userland/Libraries/LibWeb/Streams/ReadableStreamDefaultReader.h index 0d69271b942..ad2cdd75483 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStreamDefaultReader.h +++ b/Userland/Libraries/LibWeb/Streams/ReadableStreamDefaultReader.h @@ -77,7 +77,7 @@ public: virtual ~ReadableStreamDefaultReader() override = default; - JS::NonnullGCPtr read(); + JS::NonnullGCPtr read(); void read_a_chunk(Fetch::Infrastructure::IncrementalReadLoopReadRequest& read_request); void read_all_bytes(JS::NonnullGCPtr, JS::NonnullGCPtr); diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStreamGenericReader.cpp b/Userland/Libraries/LibWeb/Streams/ReadableStreamGenericReader.cpp index 4a75b695ff7..423293aac45 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStreamGenericReader.cpp +++ b/Userland/Libraries/LibWeb/Streams/ReadableStreamGenericReader.cpp @@ -14,14 +14,14 @@ namespace Web::Streams { // https://streams.spec.whatwg.org/#generic-reader-closed -JS::GCPtr ReadableStreamGenericReaderMixin::closed() +JS::GCPtr ReadableStreamGenericReaderMixin::closed() { // 1. Return this.[[closedPromise]]. - return JS::GCPtr { verify_cast(*m_closed_promise->promise()) }; + return m_closed_promise; } // https://streams.spec.whatwg.org/#generic-reader-cancel -JS::NonnullGCPtr ReadableStreamGenericReaderMixin::cancel(JS::Value reason) +JS::NonnullGCPtr ReadableStreamGenericReaderMixin::cancel(JS::Value reason) { // 1. If this.[[stream]] is undefined, return a promise rejected with a TypeError exception. if (!m_stream) { @@ -30,8 +30,7 @@ JS::NonnullGCPtr ReadableStreamGenericReaderMixin::cancel(JS::Value } // 2. Return ! ReadableStreamReaderGenericCancel(this, reason). - auto promise_capability = readable_stream_reader_generic_cancel(*this, reason); - return JS::NonnullGCPtr { verify_cast(*promise_capability->promise().ptr()) }; + return readable_stream_reader_generic_cancel(*this, reason); } ReadableStreamGenericReaderMixin::ReadableStreamGenericReaderMixin(JS::Realm& realm) diff --git a/Userland/Libraries/LibWeb/Streams/ReadableStreamGenericReader.h b/Userland/Libraries/LibWeb/Streams/ReadableStreamGenericReader.h index 6b8579e5cd5..e59732ebb99 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableStreamGenericReader.h +++ b/Userland/Libraries/LibWeb/Streams/ReadableStreamGenericReader.h @@ -19,9 +19,9 @@ class ReadableStreamGenericReaderMixin { public: virtual ~ReadableStreamGenericReaderMixin() = default; - JS::GCPtr closed(); + JS::GCPtr closed(); - JS::NonnullGCPtr cancel(JS::Value reason); + JS::NonnullGCPtr cancel(JS::Value reason); JS::GCPtr stream() const { return m_stream; } void set_stream(JS::GCPtr stream) { m_stream = stream; } diff --git a/Userland/Libraries/LibWeb/Streams/WritableStream.cpp b/Userland/Libraries/LibWeb/Streams/WritableStream.cpp index 0a500380cf2..060a42e40d5 100644 --- a/Userland/Libraries/LibWeb/Streams/WritableStream.cpp +++ b/Userland/Libraries/LibWeb/Streams/WritableStream.cpp @@ -58,39 +58,39 @@ bool WritableStream::locked() const } // https://streams.spec.whatwg.org/#ws-close -JS::GCPtr WritableStream::close() +JS::GCPtr WritableStream::close() { auto& realm = this->realm(); // 1. If ! IsWritableStreamLocked(this) is true, return a promise rejected with a TypeError exception. if (is_writable_stream_locked(*this)) { auto exception = JS::TypeError::create(realm, "Cannot close a locked stream"sv); - return WebIDL::create_rejected_promise(realm, exception)->promise(); + return WebIDL::create_rejected_promise(realm, exception); } // 2. If ! WritableStreamCloseQueuedOrInFlight(this) is true, return a promise rejected with a TypeError exception. if (writable_stream_close_queued_or_in_flight(*this)) { auto exception = JS::TypeError::create(realm, "Cannot close a stream that is already closed or errored"sv); - return WebIDL::create_rejected_promise(realm, exception)->promise(); + return WebIDL::create_rejected_promise(realm, exception); } // 3. Return ! WritableStreamClose(this). - return writable_stream_close(*this)->promise(); + return writable_stream_close(*this); } // https://streams.spec.whatwg.org/#ws-abort -JS::GCPtr WritableStream::abort(JS::Value reason) +JS::GCPtr WritableStream::abort(JS::Value reason) { auto& realm = this->realm(); // 1. If ! IsWritableStreamLocked(this) is true, return a promise rejected with a TypeError exception. if (is_writable_stream_locked(*this)) { auto exception = JS::TypeError::create(realm, "Cannot abort a locked stream"sv); - return WebIDL::create_rejected_promise(realm, exception)->promise(); + return WebIDL::create_rejected_promise(realm, exception); } // 2. Return ! WritableStreamAbort(this, reason). - return writable_stream_abort(*this, reason)->promise(); + return writable_stream_abort(*this, reason); } // https://streams.spec.whatwg.org/#ws-get-writer diff --git a/Userland/Libraries/LibWeb/Streams/WritableStream.h b/Userland/Libraries/LibWeb/Streams/WritableStream.h index 933824c46f8..43f416f10ad 100644 --- a/Userland/Libraries/LibWeb/Streams/WritableStream.h +++ b/Userland/Libraries/LibWeb/Streams/WritableStream.h @@ -49,8 +49,8 @@ public: virtual ~WritableStream() = default; bool locked() const; - JS::GCPtr abort(JS::Value reason); - JS::GCPtr close(); + JS::GCPtr abort(JS::Value reason); + JS::GCPtr close(); WebIDL::ExceptionOr> get_writer(); bool backpressure() const { return m_backpressure; } diff --git a/Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.cpp b/Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.cpp index 04b87a8a9ec..07e55c712f6 100644 --- a/Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.cpp +++ b/Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.cpp @@ -27,10 +27,10 @@ WebIDL::ExceptionOr> WritableStrea } // https://streams.spec.whatwg.org/#default-writer-closed -JS::GCPtr WritableStreamDefaultWriter::closed() +JS::GCPtr WritableStreamDefaultWriter::closed() { // 1. Return this.[[closedPromise]]. - return m_closed_promise->promise(); + return m_closed_promise; } // https://streams.spec.whatwg.org/#default-writer-desired-size @@ -45,29 +45,29 @@ WebIDL::ExceptionOr> WritableStreamDefaultWriter::desired_size( } // https://streams.spec.whatwg.org/#default-writer-ready -JS::GCPtr WritableStreamDefaultWriter::ready() +JS::GCPtr WritableStreamDefaultWriter::ready() { // 1. Return this.[[readyPromise]]. - return m_ready_promise->promise(); + return m_ready_promise; } // https://streams.spec.whatwg.org/#default-writer-abort -JS::GCPtr WritableStreamDefaultWriter::abort(JS::Value reason) +JS::GCPtr WritableStreamDefaultWriter::abort(JS::Value reason) { auto& realm = this->realm(); // 1. If this.[[stream]] is undefined, return a promise rejected with a TypeError exception. if (!m_stream) { auto exception = JS::TypeError::create(realm, "Cannot abort a writer that has no locked stream"sv); - return WebIDL::create_rejected_promise(realm, exception)->promise(); + return WebIDL::create_rejected_promise(realm, exception); } // 2. Return ! WritableStreamDefaultWriterAbort(this, reason). - return writable_stream_default_writer_abort(*this, reason)->promise(); + return writable_stream_default_writer_abort(*this, reason); } // https://streams.spec.whatwg.org/#default-writer-close -JS::GCPtr WritableStreamDefaultWriter::close() +JS::GCPtr WritableStreamDefaultWriter::close() { auto& realm = this->realm(); @@ -76,17 +76,17 @@ JS::GCPtr WritableStreamDefaultWriter::close() // 2. If stream is undefined, return a promise rejected with a TypeError exception. if (!m_stream) { auto exception = JS::TypeError::create(realm, "Cannot close a writer that has no locked stream"sv); - return WebIDL::create_rejected_promise(realm, exception)->promise(); + return WebIDL::create_rejected_promise(realm, exception); } // 3. If ! WritableStreamCloseQueuedOrInFlight(stream) is true, return a promise rejected with a TypeError exception. if (writable_stream_close_queued_or_in_flight(*m_stream)) { auto exception = JS::TypeError::create(realm, "Cannot close a stream that is already closed or errored"sv); - return WebIDL::create_rejected_promise(realm, exception)->promise(); + return WebIDL::create_rejected_promise(realm, exception); } // 4. Return ! WritableStreamDefaultWriterClose(this). - return writable_stream_default_writer_close(*this)->promise(); + return writable_stream_default_writer_close(*this); } // https://streams.spec.whatwg.org/#default-writer-release-lock @@ -106,18 +106,18 @@ void WritableStreamDefaultWriter::release_lock() } // https://streams.spec.whatwg.org/#default-writer-write -JS::GCPtr WritableStreamDefaultWriter::write(JS::Value chunk) +JS::GCPtr WritableStreamDefaultWriter::write(JS::Value chunk) { auto& realm = this->realm(); // 1. If this.[[stream]] is undefined, return a promise rejected with a TypeError exception. if (!m_stream) { auto exception = JS::TypeError::create(realm, "Cannot write to a writer that has no locked stream"sv); - return WebIDL::create_rejected_promise(realm, exception)->promise(); + return WebIDL::create_rejected_promise(realm, exception); } // 2. Return ! WritableStreamDefaultWriterWrite(this, chunk). - return writable_stream_default_writer_write(*this, chunk)->promise(); + return writable_stream_default_writer_write(*this, chunk); } WritableStreamDefaultWriter::WritableStreamDefaultWriter(JS::Realm& realm) diff --git a/Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.h b/Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.h index 4b85f4e301c..1f06f257ac3 100644 --- a/Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.h +++ b/Userland/Libraries/LibWeb/Streams/WritableStreamDefaultWriter.h @@ -25,13 +25,13 @@ public: virtual ~WritableStreamDefaultWriter() override = default; - JS::GCPtr closed(); + JS::GCPtr closed(); WebIDL::ExceptionOr> desired_size() const; - JS::GCPtr ready(); - JS::GCPtr abort(JS::Value reason); - JS::GCPtr close(); + JS::GCPtr ready(); + JS::GCPtr abort(JS::Value reason); + JS::GCPtr close(); void release_lock(); - JS::GCPtr write(JS::Value chunk); + JS::GCPtr write(JS::Value chunk); JS::GCPtr closed_promise() { return m_closed_promise; } void set_closed_promise(JS::GCPtr value) { m_closed_promise = value; } diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp index 53062c5ab50..7e9047ec14e 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.cpp @@ -19,12 +19,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include namespace Web::WebAssembly { @@ -80,26 +82,25 @@ bool validate(JS::VM& vm, JS::Handle& bytes) } // https://webassembly.github.io/spec/js-api/#dom-webassembly-compile -WebIDL::ExceptionOr compile(JS::VM& vm, JS::Handle& bytes) +WebIDL::ExceptionOr> compile(JS::VM& vm, JS::Handle& bytes) { auto& realm = *vm.current_realm(); // FIXME: This shouldn't block! auto compiled_module_or_error = Detail::parse_module(vm, bytes->raw_object()); - auto promise = JS::Promise::create(realm); - + auto promise = WebIDL::create_promise(realm); if (compiled_module_or_error.is_error()) { - promise->reject(*compiled_module_or_error.release_error().value()); + WebIDL::reject_promise(realm, promise, compiled_module_or_error.error_value()); } else { auto module_object = vm.heap().allocate(realm, realm, compiled_module_or_error.release_value()); - promise->fulfill(module_object); + WebIDL::resolve_promise(realm, promise, module_object); } return promise; } // https://webassembly.github.io/spec/js-api/#dom-webassembly-instantiate -WebIDL::ExceptionOr instantiate(JS::VM& vm, JS::Handle& bytes, Optional>& import_object) +WebIDL::ExceptionOr> instantiate(JS::VM& vm, JS::Handle& bytes, Optional>& import_object) { // FIXME: Implement the importObject parameter. (void)import_object; @@ -108,10 +109,10 @@ WebIDL::ExceptionOr instantiate(JS::VM& vm, JS::Handleraw_object()); - auto promise = JS::Promise::create(realm); + auto promise = WebIDL::create_promise(realm); if (compiled_module_or_error.is_error()) { - promise->reject(*compiled_module_or_error.release_error().value()); + WebIDL::reject_promise(realm, promise, compiled_module_or_error.error_value()); return promise; } @@ -119,7 +120,7 @@ WebIDL::ExceptionOr instantiate(JS::VM& vm, JS::Handlemodule); if (result.is_error()) { - promise->reject(*result.release_error().value()); + WebIDL::reject_promise(realm, promise, result.error_value()); } else { auto module_object = vm.heap().allocate(realm, realm, move(compiled_module)); auto instance_object = vm.heap().allocate(realm, realm, result.release_value()); @@ -127,29 +128,30 @@ WebIDL::ExceptionOr instantiate(JS::VM& vm, JS::Handledefine_direct_property("module", module_object, JS::default_attributes); object->define_direct_property("instance", instance_object, JS::default_attributes); - promise->fulfill(object); + WebIDL::resolve_promise(realm, promise, object); } return promise; } // https://webassembly.github.io/spec/js-api/#dom-webassembly-instantiate-moduleobject-importobject -WebIDL::ExceptionOr instantiate(JS::VM& vm, Module const& module_object, Optional>& import_object) +WebIDL::ExceptionOr> instantiate(JS::VM& vm, Module const& module_object, Optional>& import_object) { // FIXME: Implement the importObject parameter. (void)import_object; auto& realm = *vm.current_realm(); - auto promise = JS::Promise::create(realm); + auto promise = WebIDL::create_promise(realm); + // FIXME: This shouldn't block! auto const& compiled_module = module_object.compiled_module(); auto result = Detail::instantiate_module(vm, compiled_module->module); if (result.is_error()) { - promise->reject(*result.release_error().value()); + WebIDL::reject_promise(realm, promise, result.error_value()); } else { auto instance_object = vm.heap().allocate(realm, realm, result.release_value()); - promise->fulfill(instance_object); + WebIDL::resolve_promise(realm, promise, instance_object); } return promise; diff --git a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h index 19397b50164..9d92baa5cc3 100644 --- a/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h +++ b/Userland/Libraries/LibWeb/WebAssembly/WebAssembly.h @@ -22,10 +22,10 @@ void visit_edges(JS::Object&, JS::Cell::Visitor&); void finalize(JS::Object&); bool validate(JS::VM&, JS::Handle& bytes); -WebIDL::ExceptionOr compile(JS::VM&, JS::Handle& bytes); +WebIDL::ExceptionOr> compile(JS::VM&, JS::Handle& bytes); -WebIDL::ExceptionOr instantiate(JS::VM&, JS::Handle& bytes, Optional>& import_object); -WebIDL::ExceptionOr instantiate(JS::VM&, Module const& module_object, Optional>& import_object); +WebIDL::ExceptionOr> instantiate(JS::VM&, JS::Handle& bytes, Optional>& import_object); +WebIDL::ExceptionOr> instantiate(JS::VM&, Module const& module_object, Optional>& import_object); namespace Detail { struct CompiledWebAssemblyModule : public RefCounted { diff --git a/Userland/Libraries/LibWeb/WebAudio/AudioContext.cpp b/Userland/Libraries/LibWeb/WebAudio/AudioContext.cpp index 531d05efb1b..0e182eeb2f4 100644 --- a/Userland/Libraries/LibWeb/WebAudio/AudioContext.cpp +++ b/Userland/Libraries/LibWeb/WebAudio/AudioContext.cpp @@ -103,7 +103,7 @@ AudioTimestamp AudioContext::get_output_timestamp() } // https://www.w3.org/TR/webaudio/#dom-audiocontext-resume -WebIDL::ExceptionOr> AudioContext::resume() +WebIDL::ExceptionOr> AudioContext::resume() { auto& realm = this->realm(); @@ -118,7 +118,7 @@ WebIDL::ExceptionOr> AudioContext::resume() // 3. If the [[control thread state]] on the AudioContext is closed reject the promise with InvalidStateError, abort these steps, returning promise. if (state() == Bindings::AudioContextState::Closed) { WebIDL::reject_promise(realm, promise, WebIDL::InvalidStateError::create(realm, "Audio context is already closed."_string)); - return JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + return promise; } // 4. Set [[suspended by user]] to true. @@ -187,11 +187,11 @@ WebIDL::ExceptionOr> AudioContext::resume() })); // 8. Return promise. - return JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + return promise; } // https://www.w3.org/TR/webaudio/#dom-audiocontext-suspend -WebIDL::ExceptionOr> AudioContext::suspend() +WebIDL::ExceptionOr> AudioContext::suspend() { auto& realm = this->realm(); @@ -206,7 +206,7 @@ WebIDL::ExceptionOr> AudioContext::suspend() // 3. If the [[control thread state]] on the AudioContext is closed reject the promise with InvalidStateError, abort these steps, returning promise. if (state() == Bindings::AudioContextState::Closed) { WebIDL::reject_promise(realm, promise, WebIDL::InvalidStateError::create(realm, "Audio context is already closed."_string)); - return JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + return promise; } // 4. Append promise to [[pending promises]]. @@ -244,11 +244,11 @@ WebIDL::ExceptionOr> AudioContext::suspend() })); // 8. Return promise. - return JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + return promise; } // https://www.w3.org/TR/webaudio/#dom-audiocontext-close -WebIDL::ExceptionOr> AudioContext::close() +WebIDL::ExceptionOr> AudioContext::close() { auto& realm = this->realm(); @@ -263,7 +263,7 @@ WebIDL::ExceptionOr> AudioContext::close() // 3. If the [[control thread state]] flag on the AudioContext is closed reject the promise with InvalidStateError, abort these steps, returning promise. if (state() == Bindings::AudioContextState::Closed) { WebIDL::reject_promise(realm, promise, WebIDL::InvalidStateError::create(realm, "Audio context is already closed."_string)); - return JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + return promise; } // 4. Set the [[control thread state]] flag on the AudioContext to closed. @@ -296,7 +296,7 @@ WebIDL::ExceptionOr> AudioContext::close() })); // 6. Return promise - return JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + return promise; } // FIXME: Actually implement the rendering thread diff --git a/Userland/Libraries/LibWeb/WebAudio/AudioContext.h b/Userland/Libraries/LibWeb/WebAudio/AudioContext.h index daad254029c..9c67c3656bb 100644 --- a/Userland/Libraries/LibWeb/WebAudio/AudioContext.h +++ b/Userland/Libraries/LibWeb/WebAudio/AudioContext.h @@ -35,9 +35,9 @@ public: double base_latency() const { return m_base_latency; } double output_latency() const { return m_output_latency; } AudioTimestamp get_output_timestamp(); - WebIDL::ExceptionOr> resume(); - WebIDL::ExceptionOr> suspend(); - WebIDL::ExceptionOr> close(); + WebIDL::ExceptionOr> resume(); + WebIDL::ExceptionOr> suspend(); + WebIDL::ExceptionOr> close(); private: explicit AudioContext(JS::Realm&, AudioContextOptions const& context_options); diff --git a/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp b/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp index ddd6451573a..587791596cb 100644 --- a/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp +++ b/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.cpp @@ -128,7 +128,7 @@ void BaseAudioContext::queue_a_media_element_task(JS::NonnullGCPtr BaseAudioContext::decode_audio_data(JS::Handle audio_data, JS::GCPtr success_callback, JS::GCPtr error_callback) +JS::NonnullGCPtr BaseAudioContext::decode_audio_data(JS::Handle audio_data, JS::GCPtr success_callback, JS::GCPtr error_callback) { auto& realm = this->realm(); @@ -178,7 +178,7 @@ JS::NonnullGCPtr BaseAudioContext::decode_audio_data(JS::Handle(*promise->promise()); + return promise; } // https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-decodeaudiodata diff --git a/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.h b/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.h index 27b10eb9cf5..597435e81bf 100644 --- a/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.h +++ b/Userland/Libraries/LibWeb/WebAudio/BaseAudioContext.h @@ -61,7 +61,7 @@ public: WebIDL::ExceptionOr> create_dynamics_compressor(); JS::NonnullGCPtr create_gain(); - JS::NonnullGCPtr decode_audio_data(JS::Handle, JS::GCPtr, JS::GCPtr); + JS::NonnullGCPtr decode_audio_data(JS::Handle, JS::GCPtr, JS::GCPtr); protected: explicit BaseAudioContext(JS::Realm&, float m_sample_rate = 0); diff --git a/Userland/Libraries/LibWeb/WebAudio/OfflineAudioContext.cpp b/Userland/Libraries/LibWeb/WebAudio/OfflineAudioContext.cpp index 26a2cca27db..9b1f4f120c2 100644 --- a/Userland/Libraries/LibWeb/WebAudio/OfflineAudioContext.cpp +++ b/Userland/Libraries/LibWeb/WebAudio/OfflineAudioContext.cpp @@ -32,17 +32,17 @@ WebIDL::ExceptionOr> OfflineAudioContext:: OfflineAudioContext::~OfflineAudioContext() = default; // https://webaudio.github.io/web-audio-api/#dom-offlineaudiocontext-startrendering -WebIDL::ExceptionOr> OfflineAudioContext::start_rendering() +WebIDL::ExceptionOr> OfflineAudioContext::start_rendering() { return WebIDL::NotSupportedError::create(realm(), "FIXME: Implement OfflineAudioContext::start_rendering"_string); } -WebIDL::ExceptionOr> OfflineAudioContext::resume() +WebIDL::ExceptionOr> OfflineAudioContext::resume() { return WebIDL::NotSupportedError::create(realm(), "FIXME: Implement OfflineAudioContext::resume"_string); } -WebIDL::ExceptionOr> OfflineAudioContext::suspend(double suspend_time) +WebIDL::ExceptionOr> OfflineAudioContext::suspend(double suspend_time) { (void)suspend_time; return WebIDL::NotSupportedError::create(realm(), "FIXME: Implement OfflineAudioContext::suspend"_string); diff --git a/Userland/Libraries/LibWeb/WebAudio/OfflineAudioContext.h b/Userland/Libraries/LibWeb/WebAudio/OfflineAudioContext.h index a9c70c9dca8..00e4c3842fa 100644 --- a/Userland/Libraries/LibWeb/WebAudio/OfflineAudioContext.h +++ b/Userland/Libraries/LibWeb/WebAudio/OfflineAudioContext.h @@ -32,9 +32,9 @@ public: virtual ~OfflineAudioContext() override; - WebIDL::ExceptionOr> start_rendering(); - WebIDL::ExceptionOr> resume(); - WebIDL::ExceptionOr> suspend(double suspend_time); + WebIDL::ExceptionOr> start_rendering(); + WebIDL::ExceptionOr> resume(); + WebIDL::ExceptionOr> suspend(double suspend_time); WebIDL::UnsignedLong length() const; diff --git a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp index f1433d361fd..00d17cda6e8 100644 --- a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp @@ -376,24 +376,24 @@ void execute_script(HTML::BrowsingContext const& browsing_context, ByteString bo HTML::TemporaryExecutionContext execution_context { document->relevant_settings_object(), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes }; // 7. Let promise be a new Promise. - auto promise_capability = WebIDL::create_promise(realm); - JS::NonnullGCPtr promise { verify_cast(*promise_capability->promise()) }; + auto promise = WebIDL::create_promise(realm); // 8. Run the following substeps in parallel: - Platform::EventLoopPlugin::the().deferred_invoke([&realm, &browsing_context, promise_capability, document, promise, body = move(body), arguments = move(arguments)]() mutable { + Platform::EventLoopPlugin::the().deferred_invoke([&realm, &browsing_context, promise, document, body = move(body), arguments = move(arguments)]() mutable { HTML::TemporaryExecutionContext execution_context { document->relevant_settings_object() }; // 1. Let scriptPromise be the result of promise-calling execute a function body, with arguments body and arguments. auto script_result = execute_a_function_body(browsing_context, body, move(arguments)); + // FIXME: This isn't right, we should be reacting to this using WebIDL::react_to_promise() // 2. Upon fulfillment of scriptPromise with value v, resolve promise with value v. if (script_result.has_value()) { - WebIDL::resolve_promise(realm, promise_capability, script_result.release_value()); + WebIDL::resolve_promise(realm, promise, script_result.release_value()); } // 3. Upon rejection of scriptPromise with value r, reject promise with value r. if (script_result.is_throw_completion()) { - promise->reject(*script_result.throw_completion().value()); + WebIDL::reject_promise(realm, promise, *script_result.throw_completion().value()); } }); @@ -403,7 +403,9 @@ void execute_script(HTML::BrowsingContext const& browsing_context, ByteString bo return JS::js_undefined(); timer->stop(); - auto json_value_or_error = json_clone(realm, browsing_context, promise->result()); + auto promise_promise = JS::NonnullGCPtr { verify_cast(*promise->promise()) }; + + auto json_value_or_error = json_clone(realm, browsing_context, promise_promise->result()); if (json_value_or_error.is_error()) { auto error_object = JsonObject {}; error_object.set("name", "Error"); @@ -416,19 +418,19 @@ void execute_script(HTML::BrowsingContext const& browsing_context, ByteString bo // NOTE: This is handled by the HeapTimer. // 11. If promise is fulfilled with value v, let result be JSON clone with session and v, and return success with data result. - else if (promise->state() == JS::Promise::State::Fulfilled) { + else if (promise_promise->state() == JS::Promise::State::Fulfilled) { on_complete->function()({ ExecuteScriptResultType::PromiseResolved, json_value_or_error.release_value() }); } // 12. If promise is rejected with reason r, let result be JSON clone with session and r, and return error with error code javascript error and data result. - else if (promise->state() == JS::Promise::State::Rejected) { + else if (promise_promise->state() == JS::Promise::State::Rejected) { on_complete->function()({ ExecuteScriptResultType::PromiseRejected, json_value_or_error.release_value() }); } return JS::js_undefined(); }); - WebIDL::react_to_promise(promise_capability, reaction_steps, reaction_steps); + WebIDL::react_to_promise(promise, reaction_steps, reaction_steps); } void execute_async_script(HTML::BrowsingContext const& browsing_context, ByteString body, JS::MarkedVector arguments, Optional const& timeout_ms, JS::NonnullGCPtr on_complete) diff --git a/Userland/Libraries/LibWeb/WebIDL/Promise.cpp b/Userland/Libraries/LibWeb/WebIDL/Promise.cpp index f2dd79d3d99..25de081d205 100644 --- a/Userland/Libraries/LibWeb/WebIDL/Promise.cpp +++ b/Userland/Libraries/LibWeb/WebIDL/Promise.cpp @@ -93,7 +93,7 @@ void reject_promise(JS::Realm& realm, Promise const& promise, JS::Value reason) } // https://webidl.spec.whatwg.org/#dfn-perform-steps-once-promise-is-settled -JS::NonnullGCPtr react_to_promise(Promise const& promise, JS::GCPtr on_fulfilled_callback, JS::GCPtr on_rejected_callback) +JS::NonnullGCPtr react_to_promise(Promise const& promise, JS::GCPtr on_fulfilled_callback, JS::GCPtr on_rejected_callback) { auto& realm = promise.promise()->shape().realm(); auto& vm = realm.vm(); @@ -140,13 +140,17 @@ JS::NonnullGCPtr react_to_promise(Promise const& promise, JS::GCPtr auto new_capability = MUST(JS::new_promise_capability(vm, constructor)); // 7. Return PerformPromiseThen(promise.[[Promise]], onFulfilled, onRejected, newCapability). + // FIXME: https://github.com/whatwg/webidl/issues/1443 + // Returning newCapability instead of newCapability.[[Promise]. auto promise_object = verify_cast(promise.promise().ptr()); auto value = promise_object->perform_then(on_fulfilled, on_rejected, new_capability); - return verify_cast(value.as_object()); + + VERIFY(value == new_capability->promise()); + return new_capability; } // https://webidl.spec.whatwg.org/#upon-fulfillment -JS::NonnullGCPtr upon_fulfillment(Promise const& promise, JS::NonnullGCPtr steps) +JS::NonnullGCPtr upon_fulfillment(Promise const& promise, JS::NonnullGCPtr steps) { // 1. Return the result of reacting to promise: return react_to_promise(promise, @@ -157,7 +161,7 @@ JS::NonnullGCPtr upon_fulfillment(Promise const& promise, JS::Nonnu } // https://webidl.spec.whatwg.org/#upon-rejection -JS::NonnullGCPtr upon_rejection(Promise const& promise, JS::NonnullGCPtr steps) +JS::NonnullGCPtr upon_rejection(Promise const& promise, JS::NonnullGCPtr steps) { // 1. Return the result of reacting to promise: return react_to_promise(promise, {}, @@ -287,11 +291,10 @@ void wait_for_all(JS::Realm& realm, Vector> const& pro } } -JS::NonnullGCPtr create_rejected_promise_from_exception(JS::Realm& realm, Exception exception) +JS::NonnullGCPtr create_rejected_promise_from_exception(JS::Realm& realm, Exception exception) { auto throw_completion = Bindings::dom_exception_to_throw_completion(realm.vm(), move(exception)); - auto promise_capability = WebIDL::create_rejected_promise(realm, *throw_completion.value()); - return JS::NonnullGCPtr { verify_cast(*promise_capability->promise().ptr()) }; + return WebIDL::create_rejected_promise(realm, *throw_completion.value()); } } diff --git a/Userland/Libraries/LibWeb/WebIDL/Promise.h b/Userland/Libraries/LibWeb/WebIDL/Promise.h index a2d91c268a1..08cdec13b9f 100644 --- a/Userland/Libraries/LibWeb/WebIDL/Promise.h +++ b/Userland/Libraries/LibWeb/WebIDL/Promise.h @@ -27,13 +27,13 @@ JS::NonnullGCPtr create_resolved_promise(JS::Realm&, JS::Value); JS::NonnullGCPtr create_rejected_promise(JS::Realm&, JS::Value); void resolve_promise(JS::Realm&, Promise const&, JS::Value = JS::js_undefined()); void reject_promise(JS::Realm&, Promise const&, JS::Value); -JS::NonnullGCPtr react_to_promise(Promise const&, JS::GCPtr on_fulfilled_callback, JS::GCPtr on_rejected_callback); -JS::NonnullGCPtr upon_fulfillment(Promise const&, JS::NonnullGCPtr); -JS::NonnullGCPtr upon_rejection(Promise const&, JS::NonnullGCPtr); +JS::NonnullGCPtr react_to_promise(Promise const&, JS::GCPtr on_fulfilled_callback, JS::GCPtr on_rejected_callback); +JS::NonnullGCPtr upon_fulfillment(Promise const&, JS::NonnullGCPtr); +JS::NonnullGCPtr upon_rejection(Promise const&, JS::NonnullGCPtr); void mark_promise_as_handled(Promise const&); void wait_for_all(JS::Realm&, Vector> const& promises, Function const&)> success_steps, Function failure_steps); // Non-spec, convenience method. -JS::NonnullGCPtr create_rejected_promise_from_exception(JS::Realm&, Exception); +JS::NonnullGCPtr create_rejected_promise_from_exception(JS::Realm&, Exception); }