Files
ladybird/Libraries/LibJS/Runtime/AsyncFunctionDriverWrapper.h
Shannon Booth b34274a2a0 LibJS: Combine onFulfilled and onRejected into a single settled callback
The fulfilled and rejected closures in AsyncFunctionDriverWrapper::await
were identical in structure, differing only in whether they resumed the
async context with a NormalCompletion or ThrowCompletion.

Since the callback has access to the current promise, we can check its
state at reaction time to determine which completion to use. This allows
us to allocate a single GC-tracked NativeFunction (m_on_settled) and
register it for both the onFulfilled and onRejected slots in
PerformPromiseThen, halving the number of GC allocations on this path.
2026-03-16 11:18:35 -05:00

42 lines
1.2 KiB
C++

/*
* Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibJS/Bytecode/Interpreter.h>
#include <LibJS/Runtime/ECMAScriptFunctionObject.h>
#include <LibJS/Runtime/GeneratorObject.h>
#include <LibJS/Runtime/Object.h>
#include <LibJS/Runtime/Promise.h>
namespace JS {
class AsyncFunctionDriverWrapper final : public Promise {
JS_OBJECT(AsyncFunctionDriverWrapper, Promise);
GC_DECLARE_ALLOCATOR(AsyncFunctionDriverWrapper);
public:
[[nodiscard]] static GC::Ref<Promise> create(Realm&, GeneratorObject*);
virtual ~AsyncFunctionDriverWrapper() override = default;
void visit_edges(Cell::Visitor&) override;
void continue_async_execution(VM&, Value, bool is_successful);
private:
AsyncFunctionDriverWrapper(Realm&, GC::Ref<GeneratorObject>, GC::Ref<Promise> top_level_promise);
ThrowCompletionOr<void> await(Value);
GC::Ref<GeneratorObject> m_generator_object;
GC::Ref<Promise> m_top_level_promise;
GC::Ptr<Promise> m_current_promise { nullptr };
OwnPtr<ExecutionContext> m_suspended_execution_context;
GC::Ptr<NativeFunction> m_on_settled;
};
}