diff --git a/Userland/Libraries/LibWeb/FileAPI/Blob.cpp b/Userland/Libraries/LibWeb/FileAPI/Blob.cpp index fadcedadff..8943955be2 100644 --- a/Userland/Libraries/LibWeb/FileAPI/Blob.cpp +++ b/Userland/Libraries/LibWeb/FileAPI/Blob.cpp @@ -375,7 +375,7 @@ WebIDL::ExceptionOr> Blob::text() auto promise = TRY(reader->read_all_bytes_deprecated()); // 4. Return the result of transforming promise by a fulfillment handler that returns the result of running UTF-8 decode on its first argument. - return WebIDL::upon_fulfillment(*promise, [&](auto const& first_argument) -> WebIDL::ExceptionOr { + return WebIDL::upon_fulfillment(*promise, JS::create_heap_function(heap(), [&vm](JS::Value first_argument) -> WebIDL::ExceptionOr { auto const& object = first_argument.as_object(); VERIFY(is(object)); auto const& buffer = static_cast(object).buffer(); @@ -383,7 +383,7 @@ WebIDL::ExceptionOr> Blob::text() auto decoder = TextCodec::decoder_for("UTF-8"sv); auto utf8_text = TRY_OR_THROW_OOM(vm, TextCodec::convert_input_to_utf8_using_given_decoder_unless_there_is_a_byte_order_mark(*decoder, buffer)); return JS::PrimitiveString::create(vm, move(utf8_text)); - }); + })); } // https://w3c.github.io/FileAPI/#dom-blob-arraybuffer @@ -404,13 +404,13 @@ WebIDL::ExceptionOr> Blob::array_buffer() auto promise = TRY(reader->read_all_bytes_deprecated()); // 4. Return the result of transforming promise by a fulfillment handler that returns a new ArrayBuffer whose contents are its first argument. - return WebIDL::upon_fulfillment(*promise, [&](auto const& first_argument) -> WebIDL::ExceptionOr { + return WebIDL::upon_fulfillment(*promise, JS::create_heap_function(heap(), [&realm](JS::Value first_argument) -> WebIDL::ExceptionOr { auto const& object = first_argument.as_object(); VERIFY(is(object)); auto const& buffer = static_cast(object).buffer(); return JS::ArrayBuffer::create(realm, buffer); - }); + })); } } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp index 94d680a217..7b4433096f 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp @@ -828,7 +828,7 @@ void fetch_descendants_of_and_link_a_module_script(JS::Realm& realm, auto& loading_promise = record->load_requested_modules(state); // 6. Upon fulfillment of loadingPromise, run the following steps: - WebIDL::upon_fulfillment(loading_promise, [&realm, record, &module_script, on_complete](auto const&) -> WebIDL::ExceptionOr { + WebIDL::upon_fulfillment(loading_promise, JS::create_heap_function(realm.heap(), [&realm, record, &module_script, on_complete](JS::Value) -> WebIDL::ExceptionOr { // 1. Perform record.Link(). auto linking_result = record->link(realm.vm()); @@ -840,10 +840,10 @@ void fetch_descendants_of_and_link_a_module_script(JS::Realm& realm, on_complete->function()(module_script); return JS::js_undefined(); - }); + })); // 7. Upon rejection of loadingPromise, run the following steps: - WebIDL::upon_rejection(loading_promise, [state, &module_script, on_complete](auto const&) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(loading_promise, JS::create_heap_function(realm.heap(), [state, &module_script, on_complete](JS::Value) -> WebIDL::ExceptionOr { // 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()) { @@ -857,7 +857,7 @@ void fetch_descendants_of_and_link_a_module_script(JS::Realm& realm, } return JS::js_undefined(); - }); + })); fetch_client.clean_up_after_running_callback(); realm.vm().pop_execution_context(); diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp index 4e05a8cb7e..2f500322d2 100644 --- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -127,7 +127,7 @@ WebIDL::ExceptionOr> readable_stream_cancel(Re // 8. Return the result of reacting to sourceCancelPromise with a fulfillment step that returns undefined. auto react_result = WebIDL::react_to_promise(*source_cancel_promise, - [](auto const&) -> WebIDL::ExceptionOr { return JS::js_undefined(); }, + JS::create_heap_function(stream.heap(), [](JS::Value) -> WebIDL::ExceptionOr { return JS::js_undefined(); }), {}); return WebIDL::create_resolved_promise(realm, react_result); @@ -535,7 +535,7 @@ WebIDL::ExceptionOr readable_stream_default_tee(JS::Realm& r params->branch2 = MUST(create_readable_stream(realm, start_algorithm, pull_algorithm, cancel2_algorithm)); // 19. Upon rejection of reader.[[closedPromise]] with reason r, - WebIDL::upon_rejection(*reader->closed_promise_capability(), [&realm, params, cancel_promise](auto reason) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(*reader->closed_promise_capability(), JS::create_heap_function(realm.heap(), [&realm, params, cancel_promise](JS::Value reason) -> WebIDL::ExceptionOr { auto controller1 = params->branch1->controller()->get>(); auto controller2 = params->branch2->controller()->get>(); @@ -551,7 +551,7 @@ WebIDL::ExceptionOr readable_stream_default_tee(JS::Realm& r } return JS::js_undefined(); - }); + })); // 20. Return « branch1, branch2 ». return ReadableStreamPair { *params->branch1, *params->branch2 }; @@ -964,7 +964,7 @@ WebIDL::ExceptionOr readable_byte_stream_tee(JS::Realm& real // 1. Upon rejection of thisReader.[[closedPromise]] with reason r, auto closed_promise = this_reader.visit([](auto const& underlying_reader) { return underlying_reader->closed_promise_capability(); }); - WebIDL::upon_rejection(*closed_promise, [&realm, this_reader, params, cancel_promise](auto reason) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(*closed_promise, JS::create_heap_function(realm.heap(), [&realm, this_reader, params, cancel_promise](JS::Value reason) -> WebIDL::ExceptionOr { auto controller1 = params->branch1->controller()->get>(); auto controller2 = params->branch2->controller()->get>(); @@ -985,7 +985,7 @@ WebIDL::ExceptionOr readable_byte_stream_tee(JS::Realm& real } return JS::js_undefined(); - }); + })); }); // 15. Let pullWithDefaultReader be the following steps: @@ -1938,7 +1938,7 @@ WebIDL::ExceptionOr readable_stream_default_controller_can_pull_if_needed( auto pull_promise = TRY(controller.pull_algorithm()->function()()); // 7. Upon fulfillment of pullPromise, - WebIDL::upon_fulfillment(*pull_promise, [&](auto const&) -> WebIDL::ExceptionOr { + WebIDL::upon_fulfillment(*pull_promise, JS::create_heap_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr { // 1. Set controller.[[pulling]] to false. controller.set_pulling(false); @@ -1952,15 +1952,15 @@ WebIDL::ExceptionOr readable_stream_default_controller_can_pull_if_needed( } return JS::js_undefined(); - }); + })); // 8. Upon rejection of pullPromise with reason e, - WebIDL::upon_rejection(*pull_promise, [&](auto const& e) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(*pull_promise, JS::create_heap_function(controller.heap(), [&controller](JS::Value e) -> WebIDL::ExceptionOr { // 1. Perform ! ReadableStreamDefaultControllerError(controller, e). readable_stream_default_controller_error(controller, e); return JS::js_undefined(); - }); + })); return {}; } @@ -2345,7 +2345,7 @@ WebIDL::ExceptionOr set_up_readable_stream_default_controller(ReadableStre auto start_promise = WebIDL::create_resolved_promise(realm, start_result); // 11. Upon fulfillment of startPromise, - WebIDL::upon_fulfillment(start_promise, [&](auto const&) -> WebIDL::ExceptionOr { + WebIDL::upon_fulfillment(start_promise, JS::create_heap_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr { // 1. Set controller.[[started]] to true. controller.set_started(true); @@ -2359,15 +2359,15 @@ WebIDL::ExceptionOr set_up_readable_stream_default_controller(ReadableStre TRY(readable_stream_default_controller_can_pull_if_needed(controller)); return JS::js_undefined(); - }); + })); // 12. Upon rejection of startPromise with reason r, - WebIDL::upon_rejection(start_promise, [&](auto const& r) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(start_promise, JS::create_heap_function(controller.heap(), [&controller](JS::Value r) -> WebIDL::ExceptionOr { // 1. Perform ! ReadableStreamDefaultControllerError(controller, r). readable_stream_default_controller_error(controller, r); return JS::js_undefined(); - }); + })); return {}; } @@ -2454,7 +2454,7 @@ WebIDL::ExceptionOr readable_byte_stream_controller_call_pull_if_needed(Re auto pull_promise = TRY(controller.pull_algorithm()->function()()); // 7. Upon fulfillment of pullPromise, - WebIDL::upon_fulfillment(*pull_promise, [&](auto const&) -> WebIDL::ExceptionOr { + WebIDL::upon_fulfillment(*pull_promise, JS::create_heap_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr { // 1. Set controller.[[pulling]] to false. controller.set_pulling(false); @@ -2468,15 +2468,15 @@ WebIDL::ExceptionOr readable_byte_stream_controller_call_pull_if_needed(Re } return JS::js_undefined(); - }); + })); // 8. Upon rejection of pullPromise with reason e, - WebIDL::upon_rejection(*pull_promise, [&](auto const& error) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(*pull_promise, JS::create_heap_function(controller.heap(), [&controller](JS::Value error) -> WebIDL::ExceptionOr { // 1. Perform ! ReadableByteStreamControllerError(controller, e). readable_byte_stream_controller_error(controller, error); return JS::js_undefined(); - }); + })); return {}; } @@ -2967,7 +2967,7 @@ WebIDL::ExceptionOr set_up_readable_byte_stream_controller(ReadableStream& auto start_promise = WebIDL::create_resolved_promise(realm, start_result); // 16. Upon fulfillment of startPromise, - WebIDL::upon_fulfillment(start_promise, [&](auto const&) -> WebIDL::ExceptionOr { + WebIDL::upon_fulfillment(start_promise, JS::create_heap_function(controller.heap(), [&controller](JS::Value) -> WebIDL::ExceptionOr { // 1. Set controller.[[started]] to true. controller.set_started(true); @@ -2981,15 +2981,15 @@ WebIDL::ExceptionOr set_up_readable_byte_stream_controller(ReadableStream& TRY(readable_byte_stream_controller_call_pull_if_needed(controller)); return JS::js_undefined(); - }); + })); // 17. Upon rejection of startPromise with reason r, - WebIDL::upon_rejection(start_promise, [&](auto const& r) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(start_promise, JS::create_heap_function(controller.heap(), [&controller](JS::Value r) -> WebIDL::ExceptionOr { // 1. Perform ! ReadableByteStreamControllerError(controller, r). readable_byte_stream_controller_error(controller, r); return JS::js_undefined(); - }); + })); return {}; } @@ -3577,7 +3577,7 @@ WebIDL::ExceptionOr writable_stream_finish_erroring(WritableStream& stream auto promise = TRY(stream.controller()->abort_steps(abort_request.reason)); // 13. Upon fulfillment of promise, - WebIDL::upon_fulfillment(*promise, [&, abort_promise = abort_request.promise](auto const&) -> WebIDL::ExceptionOr { + WebIDL::upon_fulfillment(*promise, JS::create_heap_function(realm.heap(), [&realm, &stream, abort_promise = abort_request.promise](JS::Value) -> WebIDL::ExceptionOr { // 1. Resolve abortRequest’s promise with undefined. WebIDL::resolve_promise(realm, abort_promise, JS::js_undefined()); @@ -3585,10 +3585,10 @@ WebIDL::ExceptionOr writable_stream_finish_erroring(WritableStream& stream writable_stream_reject_close_and_closed_promise_if_needed(stream); return JS::js_undefined(); - }); + })); // 14. Upon rejection of promise with reason reason, - WebIDL::upon_rejection(*promise, [&, abort_promise = abort_request.promise](auto const& reason) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(*promise, JS::create_heap_function(realm.heap(), [&realm, &stream, abort_promise = abort_request.promise](JS::Value reason) -> WebIDL::ExceptionOr { // 1. Reject abortRequest’s promise with reason. WebIDL::reject_promise(realm, abort_promise, reason); @@ -3596,7 +3596,7 @@ WebIDL::ExceptionOr writable_stream_finish_erroring(WritableStream& stream writable_stream_reject_close_and_closed_promise_if_needed(stream); return JS::js_undefined(); - }); + })); return {}; } @@ -4085,7 +4085,7 @@ WebIDL::ExceptionOr set_up_writable_stream_default_controller(WritableStre auto start_promise = WebIDL::create_resolved_promise(realm, start_result); // 17. Upon fulfillment of startPromise, - WebIDL::upon_fulfillment(*start_promise, [&](auto const&) -> WebIDL::ExceptionOr { + WebIDL::upon_fulfillment(*start_promise, JS::create_heap_function(realm.heap(), [&controller, &stream](JS::Value) -> WebIDL::ExceptionOr { // 1. Assert: stream.[[state]] is "writable" or "erroring". auto state = stream.state(); VERIFY(state == WritableStream::State::Writable || state == WritableStream::State::Erroring); @@ -4097,10 +4097,10 @@ WebIDL::ExceptionOr set_up_writable_stream_default_controller(WritableStre TRY(writable_stream_default_controller_advance_queue_if_needed(controller)); return JS::js_undefined(); - }); + })); // 18. Upon rejection of startPromise with reason r, - WebIDL::upon_rejection(*start_promise, [&](JS::Value reason) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(*start_promise, JS::create_heap_function(realm.heap(), [&stream, &controller](JS::Value reason) -> WebIDL::ExceptionOr { // 1. Assert: stream.[[state]] is "writable" or "erroring". auto state = stream.state(); VERIFY(state == WritableStream::State::Writable || state == WritableStream::State::Erroring); @@ -4112,7 +4112,7 @@ WebIDL::ExceptionOr set_up_writable_stream_default_controller(WritableStre TRY(writable_stream_deal_with_rejection(stream, reason)); return JS::js_undefined(); - }); + })); return {}; } @@ -4342,20 +4342,20 @@ WebIDL::ExceptionOr writable_stream_default_controller_process_close(Writa writable_stream_default_controller_clear_algorithms(controller); // 7. Upon fulfillment of sinkClosePromise, - WebIDL::upon_fulfillment(*sink_close_promise, [&, stream = stream](auto const&) -> WebIDL::ExceptionOr { + WebIDL::upon_fulfillment(*sink_close_promise, JS::create_heap_function(controller.heap(), [stream](JS::Value) -> WebIDL::ExceptionOr { // 1. Perform ! WritableStreamFinishInFlightClose(stream). writable_stream_finish_in_flight_close(*stream); return JS::js_undefined(); - }); + })); // 8. Upon rejection of sinkClosePromise with reason reason, - WebIDL::upon_rejection(*sink_close_promise, [&, stream = stream](auto const& reason) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(*sink_close_promise, JS::create_heap_function(controller.heap(), [stream = stream](JS::Value reason) -> WebIDL::ExceptionOr { // 1. Perform ! WritableStreamFinishInFlightCloseWithError(stream, reason). TRY(writable_stream_finish_in_flight_close_with_error(*stream, reason)); return JS::js_undefined(); - }); + })); return {}; } @@ -4373,7 +4373,7 @@ WebIDL::ExceptionOr writable_stream_default_controller_process_write(Writa auto sink_write_promise = TRY(controller.write_algorithm()->function()(chunk)); // 4. Upon fulfillment of sinkWritePromise, - WebIDL::upon_fulfillment(*sink_write_promise, [&, stream = stream](auto const&) -> WebIDL::ExceptionOr { + WebIDL::upon_fulfillment(*sink_write_promise, JS::create_heap_function(controller.heap(), [&controller, stream](JS::Value) -> WebIDL::ExceptionOr { // 1. Perform ! WritableStreamFinishInFlightWrite(stream). writable_stream_finish_in_flight_write(*stream); @@ -4399,10 +4399,10 @@ WebIDL::ExceptionOr writable_stream_default_controller_process_write(Writa TRY(writable_stream_default_controller_advance_queue_if_needed(controller)); return JS::js_undefined(); - }); + })); // 5. Upon rejection of sinkWritePromise with reason, - WebIDL::upon_rejection(*sink_write_promise, [&, stream = stream](auto const& reason) -> WebIDL::ExceptionOr { + WebIDL::upon_rejection(*sink_write_promise, JS::create_heap_function(controller.heap(), [&controller, stream](JS::Value reason) -> WebIDL::ExceptionOr { // 1. If stream.[[state]] is "writable", perform ! WritableStreamDefaultControllerClearAlgorithms(controller). if (stream->state() == WritableStream::State::Writable) writable_stream_default_controller_clear_algorithms(controller); @@ -4411,7 +4411,7 @@ WebIDL::ExceptionOr writable_stream_default_controller_process_write(Writa TRY(writable_stream_finish_in_flight_write_with_error(*stream, reason)); return JS::js_undefined(); - }); + })); return {}; } @@ -4700,13 +4700,13 @@ WebIDL::ExceptionOr> transform_stream_default_ // 2. Return the result of reacting to transformPromise with the following rejection steps given the argument r: auto react_result = WebIDL::react_to_promise(*transform_promise, {}, - [&](auto const& reason) -> WebIDL::ExceptionOr { + JS::create_heap_function(realm.heap(), [&controller](JS::Value reason) -> WebIDL::ExceptionOr { // 1. Perform ! TransformStreamError(controller.[[stream]], r). TRY(transform_stream_error(*controller.stream(), reason)); // 2. Throw r. return JS::throw_completion(reason); - }); + })); return WebIDL::create_resolved_promise(realm, react_result); } @@ -4744,7 +4744,7 @@ WebIDL::ExceptionOr> transform_stream_default_ auto react_result = WebIDL::react_to_promise( *flush_promise, // 1. If flushPromise was fulfilled, then: - [readable](auto const&) -> WebIDL::ExceptionOr { + JS::create_heap_function(realm.heap(), [readable](JS::Value) -> WebIDL::ExceptionOr { // 1. If readable.[[state]] is "errored", throw readable.[[storedError]]. if (readable->state() == ReadableStream::State::Errored) return JS::throw_completion(readable->stored_error()); @@ -4754,15 +4754,15 @@ WebIDL::ExceptionOr> transform_stream_default_ readable_stream_default_controller_close(readable->controller().value().get>()); return JS::js_undefined(); - }, + }), // 2. If flushPromise was rejected with reason r, then: - [&stream, readable](auto const& reason) -> WebIDL::ExceptionOr { + JS::create_heap_function(realm.heap(), [&stream, readable](JS::Value reason) -> WebIDL::ExceptionOr { // 1. Perform ! TransformStreamError(stream, r). TRY(transform_stream_error(stream, reason)); // 2. Throw readable.[[storedError]]. return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, readable->stored_error().as_string().utf8_string() }; - }); + })); return WebIDL::create_resolved_promise(realm, react_result); } @@ -4788,7 +4788,7 @@ WebIDL::ExceptionOr> transform_stream_default_ // 3. Return the result of reacting to backpressureChangePromise with the following fulfillment steps: auto react_result = WebIDL::react_to_promise(*backpressure_change_promise, - [&stream, controller, chunk](auto const&) -> WebIDL::ExceptionOr { + JS::create_heap_function(realm.heap(), [&stream, controller, chunk](JS::Value) -> WebIDL::ExceptionOr { // 1. Let writable be stream.[[writable]]. auto writable = stream.writable(); @@ -4804,7 +4804,7 @@ WebIDL::ExceptionOr> transform_stream_default_ // 5. Return ! TransformStreamDefaultControllerPerformTransform(controller, chunk). return TRY(transform_stream_default_controller_perform_transform(*controller, chunk))->promise(); - }, + }), {}); return WebIDL::create_resolved_promise(realm, react_result); diff --git a/Userland/Libraries/LibWeb/WebIDL/Promise.cpp b/Userland/Libraries/LibWeb/WebIDL/Promise.cpp index d2e58a8128..3b7bda2e4c 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, Optional on_fulfilled_callback, Optional 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(); @@ -104,8 +104,8 @@ JS::NonnullGCPtr react_to_promise(Promise const& promise, Optional< auto value = vm.argument(0); // 2. If there is a set of steps to be run if the promise was fulfilled, then let result be the result of performing them, given value if T is not undefined. Otherwise, let result be value. - auto result = on_fulfilled_callback.has_value() - ? TRY(Bindings::throw_dom_exception_if_needed(vm, [&] { return (*on_fulfilled_callback)(value); })) + auto result = on_fulfilled_callback + ? TRY(Bindings::throw_dom_exception_if_needed(vm, [&] { return on_fulfilled_callback->function()(value); })) : value; // 3. Return result, converted to an ECMAScript value. @@ -121,8 +121,8 @@ JS::NonnullGCPtr react_to_promise(Promise const& promise, Optional< auto reason = vm.argument(0); // 2. If there is a set of steps to be run if the promise was rejected, then let result be the result of performing them, given reason. Otherwise, let result be a promise rejected with reason. - auto result = on_rejected_callback.has_value() - ? TRY(Bindings::throw_dom_exception_if_needed(vm, [&] { return (*on_rejected_callback)(reason); })) + auto result = on_rejected_callback + ? TRY(Bindings::throw_dom_exception_if_needed(vm, [&] { return on_rejected_callback->function()(reason); })) : WebIDL::create_rejected_promise(realm, reason)->promise(); // 3. Return result, converted to an ECMAScript value. @@ -146,32 +146,24 @@ JS::NonnullGCPtr react_to_promise(Promise const& promise, Optional< } // https://webidl.spec.whatwg.org/#upon-fulfillment -JS::NonnullGCPtr upon_fulfillment(Promise const& promise, ReactionSteps steps) +JS::NonnullGCPtr upon_fulfillment(Promise const& promise, JS::NonnullGCPtr steps) { // 1. Return the result of reacting to promise: return react_to_promise(promise, // - If promise was fulfilled with value v, then: - [steps = move(steps)](auto value) { - // 1. Perform steps with v. - // NOTE: The `return` is not immediately obvious, but `steps` may be something like - // "Return the result of ...", which we also need to do _here_. - return steps(value); - }, + // 1. Perform steps with v. + steps, {}); } // https://webidl.spec.whatwg.org/#upon-rejection -JS::NonnullGCPtr upon_rejection(Promise const& promise, ReactionSteps steps) +JS::NonnullGCPtr upon_rejection(Promise const& promise, JS::NonnullGCPtr steps) { // 1. Return the result of reacting to promise: return react_to_promise(promise, {}, // - If promise was rejected with reason r, then: - [steps = move(steps)](auto reason) { - // 1. Perform steps with r. - // NOTE: The `return` is not immediately obvious, but `steps` may be something like - // "Return the result of ...", which we also need to do _here_. - return steps(reason); - }); + // 1. Perform steps with r. + steps); } // https://webidl.spec.whatwg.org/#mark-a-promise-as-handled diff --git a/Userland/Libraries/LibWeb/WebIDL/Promise.h b/Userland/Libraries/LibWeb/WebIDL/Promise.h index d7a42c1215..a2d91c268a 100644 --- a/Userland/Libraries/LibWeb/WebIDL/Promise.h +++ b/Userland/Libraries/LibWeb/WebIDL/Promise.h @@ -17,7 +17,7 @@ namespace Web::WebIDL { // NOTE: This is Function, not SafeFunction, because they get stored in a NativeFunction anyway, which will protect captures. -using ReactionSteps = Function(JS::Value)>; +using ReactionSteps = JS::HeapFunction(JS::Value)>; // https://webidl.spec.whatwg.org/#es-promise using Promise = JS::PromiseCapability; @@ -27,9 +27,9 @@ 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&, Optional on_fulfilled_callback, Optional on_rejected_callback); -JS::NonnullGCPtr upon_fulfillment(Promise const&, ReactionSteps); -JS::NonnullGCPtr upon_rejection(Promise const&, ReactionSteps); +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);