mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 09:24:57 +00:00
LibWeb: Propagate Realm instead of VM more through Fetch
This makes Fetch rely less on using main_thread_vm().current_realm(), which relies on the dummy execution context if no JavaScript is currently running.
This commit is contained in:
parent
f7ff1fd985
commit
9acc542059
19 changed files with 62 additions and 49 deletions
|
@ -132,7 +132,7 @@ WebIDL::ExceptionOr<JS::Value> package_data(JS::Realm& realm, ByteBuffer bytes,
|
|||
}
|
||||
case PackageDataType::JSON:
|
||||
// Return the result of running parse JSON from bytes on bytes.
|
||||
return Infra::parse_json_bytes_to_javascript_value(vm, bytes);
|
||||
return Infra::parse_json_bytes_to_javascript_value(realm, bytes);
|
||||
case PackageDataType::Text:
|
||||
// Return the result of running UTF-8 decode on bytes.
|
||||
return JS::PrimitiveString::create(vm, TRY_OR_THROW_OOM(vm, String::from_utf8(bytes)));
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <AK/TypeCasts.h>
|
||||
#include <LibJS/Runtime/PromiseCapability.h>
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/Bindings/HostDefined.h>
|
||||
#include <LibWeb/DOM/AbortSignal.h>
|
||||
#include <LibWeb/Fetch/FetchMethod.h>
|
||||
#include <LibWeb/Fetch/Fetching/Fetching.h>
|
||||
|
@ -36,7 +37,7 @@ JS::NonnullGCPtr<JS::Promise> fetch_impl(JS::VM& vm, RequestInfo const& input, R
|
|||
if (exception_or_request_object.is_exception()) {
|
||||
// FIXME: We should probably make this a public API?
|
||||
auto throw_completion = Bindings::Detail::dom_exception_to_throw_completion(vm, exception_or_request_object.release_error());
|
||||
WebIDL::reject_promise(vm, promise_capability, *throw_completion.value());
|
||||
WebIDL::reject_promise(realm, promise_capability, *throw_completion.value());
|
||||
return verify_cast<JS::Promise>(*promise_capability->promise().ptr());
|
||||
}
|
||||
auto request_object = exception_or_request_object.release_value();
|
||||
|
@ -47,7 +48,7 @@ JS::NonnullGCPtr<JS::Promise> fetch_impl(JS::VM& vm, RequestInfo const& input, R
|
|||
// 4. If requestObject’s signal is aborted, then:
|
||||
if (request_object->signal()->aborted()) {
|
||||
// 1. Abort the fetch() call with p, request, null, and requestObject’s signal’s abort reason.
|
||||
abort_fetch(vm, promise_capability, request, nullptr, request_object->signal()->reason());
|
||||
abort_fetch(realm, promise_capability, request, nullptr, request_object->signal()->reason());
|
||||
|
||||
// 2. Return p.
|
||||
return verify_cast<JS::Promise>(*promise_capability->promise().ptr());
|
||||
|
@ -79,11 +80,21 @@ JS::NonnullGCPtr<JS::Promise> fetch_impl(JS::VM& vm, RequestInfo const& input, R
|
|||
|
||||
// 12. Set controller to the result of calling fetch given request and processResponse given response being these
|
||||
// steps:
|
||||
auto process_response = [&vm, locally_aborted, promise_capability, request, response_object_handle, &relevant_realm](JS::NonnullGCPtr<Infrastructure::Response> response) mutable {
|
||||
auto process_response = [locally_aborted, promise_capability, request, response_object_handle, &relevant_realm](JS::NonnullGCPtr<Infrastructure::Response> response) mutable {
|
||||
// 1. If locallyAborted is true, then abort these steps.
|
||||
if (locally_aborted->value())
|
||||
return;
|
||||
|
||||
// NOTE: Not part of the spec, but we need to have an execution context on the stack to call native functions.
|
||||
// (In this case, Promise functions)
|
||||
auto& environment_settings_object = Bindings::host_defined_environment_settings_object(relevant_realm);
|
||||
environment_settings_object.prepare_to_run_script();
|
||||
|
||||
ScopeGuard guard = [&]() {
|
||||
// See above NOTE.
|
||||
environment_settings_object.clean_up_after_running_script();
|
||||
};
|
||||
|
||||
// 2. If response’s aborted flag is set, then:
|
||||
if (response->aborted()) {
|
||||
// FIXME: 1. Let deserializedError be the result of deserialize a serialized abort reason given controller’s
|
||||
|
@ -91,7 +102,7 @@ JS::NonnullGCPtr<JS::Promise> fetch_impl(JS::VM& vm, RequestInfo const& input, R
|
|||
auto deserialized_error = JS::js_undefined();
|
||||
|
||||
// 2. Abort the fetch() call with p, request, responseObject, and deserializedError.
|
||||
abort_fetch(vm, promise_capability, request, response_object_handle.cell(), deserialized_error);
|
||||
abort_fetch(relevant_realm, promise_capability, request, response_object_handle.cell(), deserialized_error);
|
||||
|
||||
// 3. Abort these steps.
|
||||
return;
|
||||
|
@ -100,7 +111,7 @@ JS::NonnullGCPtr<JS::Promise> fetch_impl(JS::VM& vm, RequestInfo const& input, R
|
|||
// 3. If response is a network error, then reject p with a TypeError and abort these steps.
|
||||
if (response->is_network_error()) {
|
||||
auto message = response->network_error_message().value_or("Response is a network error"sv);
|
||||
WebIDL::reject_promise(vm, promise_capability, JS::TypeError::create(relevant_realm, message).release_allocated_value_but_fixme_should_propagate_errors());
|
||||
WebIDL::reject_promise(relevant_realm, promise_capability, JS::TypeError::create(relevant_realm, message).release_allocated_value_but_fixme_should_propagate_errors());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -110,7 +121,7 @@ JS::NonnullGCPtr<JS::Promise> fetch_impl(JS::VM& vm, RequestInfo const& input, R
|
|||
response_object_handle = JS::make_handle(response_object);
|
||||
|
||||
// 5. Resolve p with responseObject.
|
||||
WebIDL::resolve_promise(vm, promise_capability, response_object);
|
||||
WebIDL::resolve_promise(relevant_realm, promise_capability, response_object);
|
||||
};
|
||||
controller = MUST(Fetching::fetch(
|
||||
realm,
|
||||
|
@ -126,7 +137,7 @@ JS::NonnullGCPtr<JS::Promise> fetch_impl(JS::VM& vm, RequestInfo const& input, R
|
|||
})));
|
||||
|
||||
// 11. Add the following abort steps to requestObject’s signal:
|
||||
request_object->signal()->add_abort_algorithm([&vm, locally_aborted, request, controller, promise_capability_handle = JS::make_handle(*promise_capability), request_object_handle = JS::make_handle(*request_object), response_object_handle] {
|
||||
request_object->signal()->add_abort_algorithm([locally_aborted, request, controller, promise_capability_handle = JS::make_handle(*promise_capability), request_object_handle = JS::make_handle(*request_object), response_object_handle, &relevant_realm] {
|
||||
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Request object signal's abort algorithm called");
|
||||
|
||||
auto& promise_capability = *promise_capability_handle;
|
||||
|
@ -140,10 +151,10 @@ JS::NonnullGCPtr<JS::Promise> fetch_impl(JS::VM& vm, RequestInfo const& input, R
|
|||
VERIFY(controller);
|
||||
|
||||
// 3. Abort controller with requestObject’s signal’s abort reason.
|
||||
controller->abort(vm, request_object.signal()->reason());
|
||||
controller->abort(relevant_realm, request_object.signal()->reason());
|
||||
|
||||
// 4. Abort the fetch() call with p, request, responseObject, and requestObject’s signal’s abort reason.
|
||||
abort_fetch(vm, promise_capability, request, response_object, request_object.signal()->reason());
|
||||
abort_fetch(relevant_realm, promise_capability, request, response_object, request_object.signal()->reason());
|
||||
});
|
||||
|
||||
// 13. Return p.
|
||||
|
@ -151,13 +162,13 @@ JS::NonnullGCPtr<JS::Promise> fetch_impl(JS::VM& vm, RequestInfo const& input, R
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#abort-fetch
|
||||
void abort_fetch(JS::VM& vm, WebIDL::Promise const& promise, JS::NonnullGCPtr<Infrastructure::Request> request, JS::GCPtr<Response> response_object, JS::Value error)
|
||||
void abort_fetch(JS::Realm& realm, WebIDL::Promise const& promise, JS::NonnullGCPtr<Infrastructure::Request> request, JS::GCPtr<Response> response_object, JS::Value error)
|
||||
{
|
||||
dbgln_if(WEB_FETCH_DEBUG, "Fetch: Aborting fetch with: request @ {}, error = {}", request.ptr(), error);
|
||||
|
||||
// 1. Reject promise with error.
|
||||
// NOTE: This is a no-op if promise has already fulfilled.
|
||||
WebIDL::reject_promise(vm, promise, error);
|
||||
WebIDL::reject_promise(realm, promise, error);
|
||||
|
||||
// 2. If request’s body is non-null and is readable, then cancel request’s body with error.
|
||||
if (auto* body = request->body().get_pointer<Infrastructure::Body>(); body != nullptr && body->stream()->is_readable()) {
|
||||
|
|
|
@ -15,6 +15,6 @@
|
|||
namespace Web::Fetch {
|
||||
|
||||
JS::NonnullGCPtr<JS::Promise> fetch_impl(JS::VM&, RequestInfo const& input, RequestInit const& init = {});
|
||||
void abort_fetch(JS::VM&, WebIDL::Promise const&, JS::NonnullGCPtr<Infrastructure::Request>, JS::GCPtr<Response>, JS::Value error);
|
||||
void abort_fetch(JS::Realm&, WebIDL::Promise const&, JS::NonnullGCPtr<Infrastructure::Request>, JS::GCPtr<Response>, JS::Value error);
|
||||
|
||||
}
|
||||
|
|
|
@ -759,7 +759,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(vm));
|
||||
auto request_for_service_worker = TRY(request->clone(realm));
|
||||
|
||||
// 2. If requestForServiceWorker’s body is non-null, then:
|
||||
if (!request_for_service_worker->body().has<Empty>()) {
|
||||
|
@ -1147,7 +1147,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(vm));
|
||||
http_request = TRY(request->clone(realm));
|
||||
|
||||
// 2. Set httpFetchParams to a copy of fetchParams.
|
||||
// 3. Set httpFetchParams’s request to httpRequest.
|
||||
|
|
|
@ -55,10 +55,8 @@ JS::NonnullGCPtr<FetchTimingInfo> FetchController::extract_full_timing_info() co
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#fetch-controller-abort
|
||||
void FetchController::abort(JS::VM& vm, Optional<JS::Value> error)
|
||||
void FetchController::abort(JS::Realm& realm, Optional<JS::Value> error)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Set controller’s state to "aborted".
|
||||
m_state = State::Aborted;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
void report_timing(JS::Object const&) const;
|
||||
void process_next_manual_redirect() const;
|
||||
[[nodiscard]] JS::NonnullGCPtr<FetchTimingInfo> extract_full_timing_info() const;
|
||||
void abort(JS::VM&, Optional<JS::Value>);
|
||||
void abort(JS::Realm&, Optional<JS::Value>);
|
||||
void terminate();
|
||||
|
||||
private:
|
||||
|
|
|
@ -25,16 +25,12 @@ Body::Body(JS::Handle<Streams::ReadableStream> stream, SourceType source, Option
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-body-clone
|
||||
WebIDL::ExceptionOr<Body> Body::clone() const
|
||||
WebIDL::ExceptionOr<Body> Body::clone(JS::Realm& realm) const
|
||||
{
|
||||
// To clone a body body, run these steps:
|
||||
|
||||
auto& vm = Bindings::main_thread_vm();
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 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(vm.heap().allocate<Streams::ReadableStream>(realm, realm));
|
||||
auto out2 = MUST_OR_THROW_OOM(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 };
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
[[nodiscard]] SourceType const& source() const { return m_source; }
|
||||
[[nodiscard]] Optional<u64> const& length() const { return m_length; }
|
||||
|
||||
WebIDL::ExceptionOr<Body> clone() const;
|
||||
WebIDL::ExceptionOr<Body> clone(JS::Realm&) const;
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> fully_read_as_promise() const;
|
||||
|
||||
|
|
|
@ -195,9 +195,10 @@ ErrorOr<ByteBuffer> Request::byte_serialize_origin() const
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-request-clone
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::clone(JS::VM& vm) const
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::clone(JS::Realm& realm) const
|
||||
{
|
||||
// To clone a request request, run these steps:
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. Let newRequest be a copy of request, except for its body.
|
||||
auto new_request = Infrastructure::Request::create(vm);
|
||||
|
@ -242,7 +243,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::clone(JS::VM& vm) const
|
|||
|
||||
// 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()));
|
||||
new_request->set_body(TRY(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::VM&) const;
|
||||
[[nodiscard]] WebIDL::ExceptionOr<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();
|
||||
|
|
|
@ -127,13 +127,14 @@ ErrorOr<Optional<AK::URL>> Response::location_url(Optional<String> const& reques
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-response-clone
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::clone(JS::VM& vm) const
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::clone(JS::Realm& realm) const
|
||||
{
|
||||
// To clone a response response, run these steps:
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. If response is a filtered response, then return a new identical filtered response whose internal response is a clone of response’s internal response.
|
||||
if (is<FilteredResponse>(*this)) {
|
||||
auto internal_response = TRY(static_cast<FilteredResponse const&>(*this).internal_response()->clone(vm));
|
||||
auto internal_response = TRY(static_cast<FilteredResponse const&>(*this).internal_response()->clone(realm));
|
||||
if (is<BasicFilteredResponse>(*this))
|
||||
return TRY_OR_THROW_OOM(vm, BasicFilteredResponse::create(vm, internal_response));
|
||||
if (is<CORSFilteredResponse>(*this))
|
||||
|
@ -164,7 +165,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::clone(JS::VM& vm) cons
|
|||
|
||||
// 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()));
|
||||
new_response->set_body(TRY(m_body->clone(realm)));
|
||||
|
||||
// 4. Return newResponse.
|
||||
return new_response;
|
||||
|
|
|
@ -106,7 +106,7 @@ public:
|
|||
[[nodiscard]] Optional<AK::URL const&> url() const;
|
||||
[[nodiscard]] ErrorOr<Optional<AK::URL>> location_url(Optional<String> const& request_fragment) const;
|
||||
|
||||
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> clone(JS::VM&) const;
|
||||
[[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> clone(JS::Realm&) const;
|
||||
|
||||
// Non-standard
|
||||
[[nodiscard]] Optional<StringView> network_error_message() const;
|
||||
|
|
|
@ -634,14 +634,14 @@ Bindings::RequestDuplex Request::duplex() const
|
|||
// https://fetch.spec.whatwg.org/#dom-request-clone
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::clone() const
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 1. If this is unusable, then throw a TypeError.
|
||||
if (is_unusable())
|
||||
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(vm));
|
||||
auto cloned_request = TRY(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()));
|
||||
|
|
|
@ -286,14 +286,14 @@ JS::NonnullGCPtr<Headers> Response::headers() const
|
|||
// https://fetch.spec.whatwg.org/#dom-response-clone
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::clone() const
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 1. If this is unusable, then throw a TypeError.
|
||||
if (is_unusable())
|
||||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Response is unusable"sv };
|
||||
|
||||
// 2. Let clonedResponse be the result of cloning this’s response.
|
||||
auto cloned_response = TRY(m_response->clone(vm));
|
||||
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()));
|
||||
|
|
|
@ -15,23 +15,25 @@
|
|||
namespace Web::Infra {
|
||||
|
||||
// https://infra.spec.whatwg.org/#parse-a-json-string-to-a-javascript-value
|
||||
WebIDL::ExceptionOr<JS::Value> parse_json_string_to_javascript_value(JS::VM& vm, StringView string)
|
||||
WebIDL::ExceptionOr<JS::Value> parse_json_string_to_javascript_value(JS::Realm& realm, StringView string)
|
||||
{
|
||||
auto& realm = *vm.current_realm();
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. Return ? Call(%JSON.parse%, undefined, « string »).
|
||||
return TRY(JS::call(vm, realm.intrinsics().json_parse_function(), JS::js_undefined(), MUST_OR_THROW_OOM(JS::PrimitiveString::create(vm, string))));
|
||||
}
|
||||
|
||||
// https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value
|
||||
WebIDL::ExceptionOr<JS::Value> parse_json_bytes_to_javascript_value(JS::VM& vm, ReadonlyBytes bytes)
|
||||
WebIDL::ExceptionOr<JS::Value> parse_json_bytes_to_javascript_value(JS::Realm& realm, ReadonlyBytes bytes)
|
||||
{
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. Let string be the result of running UTF-8 decode on bytes.
|
||||
TextCodec::UTF8Decoder decoder;
|
||||
auto string = TRY_OR_THROW_OOM(vm, decoder.to_utf8(bytes));
|
||||
|
||||
// 2. Return the result of parsing a JSON string to an Infra value given string.
|
||||
return parse_json_string_to_javascript_value(vm, string);
|
||||
return parse_json_string_to_javascript_value(realm, string);
|
||||
}
|
||||
|
||||
// https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
|
||||
namespace Web::Infra {
|
||||
|
||||
WebIDL::ExceptionOr<JS::Value> parse_json_string_to_javascript_value(JS::VM&, StringView);
|
||||
WebIDL::ExceptionOr<JS::Value> parse_json_bytes_to_javascript_value(JS::VM&, ReadonlyBytes);
|
||||
WebIDL::ExceptionOr<JS::Value> parse_json_string_to_javascript_value(JS::Realm&, StringView);
|
||||
WebIDL::ExceptionOr<JS::Value> parse_json_bytes_to_javascript_value(JS::Realm&, ReadonlyBytes);
|
||||
WebIDL::ExceptionOr<String> serialize_javascript_value_to_json_string(JS::VM&, JS::Value);
|
||||
WebIDL::ExceptionOr<ByteBuffer> serialize_javascript_value_to_json_bytes(JS::VM&, JS::Value);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <LibJS/Runtime/PromiseConstructor.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/Bindings/HostDefined.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
#include <LibWeb/WebIDL/Promise.h>
|
||||
|
||||
|
@ -69,20 +70,23 @@ JS::NonnullGCPtr<Promise> create_rejected_promise(JS::Realm& realm, JS::Value re
|
|||
}
|
||||
|
||||
// https://webidl.spec.whatwg.org/#resolve
|
||||
void resolve_promise(JS::VM& vm, Promise const& promise, JS::Value value)
|
||||
void resolve_promise(JS::Realm& realm, Promise const& promise, JS::Value value)
|
||||
{
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. If x is not given, then let it be the undefined value.
|
||||
// NOTE: This is done via the default argument.
|
||||
|
||||
// 2. Let value be the result of converting x to an ECMAScript value.
|
||||
|
||||
// 3. Perform ! Call(p.[[Resolve]], undefined, « value »).
|
||||
MUST(JS::call(vm, *promise.resolve(), JS::js_undefined(), value));
|
||||
}
|
||||
|
||||
// https://webidl.spec.whatwg.org/#reject
|
||||
void reject_promise(JS::VM& vm, Promise const& promise, JS::Value reason)
|
||||
void reject_promise(JS::Realm& realm, Promise const& promise, JS::Value reason)
|
||||
{
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. Perform ! Call(p.[[Reject]], undefined, « r »).
|
||||
MUST(JS::call(vm, *promise.reject(), JS::js_undefined(), reason));
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ using Promise = JS::PromiseCapability;
|
|||
JS::NonnullGCPtr<Promise> create_promise(JS::Realm&);
|
||||
JS::NonnullGCPtr<Promise> create_resolved_promise(JS::Realm&, JS::Value);
|
||||
JS::NonnullGCPtr<Promise> create_rejected_promise(JS::Realm&, JS::Value);
|
||||
void resolve_promise(JS::VM&, Promise const&, JS::Value = JS::js_undefined());
|
||||
void reject_promise(JS::VM&, Promise const&, 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<JS::Promise> react_to_promise(Promise const&, Optional<ReactionSteps> on_fulfilled_callback, Optional<ReactionSteps> on_rejected_callback);
|
||||
JS::NonnullGCPtr<JS::Promise> upon_fulfillment(Promise const&, ReactionSteps);
|
||||
JS::NonnullGCPtr<JS::Promise> upon_rejection(Promise const&, ReactionSteps);
|
||||
|
|
|
@ -182,7 +182,7 @@ WebIDL::ExceptionOr<JS::Value> XMLHttpRequest::response()
|
|||
return JS::js_null();
|
||||
|
||||
// 3. Let jsonObject be the result of running parse JSON from bytes on this’s received bytes. If that threw an exception, then return null.
|
||||
auto json_object_result = Infra::parse_json_bytes_to_javascript_value(vm, m_received_bytes);
|
||||
auto json_object_result = Infra::parse_json_bytes_to_javascript_value(realm(), m_received_bytes);
|
||||
if (json_object_result.is_error())
|
||||
return JS::js_null();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue