1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 08:37:34 +00:00

LibJS+LibWeb: Apply the Rule of Zero to {Nonnull,}GCPtr<T>

The compiler-generated copy constructor and copy assignment operator
already do the right thing (which is to simply copy the underlying
pointer).

The [Itanium C++ ABI][1] treats any class with non-trivial copy/move
constructors and destructors as non-trivial for the purposes of calls --
even if they are functionally identical to the compiler-generated ones.
If a class is non-trivial, it cannot be passed or returned in registers,
only via an invisible reference, which is worse for codegen. This commit
makes `{Nonnull,}GCPtr` trivial.

As the compiler can be sure that capturing a `GCPtr` by value has no
side effects, a few `-Wunused-lambda-capture` warnings had to be
addressed in LibWeb.

GCC seems to have a bug that prevents `ExceptionOr<Variant<GCPtr<T>>>`
from being implicitly constructed from `GCPtr<T>` after this change. A
non-invasive workaround is to explicitly construct the inner Variant
type.

[1]: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#non-trivial
This commit is contained in:
Daniel Bertalan 2023-07-26 19:02:37 +02:00 committed by Tim Flynn
parent 82495083c3
commit 9feb1ce39f
4 changed files with 8 additions and 26 deletions

View file

@ -868,7 +868,7 @@ WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller_from_underly
// 7. If underlyingSourceDict["cancel"] exists, then set cancelAlgorithm to an algorithm which takes an argument reason and returns the result of invoking underlyingSourceDict["cancel"] with argument list « reason » and callback this value underlyingSource.
if (underlying_source.cancel) {
cancel_algorithm = [&realm, controller, underlying_source_value, callback = underlying_source.cancel](auto const& reason) -> WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> {
cancel_algorithm = [&realm, underlying_source_value, callback = underlying_source.cancel](auto const& reason) -> WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> {
// Note: callback return a promise, so invoke_callback will never return an abrupt completion
auto result = MUST_OR_THROW_OOM(WebIDL::invoke_callback(*callback, underlying_source_value, reason)).release_value();
return WebIDL::create_resolved_promise(realm, result);
@ -2528,7 +2528,7 @@ WebIDL::ExceptionOr<void> set_up_writable_stream_default_controller_from_underly
// 8. If underlyingSinkDict["close"] exists, then set closeAlgorithm to an algorithm which returns the result of invoking underlyingSinkDict["close"] with argument list «» and callback this value underlyingSink.
if (underlying_sink.close) {
close_algorithm = [&realm, controller, underlying_sink_value, callback = underlying_sink.close]() -> WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> {
close_algorithm = [&realm, underlying_sink_value, callback = underlying_sink.close]() -> WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> {
// Note: callback return a promise, so invoke_callback will never return an abrupt completion
auto result = MUST_OR_THROW_OOM(WebIDL::invoke_callback(*callback, underlying_sink_value)).release_value();
return WebIDL::create_resolved_promise(realm, result);
@ -2537,7 +2537,7 @@ WebIDL::ExceptionOr<void> set_up_writable_stream_default_controller_from_underly
// 9. If underlyingSinkDict["abort"] exists, then set abortAlgorithm to an algorithm which takes an argument reason and returns the result of invoking underlyingSinkDict["abort"] with argument list « reason » and callback this value underlyingSink.
if (underlying_sink.abort) {
abort_algorithm = [&realm, controller, underlying_sink_value, callback = underlying_sink.abort](JS::Value reason) -> WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> {
abort_algorithm = [&realm, underlying_sink_value, callback = underlying_sink.abort](JS::Value reason) -> WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> {
// Note: callback return a promise, so invoke_callback will never return an abrupt completion
auto result = MUST_OR_THROW_OOM(WebIDL::invoke_callback(*callback, underlying_sink_value, reason)).release_value();
return WebIDL::create_resolved_promise(realm, result);
@ -3342,7 +3342,7 @@ WebIDL::ExceptionOr<void> set_up_readable_byte_stream_controller_from_underlying
// 7. If underlyingSourceDict["cancel"] exists, then set cancelAlgorithm to an algorithm which takes an argument reason and returns the result of invoking underlyingSourceDict["cancel"] with argument list « reason » and callback this value underlyingSource.
if (underlying_source_dict.cancel) {
cancel_algorithm = [&realm, controller, underlying_source, callback = underlying_source_dict.cancel](auto const& reason) -> WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> {
cancel_algorithm = [&realm, underlying_source, callback = underlying_source_dict.cancel](auto const& reason) -> WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> {
// Note: callback return a promise, so invoke_callback will never return an abrupt completion
auto result = MUST_OR_THROW_OOM(WebIDL::invoke_callback(*callback, underlying_source, reason)).release_value();
return WebIDL::create_resolved_promise(realm, result);