mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:57:45 +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:
parent
980e7164fe
commit
72c9f56c66
337 changed files with 1229 additions and 1251 deletions
|
@ -113,7 +113,7 @@ WebIDL::ExceptionOr<JS::Value> package_data(JS::Realm& realm, ByteBuffer bytes,
|
|||
// Return a Blob whose contents are bytes and type attribute is mimeType.
|
||||
// NOTE: If extracting the mime type returns failure, other browsers set it to an empty string - not sure if that's spec'd.
|
||||
auto mime_type_string = mime_type.has_value() ? TRY_OR_THROW_OOM(vm, mime_type->serialized()) : String {};
|
||||
return TRY(FileAPI::Blob::create(realm, move(bytes), move(mime_type_string)));
|
||||
return FileAPI::Blob::create(realm, move(bytes), move(mime_type_string));
|
||||
}
|
||||
case PackageDataType::FormData:
|
||||
// If mimeType’s essence is "multipart/form-data", then:
|
||||
|
|
|
@ -45,12 +45,12 @@ WebIDL::ExceptionOr<Infrastructure::BodyWithType> extract_body(JS::Realm& realm,
|
|||
else if (auto const* blob_handle = object.get_pointer<JS::Handle<FileAPI::Blob>>()) {
|
||||
// FIXME: "set stream to the result of running object’s get stream"
|
||||
(void)blob_handle;
|
||||
stream = MUST_OR_THROW_OOM(realm.heap().allocate<Streams::ReadableStream>(realm, realm));
|
||||
stream = realm.heap().allocate<Streams::ReadableStream>(realm, realm);
|
||||
}
|
||||
// 4. Otherwise, set stream to a new ReadableStream object, and set up stream.
|
||||
else {
|
||||
// FIXME: "set up stream"
|
||||
stream = MUST_OR_THROW_OOM(realm.heap().allocate<Streams::ReadableStream>(realm, realm));
|
||||
stream = realm.heap().allocate<Streams::ReadableStream>(realm, realm);
|
||||
}
|
||||
|
||||
// 5. Assert: stream is a ReadableStream object.
|
||||
|
|
|
@ -111,7 +111,7 @@ JS::NonnullGCPtr<JS::Promise> fetch(JS::VM& vm, RequestInfo const& input, Reques
|
|||
|
||||
// 4. Set responseObject to the result of creating a Response object, given response, "immutable", and
|
||||
// relevantRealm.
|
||||
auto response_object = Response::create(relevant_realm, response, Headers::Guard::Immutable).release_value_but_fixme_should_propagate_errors();
|
||||
auto response_object = Response::create(relevant_realm, response, Headers::Guard::Immutable);
|
||||
response_object_handle = JS::make_handle(response_object);
|
||||
|
||||
// 5. Resolve p with responseObject.
|
||||
|
|
|
@ -859,7 +859,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_fetch(JS::Realm& rea
|
|||
// 4. If request’s service-workers mode is "all", then:
|
||||
if (request->service_workers_mode() == Infrastructure::Request::ServiceWorkersMode::All) {
|
||||
// 1. Let requestForServiceWorker be a clone of request.
|
||||
auto request_for_service_worker = TRY(request->clone(realm));
|
||||
auto request_for_service_worker = request->clone(realm);
|
||||
|
||||
// 2. If requestForServiceWorker’s body is non-null, then:
|
||||
if (!request_for_service_worker->body().has<Empty>()) {
|
||||
|
@ -1262,7 +1262,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> http_network_or_cache_fet
|
|||
// NOTE: Implementations are encouraged to avoid teeing request’s body’s stream when request’s body’s
|
||||
// source is null as only a single body is needed in that case. E.g., when request’s body’s source
|
||||
// is null, redirects and authentication will end up failing the fetch.
|
||||
http_request = TRY(request->clone(realm));
|
||||
http_request = request->clone(realm);
|
||||
|
||||
// 2. Set httpFetchParams to a copy of fetchParams.
|
||||
// 3. Set httpFetchParams’s request to httpRequest.
|
||||
|
|
|
@ -17,7 +17,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Headers>> Headers::construct_impl(JS::Realm
|
|||
auto& vm = realm.vm();
|
||||
|
||||
// The new Headers(init) constructor steps are:
|
||||
auto headers = MUST_OR_THROW_OOM(realm.heap().allocate<Headers>(realm, realm, Infrastructure::HeaderList::create(vm)));
|
||||
auto headers = realm.heap().allocate<Headers>(realm, realm, Infrastructure::HeaderList::create(vm));
|
||||
|
||||
// 1. Set this’s guard to "none".
|
||||
headers->m_guard = Guard::None;
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Web::Bindings {
|
|||
template<>
|
||||
void Intrinsics::create_web_prototype_and_constructor<HeadersIteratorPrototype>(JS::Realm& realm)
|
||||
{
|
||||
auto prototype = heap().allocate<HeadersIteratorPrototype>(realm, realm).release_allocated_value_but_fixme_should_propagate_errors();
|
||||
auto prototype = heap().allocate<HeadersIteratorPrototype>(realm, realm);
|
||||
m_prototypes.set("HeadersIterator"sv, prototype);
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,9 @@ void Intrinsics::create_web_prototype_and_constructor<HeadersIteratorPrototype>(
|
|||
|
||||
namespace Web::Fetch {
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<HeadersIterator>> HeadersIterator::create(Headers const& headers, JS::Object::PropertyKind iteration_kind)
|
||||
JS::NonnullGCPtr<HeadersIterator> HeadersIterator::create(Headers const& headers, JS::Object::PropertyKind iteration_kind)
|
||||
{
|
||||
return MUST_OR_THROW_OOM(headers.heap().allocate<HeadersIterator>(headers.realm(), headers, iteration_kind));
|
||||
return headers.heap().allocate<HeadersIterator>(headers.realm(), headers, iteration_kind);
|
||||
}
|
||||
|
||||
HeadersIterator::HeadersIterator(Headers const& headers, JS::Object::PropertyKind iteration_kind)
|
||||
|
|
|
@ -16,7 +16,7 @@ class HeadersIterator final : public Bindings::PlatformObject {
|
|||
WEB_PLATFORM_OBJECT(HeadersIterator, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<HeadersIterator>> create(Headers const&, JS::Object::PropertyKind iteration_kind);
|
||||
[[nodiscard]] static JS::NonnullGCPtr<HeadersIterator> create(Headers const&, JS::Object::PropertyKind iteration_kind);
|
||||
|
||||
virtual ~HeadersIterator() override;
|
||||
|
||||
|
|
|
@ -26,12 +26,12 @@ Body::Body(JS::Handle<Streams::ReadableStream> stream, SourceType source, Option
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-body-clone
|
||||
WebIDL::ExceptionOr<Body> Body::clone(JS::Realm& realm) const
|
||||
Body Body::clone(JS::Realm& realm) const
|
||||
{
|
||||
// To clone a body body, run these steps:
|
||||
// FIXME: 1. Let « out1, out2 » be the result of teeing body’s stream.
|
||||
// FIXME: 2. Set body’s stream to out1.
|
||||
auto out2 = MUST_OR_THROW_OOM(realm.heap().allocate<Streams::ReadableStream>(realm, realm));
|
||||
auto out2 = realm.heap().allocate<Streams::ReadableStream>(realm, realm);
|
||||
|
||||
// 3. Return a body whose stream is out2 and other members are copied from body.
|
||||
return Body { JS::make_handle(out2), m_source, m_length };
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
[[nodiscard]] SourceType const& source() const { return m_source; }
|
||||
[[nodiscard]] Optional<u64> const& length() const { return m_length; }
|
||||
|
||||
WebIDL::ExceptionOr<Body> clone(JS::Realm&) const;
|
||||
[[nodiscard]] Body clone(JS::Realm&) const;
|
||||
|
||||
WebIDL::ExceptionOr<void> fully_read(JS::Realm&, ProcessBodyCallback process_body, ProcessBodyErrorCallback process_body_error, TaskDestination task_destination) const;
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ ErrorOr<ByteBuffer> Request::byte_serialize_origin() const
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-request-clone
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::clone(JS::Realm& realm) const
|
||||
JS::NonnullGCPtr<Request> Request::clone(JS::Realm& realm) const
|
||||
{
|
||||
// To clone a request request, run these steps:
|
||||
auto& vm = realm.vm();
|
||||
|
@ -250,7 +250,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::clone(JS::Realm& realm)
|
|||
|
||||
// 2. If request’s body is non-null, set newRequest’s body to the result of cloning request’s body.
|
||||
if (auto const* body = m_body.get_pointer<Body>())
|
||||
new_request->set_body(TRY(body->clone(realm)));
|
||||
new_request->set_body(body->clone(realm));
|
||||
|
||||
// 3. Return newRequest.
|
||||
return new_request;
|
||||
|
|
|
@ -297,7 +297,7 @@ public:
|
|||
[[nodiscard]] ErrorOr<String> serialize_origin() const;
|
||||
[[nodiscard]] ErrorOr<ByteBuffer> byte_serialize_origin() const;
|
||||
|
||||
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> clone(JS::Realm&) const;
|
||||
[[nodiscard]] JS::NonnullGCPtr<Request> clone(JS::Realm&) const;
|
||||
|
||||
[[nodiscard]] ErrorOr<void> add_range_header(u64 first, Optional<u64> const& last);
|
||||
[[nodiscard]] ErrorOr<void> add_origin_header();
|
||||
|
|
|
@ -164,7 +164,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::clone(JS::Realm& realm
|
|||
|
||||
// 3. If response’s body is non-null, then set newResponse’s body to the result of cloning response’s body.
|
||||
if (m_body.has_value())
|
||||
new_response->set_body(TRY(m_body->clone(realm)));
|
||||
new_response->set_body(m_body->clone(realm));
|
||||
|
||||
// 4. Return newResponse.
|
||||
return new_response;
|
||||
|
|
|
@ -79,18 +79,18 @@ Optional<Infrastructure::Body&> Request::body_impl()
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#request-create
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::create(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::Request> request, Headers::Guard guard)
|
||||
JS::NonnullGCPtr<Request> Request::create(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::Request> request, Headers::Guard guard)
|
||||
{
|
||||
// 1. Let requestObject be a new Request object with realm.
|
||||
// 2. Set requestObject’s request to request.
|
||||
auto request_object = MUST_OR_THROW_OOM(realm.heap().allocate<Request>(realm, realm, request));
|
||||
auto request_object = realm.heap().allocate<Request>(realm, realm, request);
|
||||
|
||||
// 3. Set requestObject’s headers to a new Headers object with realm, whose headers list is request’s headers list and guard is guard.
|
||||
request_object->m_headers = MUST_OR_THROW_OOM(realm.heap().allocate<Headers>(realm, realm, request->header_list()));
|
||||
request_object->m_headers = realm.heap().allocate<Headers>(realm, realm, request->header_list());
|
||||
request_object->m_headers->set_guard(guard);
|
||||
|
||||
// 4. Set requestObject’s signal to a new AbortSignal object with realm.
|
||||
request_object->m_signal = MUST_OR_THROW_OOM(realm.heap().allocate<DOM::AbortSignal>(realm, realm));
|
||||
request_object->m_signal = realm.heap().allocate<DOM::AbortSignal>(realm, realm);
|
||||
|
||||
// 5. Return requestObject.
|
||||
return request_object;
|
||||
|
@ -102,7 +102,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
|
|||
auto& vm = realm.vm();
|
||||
|
||||
// Referred to as 'this' in the spec.
|
||||
auto request_object = MUST_OR_THROW_OOM(realm.heap().allocate<Request>(realm, realm, Infrastructure::Request::create(vm)));
|
||||
auto request_object = realm.heap().allocate<Request>(realm, realm, Infrastructure::Request::create(vm));
|
||||
|
||||
// 1. Let request be null.
|
||||
JS::GCPtr<Infrastructure::Request> input_request;
|
||||
|
@ -387,14 +387,14 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
|
|||
|
||||
// 28. Set this’s signal to a new AbortSignal object with this’s relevant Realm.
|
||||
auto& this_relevant_realm = HTML::relevant_realm(*request_object);
|
||||
request_object->m_signal = MUST_OR_THROW_OOM(realm.heap().allocate<DOM::AbortSignal>(this_relevant_realm, this_relevant_realm));
|
||||
request_object->m_signal = realm.heap().allocate<DOM::AbortSignal>(this_relevant_realm, this_relevant_realm);
|
||||
|
||||
// 29. If signal is not null, then make this’s signal follow signal.
|
||||
if (input_signal != nullptr)
|
||||
request_object->m_signal->follow(*input_signal);
|
||||
|
||||
// 30. Set this’s headers to a new Headers object with this’s relevant Realm, whose header list is request’s header list and guard is "request".
|
||||
request_object->m_headers = MUST_OR_THROW_OOM(realm.heap().allocate<Headers>(realm, realm, request->header_list()));
|
||||
request_object->m_headers = realm.heap().allocate<Headers>(realm, realm, request->header_list());
|
||||
request_object->m_headers->set_guard(Headers::Guard::Request);
|
||||
|
||||
// 31. If this’s request’s mode is "no-cors", then:
|
||||
|
@ -639,10 +639,10 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::clone() const
|
|||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Request is unusable"sv };
|
||||
|
||||
// 2. Let clonedRequest be the result of cloning this’s request.
|
||||
auto cloned_request = TRY(m_request->clone(realm));
|
||||
auto cloned_request = m_request->clone(realm);
|
||||
|
||||
// 3. Let clonedRequestObject be the result of creating a Request object, given clonedRequest, this’s headers’s guard, and this’s relevant Realm.
|
||||
auto cloned_request_object = TRY(Request::create(HTML::relevant_realm(*this), cloned_request, m_headers->guard()));
|
||||
auto cloned_request_object = Request::create(HTML::relevant_realm(*this), cloned_request, m_headers->guard());
|
||||
|
||||
// 4. Make clonedRequestObject’s signal follow this’s signal.
|
||||
cloned_request_object->m_signal->follow(*m_signal);
|
||||
|
|
|
@ -66,7 +66,7 @@ class Request final
|
|||
WEB_PLATFORM_OBJECT(Request, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> create(JS::Realm&, JS::NonnullGCPtr<Infrastructure::Request>, Headers::Guard);
|
||||
[[nodiscard]] static JS::NonnullGCPtr<Request> create(JS::Realm&, JS::NonnullGCPtr<Infrastructure::Request>, Headers::Guard);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> construct_impl(JS::Realm&, RequestInfo const& input, RequestInit const& init = {});
|
||||
|
||||
virtual ~Request() override;
|
||||
|
|
|
@ -71,14 +71,14 @@ Optional<Infrastructure::Body&> Response::body_impl()
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#response-create
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::create(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::Response> response, Headers::Guard guard)
|
||||
JS::NonnullGCPtr<Response> Response::create(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::Response> response, Headers::Guard guard)
|
||||
{
|
||||
// 1. Let responseObject be a new Response object with realm.
|
||||
// 2. Set responseObject’s response to response.
|
||||
auto response_object = MUST_OR_THROW_OOM(realm.heap().allocate<Response>(realm, realm, response));
|
||||
auto response_object = realm.heap().allocate<Response>(realm, realm, response);
|
||||
|
||||
// 3. Set responseObject’s headers to a new Headers object with realm, whose headers list is response’s headers list and guard is guard.
|
||||
response_object->m_headers = MUST_OR_THROW_OOM(realm.heap().allocate<Headers>(realm, realm, response->header_list()));
|
||||
response_object->m_headers = realm.heap().allocate<Headers>(realm, realm, response->header_list());
|
||||
response_object->m_headers->set_guard(guard);
|
||||
|
||||
// 4. Return responseObject.
|
||||
|
@ -134,14 +134,14 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::construct_impl(JS::Rea
|
|||
auto& vm = realm.vm();
|
||||
|
||||
// Referred to as 'this' in the spec.
|
||||
auto response_object = MUST_OR_THROW_OOM(realm.heap().allocate<Response>(realm, realm, Infrastructure::Response::create(vm)));
|
||||
auto response_object = realm.heap().allocate<Response>(realm, realm, Infrastructure::Response::create(vm));
|
||||
|
||||
// 1. Set this’s response to a new response.
|
||||
// NOTE: This is done at the beginning as the 'this' value Response object
|
||||
// cannot exist with a null Infrastructure::Response.
|
||||
|
||||
// 2. Set this’s headers to a new Headers object with this’s relevant Realm, whose header list is this’s response’s header list and guard is "response".
|
||||
response_object->m_headers = MUST_OR_THROW_OOM(realm.heap().allocate<Headers>(realm, realm, response_object->response()->header_list()));
|
||||
response_object->m_headers = realm.heap().allocate<Headers>(realm, realm, response_object->response()->header_list());
|
||||
response_object->m_headers->set_guard(Headers::Guard::Response);
|
||||
|
||||
// 3. Let bodyWithType be null.
|
||||
|
@ -158,7 +158,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::construct_impl(JS::Rea
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#dom-response-error
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::error(JS::VM& vm)
|
||||
JS::NonnullGCPtr<Response> Response::error(JS::VM& vm)
|
||||
{
|
||||
// The static error() method steps are to return the result of creating a Response object, given a new network error, "immutable", and this’s relevant Realm.
|
||||
// FIXME: How can we reliably get 'this', i.e. the object the function was called on, in IDL-defined functions?
|
||||
|
@ -184,7 +184,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::redirect(JS::VM& vm, S
|
|||
|
||||
// 4. Let responseObject be the result of creating a Response object, given a new response, "immutable", and this’s relevant Realm.
|
||||
// FIXME: How can we reliably get 'this', i.e. the object the function was called on, in IDL-defined functions?
|
||||
auto response_object = TRY(Response::create(realm, Infrastructure::Response::create(vm), Headers::Guard::Immutable));
|
||||
auto response_object = Response::create(realm, Infrastructure::Response::create(vm), Headers::Guard::Immutable);
|
||||
|
||||
// 5. Set responseObject’s response’s status to status.
|
||||
response_object->response()->set_status(status);
|
||||
|
@ -213,7 +213,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::json(JS::VM& vm, JS::V
|
|||
|
||||
// 3. Let responseObject be the result of creating a Response object, given a new response, "response", and this’s relevant Realm.
|
||||
// FIXME: How can we reliably get 'this', i.e. the object the function was called on, in IDL-defined functions?
|
||||
auto response_object = TRY(Response::create(realm, Infrastructure::Response::create(vm), Headers::Guard::Response));
|
||||
auto response_object = Response::create(realm, Infrastructure::Response::create(vm), Headers::Guard::Response);
|
||||
|
||||
// 4. Perform initialize a response given responseObject, init, and (body, "application/json").
|
||||
auto body_with_type = Infrastructure::BodyWithType {
|
||||
|
@ -294,7 +294,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::clone() const
|
|||
auto cloned_response = TRY(m_response->clone(realm));
|
||||
|
||||
// 3. Return the result of creating a Response object, given clonedResponse, this’s headers’s guard, and this’s relevant Realm.
|
||||
return TRY(Response::create(HTML::relevant_realm(*this), cloned_response, m_headers->guard()));
|
||||
return Response::create(HTML::relevant_realm(*this), cloned_response, m_headers->guard());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ class Response final
|
|||
WEB_PLATFORM_OBJECT(Response, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> create(JS::Realm&, JS::NonnullGCPtr<Infrastructure::Response>, Headers::Guard);
|
||||
[[nodiscard]] static JS::NonnullGCPtr<Response> create(JS::Realm&, JS::NonnullGCPtr<Infrastructure::Response>, Headers::Guard);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> construct_impl(JS::Realm&, Optional<BodyInit> const& body = {}, ResponseInit const& init = {});
|
||||
|
||||
virtual ~Response() override;
|
||||
|
@ -48,7 +48,7 @@ public:
|
|||
[[nodiscard]] JS::NonnullGCPtr<Infrastructure::Response> response() const { return m_response; }
|
||||
|
||||
// JS API functions
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> error(JS::VM&);
|
||||
[[nodiscard]] static JS::NonnullGCPtr<Response> error(JS::VM&);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> redirect(JS::VM&, String const& url, u16 status);
|
||||
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> json(JS::VM&, JS::Value data, ResponseInit const& init = {});
|
||||
[[nodiscard]] Bindings::ResponseType type() const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue