mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 20:29:18 +00:00
LibWeb: Prefer react_to_promise over upon_fulfillment + upon_rejection
While debugging a spec-compliant implementation of ReadableStreamPipeTo, I spent a lot of time inspecting promise internals. This is much less noisy if we halve the number of temporary promises.
This commit is contained in:
parent
3033929bb6
commit
e9a7694cdb
Notes:
github-actions[bot]
2025-04-11 16:12:13 +00:00
Author: https://github.com/trflynn89
Commit: e9a7694cdb
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4311
Reviewed-by: https://github.com/ADKaster
Reviewed-by: https://github.com/shannonbooth ✅
2 changed files with 190 additions and 181 deletions
|
@ -836,37 +836,38 @@ void fetch_descendants_of_and_link_a_module_script(JS::Realm& realm,
|
||||||
// 5. Let loadingPromise be record.LoadRequestedModules(state).
|
// 5. Let loadingPromise be record.LoadRequestedModules(state).
|
||||||
auto& loading_promise = record->load_requested_modules(state);
|
auto& loading_promise = record->load_requested_modules(state);
|
||||||
|
|
||||||
// 6. Upon fulfillment of loadingPromise, run the following steps:
|
WebIDL::react_to_promise(loading_promise,
|
||||||
WebIDL::upon_fulfillment(loading_promise, GC::create_function(realm.heap(), [&realm, record, &module_script, on_complete](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
// 6. Upon fulfillment of loadingPromise, run the following steps:
|
||||||
// 1. Perform record.Link().
|
GC::create_function(realm.heap(), [&realm, record, &module_script, on_complete](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
auto linking_result = record->link(realm.vm());
|
// 1. Perform record.Link().
|
||||||
|
auto linking_result = record->link(realm.vm());
|
||||||
|
|
||||||
// If this throws an exception, set result's error to rethrow to that exception.
|
// If this throws an exception, set result's error to rethrow to that exception.
|
||||||
if (linking_result.is_throw_completion())
|
if (linking_result.is_throw_completion())
|
||||||
module_script.set_error_to_rethrow(linking_result.release_error().value());
|
module_script.set_error_to_rethrow(linking_result.release_error().value());
|
||||||
|
|
||||||
// 2. Run onComplete given moduleScript.
|
|
||||||
on_complete->function()(module_script);
|
|
||||||
|
|
||||||
return JS::js_undefined();
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 7. Upon rejection of loadingPromise, run the following steps:
|
|
||||||
WebIDL::upon_rejection(loading_promise, GC::create_function(realm.heap(), [state, &module_script, on_complete](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
|
||||||
// 1. If state.[[ParseError]] is not null, set moduleScript's error to rethrow to state.[[ParseError]] and run
|
|
||||||
// onComplete given moduleScript.
|
|
||||||
if (!state->parse_error.is_null()) {
|
|
||||||
module_script.set_error_to_rethrow(state->parse_error);
|
|
||||||
|
|
||||||
|
// 2. Run onComplete given moduleScript.
|
||||||
on_complete->function()(module_script);
|
on_complete->function()(module_script);
|
||||||
}
|
|
||||||
// 2. Otherwise, run onComplete given null.
|
|
||||||
else {
|
|
||||||
on_complete->function()(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}),
|
||||||
|
|
||||||
|
// 7. Upon rejection of loadingPromise, run the following steps:
|
||||||
|
GC::create_function(realm.heap(), [state, &module_script, on_complete](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
|
// 1. If state.[[ParseError]] is not null, set moduleScript's error to rethrow to state.[[ParseError]] and run
|
||||||
|
// onComplete given moduleScript.
|
||||||
|
if (!state->parse_error.is_null()) {
|
||||||
|
module_script.set_error_to_rethrow(state->parse_error);
|
||||||
|
|
||||||
|
on_complete->function()(module_script);
|
||||||
|
}
|
||||||
|
// 2. Otherwise, run onComplete given null.
|
||||||
|
else {
|
||||||
|
on_complete->function()(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return JS::js_undefined();
|
||||||
|
}));
|
||||||
|
|
||||||
clean_up_after_running_callback(realm);
|
clean_up_after_running_callback(realm);
|
||||||
|
|
||||||
|
|
|
@ -2199,30 +2199,31 @@ void readable_stream_default_controller_can_pull_if_needed(ReadableStreamDefault
|
||||||
// 6. Let pullPromise be the result of performing controller.[[pullAlgorithm]].
|
// 6. Let pullPromise be the result of performing controller.[[pullAlgorithm]].
|
||||||
auto pull_promise = controller.pull_algorithm()->function()();
|
auto pull_promise = controller.pull_algorithm()->function()();
|
||||||
|
|
||||||
// 7. Upon fulfillment of pullPromise,
|
WebIDL::react_to_promise(pull_promise,
|
||||||
WebIDL::upon_fulfillment(*pull_promise, GC::create_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
// 7. Upon fulfillment of pullPromise,
|
||||||
// 1. Set controller.[[pulling]] to false.
|
GC::create_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
controller.set_pulling(false);
|
// 1. Set controller.[[pulling]] to false.
|
||||||
|
controller.set_pulling(false);
|
||||||
|
|
||||||
// 2. If controller.[[pullAgain]] is true,
|
// 2. If controller.[[pullAgain]] is true,
|
||||||
if (controller.pull_again()) {
|
if (controller.pull_again()) {
|
||||||
// 1. Set controller.[[pullAgain]] to false.
|
// 1. Set controller.[[pullAgain]] to false.
|
||||||
controller.set_pull_again(false);
|
controller.set_pull_again(false);
|
||||||
|
|
||||||
// 2. Perform ! ReadableStreamDefaultControllerCallPullIfNeeded(controller).
|
// 2. Perform ! ReadableStreamDefaultControllerCallPullIfNeeded(controller).
|
||||||
readable_stream_default_controller_can_pull_if_needed(controller);
|
readable_stream_default_controller_can_pull_if_needed(controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}),
|
||||||
|
|
||||||
// 8. Upon rejection of pullPromise with reason e,
|
// 8. Upon rejection of pullPromise with reason e,
|
||||||
WebIDL::upon_rejection(*pull_promise, GC::create_function(controller.heap(), [&controller](JS::Value e) -> WebIDL::ExceptionOr<JS::Value> {
|
GC::create_function(controller.heap(), [&controller](JS::Value e) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
// 1. Perform ! ReadableStreamDefaultControllerError(controller, e).
|
// 1. Perform ! ReadableStreamDefaultControllerError(controller, e).
|
||||||
readable_stream_default_controller_error(controller, e);
|
readable_stream_default_controller_error(controller, e);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#readable-stream-default-controller-should-call-pull
|
// https://streams.spec.whatwg.org/#readable-stream-default-controller-should-call-pull
|
||||||
|
@ -2626,30 +2627,31 @@ WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller(ReadableStre
|
||||||
// 10. Let startPromise be a promise resolved with startResult.
|
// 10. Let startPromise be a promise resolved with startResult.
|
||||||
auto start_promise = WebIDL::create_resolved_promise(realm, start_result);
|
auto start_promise = WebIDL::create_resolved_promise(realm, start_result);
|
||||||
|
|
||||||
// 11. Upon fulfillment of startPromise,
|
WebIDL::react_to_promise(start_promise,
|
||||||
WebIDL::upon_fulfillment(start_promise, GC::create_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
// 11. Upon fulfillment of startPromise,
|
||||||
// 1. Set controller.[[started]] to true.
|
GC::create_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
controller.set_started(true);
|
// 1. Set controller.[[started]] to true.
|
||||||
|
controller.set_started(true);
|
||||||
|
|
||||||
// 2. Assert: controller.[[pulling]] is false.
|
// 2. Assert: controller.[[pulling]] is false.
|
||||||
VERIFY(!controller.pulling());
|
VERIFY(!controller.pulling());
|
||||||
|
|
||||||
// 3. Assert: controller.[[pullAgain]] is false.
|
// 3. Assert: controller.[[pullAgain]] is false.
|
||||||
VERIFY(!controller.pull_again());
|
VERIFY(!controller.pull_again());
|
||||||
|
|
||||||
// 4. Perform ! ReadableStreamDefaultControllerCallPullIfNeeded(controller).
|
// 4. Perform ! ReadableStreamDefaultControllerCallPullIfNeeded(controller).
|
||||||
readable_stream_default_controller_can_pull_if_needed(controller);
|
readable_stream_default_controller_can_pull_if_needed(controller);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}),
|
||||||
|
|
||||||
// 12. Upon rejection of startPromise with reason r,
|
// 12. Upon rejection of startPromise with reason r,
|
||||||
WebIDL::upon_rejection(start_promise, GC::create_function(controller.heap(), [&controller](JS::Value r) -> WebIDL::ExceptionOr<JS::Value> {
|
GC::create_function(controller.heap(), [&controller](JS::Value r) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
// 1. Perform ! ReadableStreamDefaultControllerError(controller, r).
|
// 1. Perform ! ReadableStreamDefaultControllerError(controller, r).
|
||||||
readable_stream_default_controller_error(controller, r);
|
readable_stream_default_controller_error(controller, r);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -2735,30 +2737,31 @@ void readable_byte_stream_controller_call_pull_if_needed(ReadableByteStreamContr
|
||||||
// 6. Let pullPromise be the result of performing controller.[[pullAlgorithm]].
|
// 6. Let pullPromise be the result of performing controller.[[pullAlgorithm]].
|
||||||
auto pull_promise = controller.pull_algorithm()->function()();
|
auto pull_promise = controller.pull_algorithm()->function()();
|
||||||
|
|
||||||
// 7. Upon fulfillment of pullPromise,
|
WebIDL::react_to_promise(pull_promise,
|
||||||
WebIDL::upon_fulfillment(*pull_promise, GC::create_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
// 7. Upon fulfillment of pullPromise,
|
||||||
// 1. Set controller.[[pulling]] to false.
|
GC::create_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
controller.set_pulling(false);
|
// 1. Set controller.[[pulling]] to false.
|
||||||
|
controller.set_pulling(false);
|
||||||
|
|
||||||
// 2. If controller.[[pullAgain]] is true,
|
// 2. If controller.[[pullAgain]] is true,
|
||||||
if (controller.pull_again()) {
|
if (controller.pull_again()) {
|
||||||
// 1. Set controller.[[pullAgain]] to false.
|
// 1. Set controller.[[pullAgain]] to false.
|
||||||
controller.set_pull_again(false);
|
controller.set_pull_again(false);
|
||||||
|
|
||||||
// 2. Perform ! ReadableByteStreamControllerCallPullIfNeeded(controller).
|
// 2. Perform ! ReadableByteStreamControllerCallPullIfNeeded(controller).
|
||||||
readable_byte_stream_controller_call_pull_if_needed(controller);
|
readable_byte_stream_controller_call_pull_if_needed(controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}),
|
||||||
|
|
||||||
// 8. Upon rejection of pullPromise with reason e,
|
// 8. Upon rejection of pullPromise with reason e,
|
||||||
WebIDL::upon_rejection(*pull_promise, GC::create_function(controller.heap(), [&controller](JS::Value error) -> WebIDL::ExceptionOr<JS::Value> {
|
GC::create_function(controller.heap(), [&controller](JS::Value error) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
// 1. Perform ! ReadableByteStreamControllerError(controller, e).
|
// 1. Perform ! ReadableByteStreamControllerError(controller, e).
|
||||||
readable_byte_stream_controller_error(controller, error);
|
readable_byte_stream_controller_error(controller, error);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#readable-byte-stream-controller-clear-algorithms
|
// https://streams.spec.whatwg.org/#readable-byte-stream-controller-clear-algorithms
|
||||||
|
@ -3242,30 +3245,31 @@ WebIDL::ExceptionOr<void> set_up_readable_byte_stream_controller(ReadableStream&
|
||||||
// 15. Let startPromise be a promise resolved with startResult.
|
// 15. Let startPromise be a promise resolved with startResult.
|
||||||
auto start_promise = WebIDL::create_resolved_promise(realm, start_result);
|
auto start_promise = WebIDL::create_resolved_promise(realm, start_result);
|
||||||
|
|
||||||
// 16. Upon fulfillment of startPromise,
|
WebIDL::react_to_promise(start_promise,
|
||||||
WebIDL::upon_fulfillment(start_promise, GC::create_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
// 16. Upon fulfillment of startPromise,
|
||||||
// 1. Set controller.[[started]] to true.
|
GC::create_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
controller.set_started(true);
|
// 1. Set controller.[[started]] to true.
|
||||||
|
controller.set_started(true);
|
||||||
|
|
||||||
// 2. Assert: controller.[[pulling]] is false.
|
// 2. Assert: controller.[[pulling]] is false.
|
||||||
VERIFY(!controller.pulling());
|
VERIFY(!controller.pulling());
|
||||||
|
|
||||||
// 3. Assert: controller.[[pullAgain]] is false.
|
// 3. Assert: controller.[[pullAgain]] is false.
|
||||||
VERIFY(!controller.pull_again());
|
VERIFY(!controller.pull_again());
|
||||||
|
|
||||||
// 4. Perform ! ReadableByteStreamControllerCallPullIfNeeded(controller).
|
// 4. Perform ! ReadableByteStreamControllerCallPullIfNeeded(controller).
|
||||||
readable_byte_stream_controller_call_pull_if_needed(controller);
|
readable_byte_stream_controller_call_pull_if_needed(controller);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}),
|
||||||
|
|
||||||
// 17. Upon rejection of startPromise with reason r,
|
// 17. Upon rejection of startPromise with reason r,
|
||||||
WebIDL::upon_rejection(start_promise, GC::create_function(controller.heap(), [&controller](JS::Value r) -> WebIDL::ExceptionOr<JS::Value> {
|
GC::create_function(controller.heap(), [&controller](JS::Value r) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
// 1. Perform ! ReadableByteStreamControllerError(controller, r).
|
// 1. Perform ! ReadableByteStreamControllerError(controller, r).
|
||||||
readable_byte_stream_controller_error(controller, r);
|
readable_byte_stream_controller_error(controller, r);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -3782,27 +3786,28 @@ void writable_stream_finish_erroring(WritableStream& stream)
|
||||||
// 12. Let promise be ! stream.[[controller]].[[AbortSteps]](abortRequest’s reason).
|
// 12. Let promise be ! stream.[[controller]].[[AbortSteps]](abortRequest’s reason).
|
||||||
auto promise = stream.controller()->abort_steps(abort_request.reason);
|
auto promise = stream.controller()->abort_steps(abort_request.reason);
|
||||||
|
|
||||||
// 13. Upon fulfillment of promise,
|
WebIDL::react_to_promise(promise,
|
||||||
WebIDL::upon_fulfillment(*promise, GC::create_function(realm.heap(), [&realm, &stream, abort_promise = abort_request.promise](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
// 13. Upon fulfillment of promise,
|
||||||
// 1. Resolve abortRequest’s promise with undefined.
|
GC::create_function(realm.heap(), [&realm, &stream, abort_promise = abort_request.promise](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
WebIDL::resolve_promise(realm, abort_promise, JS::js_undefined());
|
// 1. Resolve abortRequest’s promise with undefined.
|
||||||
|
WebIDL::resolve_promise(realm, abort_promise, JS::js_undefined());
|
||||||
|
|
||||||
// 2. Perform ! WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream).
|
// 2. Perform ! WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream).
|
||||||
writable_stream_reject_close_and_closed_promise_if_needed(stream);
|
writable_stream_reject_close_and_closed_promise_if_needed(stream);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}),
|
||||||
|
|
||||||
// 14. Upon rejection of promise with reason reason,
|
// 14. Upon rejection of promise with reason reason,
|
||||||
WebIDL::upon_rejection(*promise, GC::create_function(realm.heap(), [&realm, &stream, abort_promise = abort_request.promise](JS::Value reason) -> WebIDL::ExceptionOr<JS::Value> {
|
GC::create_function(realm.heap(), [&realm, &stream, abort_promise = abort_request.promise](JS::Value reason) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
// 1. Reject abortRequest’s promise with reason.
|
// 1. Reject abortRequest’s promise with reason.
|
||||||
WebIDL::reject_promise(realm, abort_promise, reason);
|
WebIDL::reject_promise(realm, abort_promise, reason);
|
||||||
|
|
||||||
// 2. Perform ! WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream).
|
// 2. Perform ! WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream).
|
||||||
writable_stream_reject_close_and_closed_promise_if_needed(stream);
|
writable_stream_reject_close_and_closed_promise_if_needed(stream);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#writable-stream-finish-in-flight-close
|
// https://streams.spec.whatwg.org/#writable-stream-finish-in-flight-close
|
||||||
|
@ -4313,35 +4318,36 @@ WebIDL::ExceptionOr<void> set_up_writable_stream_default_controller(WritableStre
|
||||||
// 16. Let startPromise be a promise resolved with startResult.
|
// 16. Let startPromise be a promise resolved with startResult.
|
||||||
auto start_promise = WebIDL::create_resolved_promise(realm, start_result);
|
auto start_promise = WebIDL::create_resolved_promise(realm, start_result);
|
||||||
|
|
||||||
// 17. Upon fulfillment of startPromise,
|
WebIDL::react_to_promise(start_promise,
|
||||||
WebIDL::upon_fulfillment(*start_promise, GC::create_function(realm.heap(), [&controller, &stream](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
// 17. Upon fulfillment of startPromise,
|
||||||
// 1. Assert: stream.[[state]] is "writable" or "erroring".
|
GC::create_function(realm.heap(), [&controller, &stream](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
auto state = stream.state();
|
// 1. Assert: stream.[[state]] is "writable" or "erroring".
|
||||||
VERIFY(state == WritableStream::State::Writable || state == WritableStream::State::Erroring);
|
auto state = stream.state();
|
||||||
|
VERIFY(state == WritableStream::State::Writable || state == WritableStream::State::Erroring);
|
||||||
|
|
||||||
// 2. Set controller.[[started]] to true.
|
// 2. Set controller.[[started]] to true.
|
||||||
controller.set_started(true);
|
controller.set_started(true);
|
||||||
|
|
||||||
// 3. Perform ! WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller).
|
// 3. Perform ! WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller).
|
||||||
writable_stream_default_controller_advance_queue_if_needed(controller);
|
writable_stream_default_controller_advance_queue_if_needed(controller);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}),
|
||||||
|
|
||||||
// 18. Upon rejection of startPromise with reason r,
|
// 18. Upon rejection of startPromise with reason r,
|
||||||
WebIDL::upon_rejection(*start_promise, GC::create_function(realm.heap(), [&stream, &controller](JS::Value reason) -> WebIDL::ExceptionOr<JS::Value> {
|
GC::create_function(realm.heap(), [&stream, &controller](JS::Value reason) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
// 1. Assert: stream.[[state]] is "writable" or "erroring".
|
// 1. Assert: stream.[[state]] is "writable" or "erroring".
|
||||||
auto state = stream.state();
|
auto state = stream.state();
|
||||||
VERIFY(state == WritableStream::State::Writable || state == WritableStream::State::Erroring);
|
VERIFY(state == WritableStream::State::Writable || state == WritableStream::State::Erroring);
|
||||||
|
|
||||||
// 2. Set controller.[[started]] to true.
|
// 2. Set controller.[[started]] to true.
|
||||||
controller.set_started(true);
|
controller.set_started(true);
|
||||||
|
|
||||||
// 3. Perform ! WritableStreamDealWithRejection(stream, r).
|
// 3. Perform ! WritableStreamDealWithRejection(stream, r).
|
||||||
writable_stream_deal_with_rejection(stream, reason);
|
writable_stream_deal_with_rejection(stream, reason);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -4575,21 +4581,22 @@ void writable_stream_default_controller_process_close(WritableStreamDefaultContr
|
||||||
// 6. Perform ! WritableStreamDefaultControllerClearAlgorithms(controller).
|
// 6. Perform ! WritableStreamDefaultControllerClearAlgorithms(controller).
|
||||||
writable_stream_default_controller_clear_algorithms(controller);
|
writable_stream_default_controller_clear_algorithms(controller);
|
||||||
|
|
||||||
// 7. Upon fulfillment of sinkClosePromise,
|
WebIDL::react_to_promise(sink_close_promise,
|
||||||
WebIDL::upon_fulfillment(*sink_close_promise, GC::create_function(controller.heap(), [stream](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
// 7. Upon fulfillment of sinkClosePromise,
|
||||||
// 1. Perform ! WritableStreamFinishInFlightClose(stream).
|
GC::create_function(controller.heap(), [stream](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
writable_stream_finish_in_flight_close(*stream);
|
// 1. Perform ! WritableStreamFinishInFlightClose(stream).
|
||||||
|
writable_stream_finish_in_flight_close(*stream);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}),
|
||||||
|
|
||||||
// 8. Upon rejection of sinkClosePromise with reason reason,
|
// 8. Upon rejection of sinkClosePromise with reason reason,
|
||||||
WebIDL::upon_rejection(*sink_close_promise, GC::create_function(controller.heap(), [stream = stream](JS::Value reason) -> WebIDL::ExceptionOr<JS::Value> {
|
GC::create_function(controller.heap(), [stream = stream](JS::Value reason) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
// 1. Perform ! WritableStreamFinishInFlightCloseWithError(stream, reason).
|
// 1. Perform ! WritableStreamFinishInFlightCloseWithError(stream, reason).
|
||||||
writable_stream_finish_in_flight_close_with_error(*stream, reason);
|
writable_stream_finish_in_flight_close_with_error(*stream, reason);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#writable-stream-default-controller-process-write
|
// https://streams.spec.whatwg.org/#writable-stream-default-controller-process-write
|
||||||
|
@ -4604,46 +4611,47 @@ void writable_stream_default_controller_process_write(WritableStreamDefaultContr
|
||||||
// 3. Let sinkWritePromise be the result of performing controller.[[writeAlgorithm]], passing in chunk.
|
// 3. Let sinkWritePromise be the result of performing controller.[[writeAlgorithm]], passing in chunk.
|
||||||
auto sink_write_promise = controller.write_algorithm()->function()(chunk);
|
auto sink_write_promise = controller.write_algorithm()->function()(chunk);
|
||||||
|
|
||||||
// 4. Upon fulfillment of sinkWritePromise,
|
WebIDL::react_to_promise(sink_write_promise,
|
||||||
WebIDL::upon_fulfillment(*sink_write_promise, GC::create_function(controller.heap(), [&controller, stream](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
// 4. Upon fulfillment of sinkWritePromise,
|
||||||
// 1. Perform ! WritableStreamFinishInFlightWrite(stream).
|
GC::create_function(controller.heap(), [&controller, stream](JS::Value) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
writable_stream_finish_in_flight_write(*stream);
|
// 1. Perform ! WritableStreamFinishInFlightWrite(stream).
|
||||||
|
writable_stream_finish_in_flight_write(*stream);
|
||||||
|
|
||||||
// 2. Let state be stream.[[state]].
|
// 2. Let state be stream.[[state]].
|
||||||
auto state = stream->state();
|
auto state = stream->state();
|
||||||
|
|
||||||
// 3. Assert: state is "writable" or "erroring".
|
// 3. Assert: state is "writable" or "erroring".
|
||||||
VERIFY(state == WritableStream::State::Writable || state == WritableStream::State::Erroring);
|
VERIFY(state == WritableStream::State::Writable || state == WritableStream::State::Erroring);
|
||||||
|
|
||||||
// 4. Perform ! DequeueValue(controller).
|
// 4. Perform ! DequeueValue(controller).
|
||||||
dequeue_value(controller);
|
dequeue_value(controller);
|
||||||
|
|
||||||
// 5. If ! WritableStreamCloseQueuedOrInFlight(stream) is false and state is "writable",
|
// 5. If ! WritableStreamCloseQueuedOrInFlight(stream) is false and state is "writable",
|
||||||
if (!writable_stream_close_queued_or_in_flight(*stream) && state == WritableStream::State::Writable) {
|
if (!writable_stream_close_queued_or_in_flight(*stream) && state == WritableStream::State::Writable) {
|
||||||
// 1. Let backpressure be ! WritableStreamDefaultControllerGetBackpressure(controller).
|
// 1. Let backpressure be ! WritableStreamDefaultControllerGetBackpressure(controller).
|
||||||
auto backpressure = writable_stream_default_controller_get_backpressure(controller);
|
auto backpressure = writable_stream_default_controller_get_backpressure(controller);
|
||||||
|
|
||||||
// 2. Perform ! WritableStreamUpdateBackpressure(stream, backpressure).
|
// 2. Perform ! WritableStreamUpdateBackpressure(stream, backpressure).
|
||||||
writable_stream_update_backpressure(*stream, backpressure);
|
writable_stream_update_backpressure(*stream, backpressure);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6 .Perform ! WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller).
|
// 6 .Perform ! WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller).
|
||||||
writable_stream_default_controller_advance_queue_if_needed(controller);
|
writable_stream_default_controller_advance_queue_if_needed(controller);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}),
|
||||||
|
|
||||||
// 5. Upon rejection of sinkWritePromise with reason,
|
// 5. Upon rejection of sinkWritePromise with reason,
|
||||||
WebIDL::upon_rejection(*sink_write_promise, GC::create_function(controller.heap(), [&controller, stream](JS::Value reason) -> WebIDL::ExceptionOr<JS::Value> {
|
GC::create_function(controller.heap(), [&controller, stream](JS::Value reason) -> WebIDL::ExceptionOr<JS::Value> {
|
||||||
// 1. If stream.[[state]] is "writable", perform ! WritableStreamDefaultControllerClearAlgorithms(controller).
|
// 1. If stream.[[state]] is "writable", perform ! WritableStreamDefaultControllerClearAlgorithms(controller).
|
||||||
if (stream->state() == WritableStream::State::Writable)
|
if (stream->state() == WritableStream::State::Writable)
|
||||||
writable_stream_default_controller_clear_algorithms(controller);
|
writable_stream_default_controller_clear_algorithms(controller);
|
||||||
|
|
||||||
// 2. Perform ! WritableStreamFinishInFlightWriteWithError(stream, reason).
|
// 2. Perform ! WritableStreamFinishInFlightWriteWithError(stream, reason).
|
||||||
writable_stream_finish_in_flight_write_with_error(*stream, reason);
|
writable_stream_finish_in_flight_write_with_error(*stream, reason);
|
||||||
|
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#writable-stream-default-controller-write
|
// https://streams.spec.whatwg.org/#writable-stream-default-controller-write
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue