1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 08:58:11 +00:00

LibJS: Make Heap::allocate<T>() infallible

Stop worrying about tiny OOMs. Work towards #20449.

While going through these, I also changed the function signature in many
places where returning ThrowCompletionOr<T> is no longer necessary.
This commit is contained in:
Andreas Kling 2023-08-13 13:05:26 +02:00
parent 980e7164fe
commit 72c9f56c66
337 changed files with 1229 additions and 1251 deletions

View file

@ -84,9 +84,9 @@ private:
u32 m_handle { 0 };
};
WebIDL::ExceptionOr<JS::NonnullGCPtr<Window>> Window::create(JS::Realm& realm)
JS::NonnullGCPtr<Window> Window::create(JS::Realm& realm)
{
return MUST_OR_THROW_OOM(realm.heap().allocate<Window>(realm, realm));
return realm.heap().allocate<Window>(realm, realm);
}
Window::Window(JS::Realm& realm)
@ -577,7 +577,7 @@ void Window::fire_a_page_transition_event(FlyString const& event_name, bool pers
// with the persisted attribute initialized to persisted,
PageTransitionEventInit event_init {};
event_init.persisted = persisted;
auto event = PageTransitionEvent::create(associated_document().realm(), event_name, event_init).release_value_but_fixme_should_propagate_errors();
auto event = PageTransitionEvent::create(associated_document().realm(), event_name, event_init);
// ...the cancelable attribute initialized to true,
event->set_cancelable(true);
@ -593,15 +593,10 @@ void Window::fire_a_page_transition_event(FlyString const& event_name, bool pers
WebIDL::ExceptionOr<JS::NonnullGCPtr<Storage>> Window::local_storage()
{
// FIXME: Implement according to spec.
auto& vm = this->vm();
static HashMap<Origin, JS::Handle<Storage>> local_storage_per_origin;
auto storage = TRY_OR_THROW_OOM(vm, local_storage_per_origin.try_ensure(associated_document().origin(), [this]() -> ErrorOr<JS::Handle<Storage>> {
auto storage_or_exception = Storage::create(realm());
if (storage_or_exception.is_exception())
return Error::from_errno(ENOMEM);
return *storage_or_exception.release_value();
}));
auto storage = local_storage_per_origin.ensure(associated_document().origin(), [this]() -> JS::Handle<Storage> {
return Storage::create(realm());
});
return JS::NonnullGCPtr { *storage };
}
@ -609,15 +604,10 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Storage>> Window::local_storage()
WebIDL::ExceptionOr<JS::NonnullGCPtr<Storage>> Window::session_storage()
{
// FIXME: Implement according to spec.
auto& vm = this->vm();
static HashMap<Origin, JS::Handle<Storage>> session_storage_per_origin;
auto storage = TRY_OR_THROW_OOM(vm, session_storage_per_origin.try_ensure(associated_document().origin(), [this]() -> ErrorOr<JS::Handle<Storage>> {
auto storage_or_exception = Storage::create(realm());
if (storage_or_exception.is_exception())
return Error::from_errno(ENOMEM);
return *storage_or_exception.release_value();
}));
auto storage = session_storage_per_origin.ensure(associated_document().origin(), [this]() -> JS::Handle<Storage> {
return Storage::create(realm());
});
return JS::NonnullGCPtr { *storage };
}
@ -680,7 +670,7 @@ void Window::invoke_idle_callbacks()
// 1. Pop the top callback from window's list of runnable idle callbacks.
auto callback = m_runnable_idle_callbacks.take_first();
// 2. Let deadlineArg be a new IdleDeadline whose [get deadline time algorithm] is getDeadline.
auto deadline_arg = RequestIdleCallback::IdleDeadline::create(realm()).release_value_but_fixme_should_propagate_errors();
auto deadline_arg = RequestIdleCallback::IdleDeadline::create(realm());
// 3. Call callback with deadlineArg as its argument. If an uncaught runtime script error occurs, then report the exception.
auto result = callback->invoke(deadline_arg);
if (result.is_error())
@ -730,11 +720,11 @@ Vector<JS::NonnullGCPtr<Plugin>> Window::pdf_viewer_plugin_objects()
if (m_pdf_viewer_plugin_objects.is_empty()) {
// FIXME: Propagate errors.
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), "PDF Viewer"_string).release_allocated_value_but_fixme_should_propagate_errors());
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), "Chrome PDF Viewer"_string).release_allocated_value_but_fixme_should_propagate_errors());
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), "Chromium PDF Viewer"_string).release_allocated_value_but_fixme_should_propagate_errors());
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), "Microsoft Edge PDF Viewer"_string).release_allocated_value_but_fixme_should_propagate_errors());
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), "WebKit built-in PDF"_string).release_allocated_value_but_fixme_should_propagate_errors());
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), "PDF Viewer"_string));
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), "Chrome PDF Viewer"_string));
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), "Chromium PDF Viewer"_string));
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), "Microsoft Edge PDF Viewer"_string));
m_pdf_viewer_plugin_objects.append(realm().heap().allocate<Plugin>(realm(), realm(), "WebKit built-in PDF"_string));
}
return m_pdf_viewer_plugin_objects;
@ -753,8 +743,8 @@ Vector<JS::NonnullGCPtr<MimeType>> Window::pdf_viewer_mime_type_objects()
return {};
if (m_pdf_viewer_mime_type_objects.is_empty()) {
m_pdf_viewer_mime_type_objects.append(realm().heap().allocate<MimeType>(realm(), realm(), "application/pdf"_string).release_allocated_value_but_fixme_should_propagate_errors());
m_pdf_viewer_mime_type_objects.append(realm().heap().allocate<MimeType>(realm(), realm(), "text/pdf"_string).release_allocated_value_but_fixme_should_propagate_errors());
m_pdf_viewer_mime_type_objects.append(realm().heap().allocate<MimeType>(realm(), realm(), "application/pdf"_string));
m_pdf_viewer_mime_type_objects.append(realm().heap().allocate<MimeType>(realm(), realm(), "text/pdf"_string));
}
return m_pdf_viewer_mime_type_objects;
@ -776,7 +766,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::CallbackType>> Window::count_queuin
auto function = JS::NativeFunction::create(realm, move(steps), 0, "size", &realm);
// 3. Set globalObjects count queuing strategy size function to a Function that represents a reference to F, with callback context equal to globalObjects relevant settings object.
m_count_queuing_strategy_size_function = MUST_OR_THROW_OOM(heap().allocate<WebIDL::CallbackType>(realm, *function, relevant_settings_object(*this)));
m_count_queuing_strategy_size_function = heap().allocate<WebIDL::CallbackType>(realm, *function, relevant_settings_object(*this));
}
return JS::NonnullGCPtr { *m_count_queuing_strategy_size_function };
@ -800,7 +790,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::CallbackType>> Window::byte_length_
auto function = JS::NativeFunction::create(realm, move(steps), 1, "size", &realm);
// 3. Set globalObjects byte length queuing strategy size function to a Function that represents a reference to F, with callback context equal to globalObjects relevant settings object.
m_byte_length_queuing_strategy_size_function = MUST_OR_THROW_OOM(heap().allocate<WebIDL::CallbackType>(realm, *function, relevant_settings_object(*this)));
m_byte_length_queuing_strategy_size_function = heap().allocate<WebIDL::CallbackType>(realm, *function, relevant_settings_object(*this));
}
return JS::NonnullGCPtr { *m_byte_length_queuing_strategy_size_function };
@ -824,7 +814,7 @@ WebIDL::ExceptionOr<void> Window::initialize_web_interfaces(Badge<WindowEnvironm
WindowOrWorkerGlobalScopeMixin::initialize(realm);
if (s_internals_object_exposed)
define_direct_property("internals", MUST_OR_THROW_OOM(heap().allocate<Internals::Internals>(realm, realm)), JS::default_attributes);
define_direct_property("internals", heap().allocate<Internals::Internals>(realm, realm), JS::default_attributes);
return {};
}
@ -880,13 +870,13 @@ void Window::set_name(String const& name)
}
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-location
WebIDL::ExceptionOr<JS::NonnullGCPtr<Location>> Window::location()
JS::NonnullGCPtr<Location> Window::location()
{
auto& realm = this->realm();
// The Window object's location getter steps are to return this's Location object.
if (!m_location)
m_location = MUST_OR_THROW_OOM(heap().allocate<Location>(realm, realm));
m_location = heap().allocate<Location>(realm, realm);
return JS::NonnullGCPtr { *m_location };
}
@ -993,13 +983,13 @@ WebIDL::ExceptionOr<JS::GCPtr<WindowProxy>> Window::open(Optional<String> const&
}
// https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator
WebIDL::ExceptionOr<JS::NonnullGCPtr<Navigator>> Window::navigator()
JS::NonnullGCPtr<Navigator> Window::navigator()
{
auto& realm = this->realm();
// The navigator and clientInformation getter steps are to return this's associated Navigator.
if (!m_navigator)
m_navigator = MUST_OR_THROW_OOM(heap().allocate<Navigator>(realm, realm));
m_navigator = heap().allocate<Navigator>(realm, realm);
return JS::NonnullGCPtr { *m_navigator };
}
@ -1043,7 +1033,7 @@ void Window::post_message(JS::Value message, String const&)
MessageEventInit event_init {};
event_init.data = message;
event_init.origin = "<origin>"_string;
dispatch_event(MessageEvent::create(realm(), EventNames::message, event_init).release_value_but_fixme_should_propagate_errors());
dispatch_event(MessageEvent::create(realm(), EventNames::message, event_init));
});
}
@ -1057,11 +1047,11 @@ Variant<JS::Handle<DOM::Event>, JS::Value> Window::event() const
}
// https://w3c.github.io/csswg-drafts/cssom/#dom-window-getcomputedstyle
WebIDL::ExceptionOr<JS::NonnullGCPtr<CSS::CSSStyleDeclaration>> Window::get_computed_style(DOM::Element& element, Optional<String> const& pseudo_element) const
JS::NonnullGCPtr<CSS::CSSStyleDeclaration> Window::get_computed_style(DOM::Element& element, Optional<String> const& pseudo_element) const
{
// FIXME: Make this fully spec compliant.
(void)pseudo_element;
return MUST_OR_THROW_OOM(heap().allocate<CSS::ResolvedCSSStyleDeclaration>(realm(), element));
return heap().allocate<CSS::ResolvedCSSStyleDeclaration>(realm(), element);
}
// https://w3c.github.io/csswg-drafts/cssom-view/#dom-window-matchmedia
@ -1071,21 +1061,21 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<CSS::MediaQueryList>> Window::match_media(S
auto parsed_media_query_list = parse_media_query_list(CSS::Parser::ParsingContext(associated_document()), query);
// 2. Return a new MediaQueryList object, with this's associated Document as the document, with parsed media query list as its associated media query list.
auto media_query_list = MUST_OR_THROW_OOM(heap().allocate<CSS::MediaQueryList>(realm(), associated_document(), move(parsed_media_query_list)));
auto media_query_list = heap().allocate<CSS::MediaQueryList>(realm(), associated_document(), move(parsed_media_query_list));
associated_document().add_media_query_list(media_query_list);
return media_query_list;
}
// https://w3c.github.io/csswg-drafts/cssom-view/#dom-window-screen
WebIDL::ExceptionOr<JS::NonnullGCPtr<CSS::Screen>> Window::screen()
JS::NonnullGCPtr<CSS::Screen> Window::screen()
{
// The screen attribute must return the Screen object associated with the Window object.
if (!m_screen)
m_screen = MUST_OR_THROW_OOM(heap().allocate<CSS::Screen>(realm(), *this));
m_screen = heap().allocate<CSS::Screen>(realm(), *this);
return JS::NonnullGCPtr { *m_screen };
}
WebIDL::ExceptionOr<JS::GCPtr<CSS::VisualViewport>> Window::visual_viewport()
JS::GCPtr<CSS::VisualViewport> Window::visual_viewport()
{
// If the associated document is fully active, the visualViewport attribute must return
// the VisualViewport object associated with the Window objects associated document.
@ -1396,31 +1386,31 @@ JS::GCPtr<Selection::Selection> Window::get_selection() const
}
// https://w3c.github.io/hr-time/#dom-windoworworkerglobalscope-performance
WebIDL::ExceptionOr<JS::NonnullGCPtr<HighResolutionTime::Performance>> Window::performance()
JS::NonnullGCPtr<HighResolutionTime::Performance> Window::performance()
{
if (!m_performance)
m_performance = MUST_OR_THROW_OOM(heap().allocate<HighResolutionTime::Performance>(realm(), *this));
m_performance = heap().allocate<HighResolutionTime::Performance>(realm(), *this);
return JS::NonnullGCPtr { *m_performance };
}
// https://w3c.github.io/webcrypto/#dom-windoworworkerglobalscope-crypto
WebIDL::ExceptionOr<JS::NonnullGCPtr<Crypto::Crypto>> Window::crypto()
JS::NonnullGCPtr<Crypto::Crypto> Window::crypto()
{
auto& realm = this->realm();
if (!m_crypto)
m_crypto = MUST_OR_THROW_OOM(heap().allocate<Crypto::Crypto>(realm, realm));
m_crypto = heap().allocate<Crypto::Crypto>(realm, realm);
return JS::NonnullGCPtr { *m_crypto };
}
// https://html.spec.whatwg.org/multipage/custom-elements.html#dom-window-customelements
WebIDL::ExceptionOr<JS::NonnullGCPtr<CustomElementRegistry>> Window::custom_elements()
JS::NonnullGCPtr<CustomElementRegistry> Window::custom_elements()
{
auto& realm = this->realm();
// The customElements attribute of the Window interface must return the CustomElementRegistry object for that Window object.
if (!m_custom_element_registry)
m_custom_element_registry = MUST_OR_THROW_OOM(heap().allocate<CustomElementRegistry>(realm, realm));
m_custom_element_registry = heap().allocate<CustomElementRegistry>(realm, realm);
return JS::NonnullGCPtr { *m_custom_element_registry };
}