mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Implement RefCounted for napi_env
This change makes `napi_env__` extend `RefCounted<napi_env__>` and uses `RefPtr<napi_env__>` throughout the codebase, following the RAII pattern for automatic reference counting. Changes: - Make `struct napi_env__` extend `RefCounted<napi_env__>` - Add `using NapiEnv = WTF::RefPtr<napi_env__>` typedef - Update `NapiRef` to store `NapiEnv` instead of raw `napi_env` - Update `ZigGlobalObject::m_napiEnvs` to use `Vector<NapiEnv>` - Update `makeNapiEnv()` to use `adoptRef()` instead of `make_unique()` - Update finalizer lambda to capture `NapiEnv` via RefPtr for automatic ref/unref - Update all usages to call `.get()` when accessing the raw pointer This enables automatic reference counting via RAII - RefPtr handles ref/unref through constructors/destructors, eliminating the need for manual reference management.
This commit is contained in:
@@ -37,7 +37,7 @@ void NapiRef::unref()
|
||||
void NapiRef::clear()
|
||||
{
|
||||
NAPI_LOG("ref clear %p", this);
|
||||
finalizer.call(env, nativeObject);
|
||||
finalizer.call(env.get(), nativeObject);
|
||||
globalObject.clear();
|
||||
weakValueRef.clear();
|
||||
strongRef.clear();
|
||||
|
||||
@@ -3519,7 +3519,7 @@ GlobalObject::PromiseFunctions GlobalObject::promiseHandlerID(Zig::FFIFunction h
|
||||
|
||||
napi_env GlobalObject::makeNapiEnv(const napi_module& mod)
|
||||
{
|
||||
m_napiEnvs.append(std::make_unique<napi_env__>(this, mod));
|
||||
m_napiEnvs.append(adoptRef(new napi_env__(this, mod)));
|
||||
return m_napiEnvs.last().get();
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,9 @@ class GlobalInternals;
|
||||
#include "BakeAdditionsToGlobalObject.h"
|
||||
#include "WriteBarrierList.h"
|
||||
|
||||
struct napi_env__;
|
||||
using NapiEnv = WTF::RefPtr<napi_env__>;
|
||||
|
||||
namespace Bun {
|
||||
class JSCommonJSExtensions;
|
||||
class InternalModuleRegistry;
|
||||
@@ -724,7 +727,7 @@ public:
|
||||
// De-optimization once `require("module").runMain` is written to
|
||||
bool hasOverriddenModuleRunMain = false;
|
||||
|
||||
WTF::Vector<std::unique_ptr<napi_env__>> m_napiEnvs;
|
||||
WTF::Vector<NapiEnv> m_napiEnvs;
|
||||
napi_env makeNapiEnv(const napi_module&);
|
||||
napi_env makeNapiEnvForFFI();
|
||||
bool hasNapiFinalizers() const;
|
||||
|
||||
@@ -1126,9 +1126,11 @@ extern "C" napi_status napi_add_finalizer(napi_env env, napi_value js_object,
|
||||
*result = toNapi(ref);
|
||||
} else {
|
||||
// Otherwise, it's cheaper to just call .addFinalizer.
|
||||
vm.heap.addFinalizer(object, [env, finalize_cb, native_object, finalize_hint](JSCell* cell) -> void {
|
||||
// Capture env as RefPtr - automatically refs on capture, unrefs on destruction
|
||||
NapiEnv envRef = env;
|
||||
vm.heap.addFinalizer(object, [envRef = WTFMove(envRef), finalize_cb, native_object, finalize_hint](JSCell* cell) -> void {
|
||||
NAPI_LOG("finalizer %p", finalize_hint);
|
||||
env->doFinalizer(finalize_cb, native_object, finalize_hint);
|
||||
envRef->doFinalizer(finalize_cb, native_object, finalize_hint);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ static bool equal(napi_async_cleanup_hook_handle one, napi_async_cleanup_hook_ha
|
||||
} while (0)
|
||||
|
||||
// Named this way so we can manipulate napi_env values directly (since napi_env is defined as a pointer to struct napi_env__)
|
||||
struct napi_env__ {
|
||||
struct napi_env__ : public RefCounted<napi_env__> {
|
||||
public:
|
||||
napi_env__(Zig::GlobalObject* globalObject, const napi_module& napiModule)
|
||||
: m_globalObject(globalObject)
|
||||
@@ -506,6 +506,8 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
using NapiEnv = WTF::RefPtr<napi_env__>;
|
||||
|
||||
extern "C" void napi_internal_cleanup_env_cpp(napi_env);
|
||||
extern "C" void napi_internal_remove_finalizer(napi_env, napi_finalize callback, void* hint, void* data);
|
||||
|
||||
@@ -659,9 +661,9 @@ public:
|
||||
void unref();
|
||||
void clear();
|
||||
|
||||
NapiRef(napi_env env, uint32_t count, Bun::NapiFinalizer finalizer)
|
||||
: env(env)
|
||||
, globalObject(JSC::Weak<JSC::JSGlobalObject>(env->globalObject()))
|
||||
NapiRef(napi_env rawEnv, uint32_t count, Bun::NapiFinalizer finalizer)
|
||||
: env(rawEnv)
|
||||
, globalObject(JSC::Weak<JSC::JSGlobalObject>(rawEnv->globalObject()))
|
||||
, finalizer(WTFMove(finalizer))
|
||||
, refCount(count)
|
||||
{
|
||||
@@ -708,14 +710,14 @@ public:
|
||||
// calling the finalizer
|
||||
Bun::NapiFinalizer saved_finalizer = this->finalizer;
|
||||
this->finalizer.clear();
|
||||
saved_finalizer.call(env, nativeObject, !env->mustDeferFinalizers() || !env->inGC());
|
||||
saved_finalizer.call(env.get(), nativeObject, !env->mustDeferFinalizers() || !env->inGC());
|
||||
}
|
||||
|
||||
~NapiRef()
|
||||
{
|
||||
NAPI_LOG("destruct napi ref %p", this);
|
||||
if (boundCleanup) {
|
||||
boundCleanup->deactivate(env);
|
||||
boundCleanup->deactivate(env.get());
|
||||
boundCleanup = nullptr;
|
||||
}
|
||||
|
||||
@@ -728,7 +730,7 @@ public:
|
||||
weakValueRef.clear();
|
||||
}
|
||||
|
||||
napi_env env = nullptr;
|
||||
NapiEnv env = nullptr;
|
||||
JSC::Weak<JSC::JSGlobalObject> globalObject;
|
||||
NapiWeakValue weakValueRef;
|
||||
JSC::Strong<JSC::Unknown> strongRef;
|
||||
|
||||
Reference in New Issue
Block a user