mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 17:55:07 +02:00
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.
42 lines
1.2 KiB
C++
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;
|
|
};
|
|
|
|
}
|