Skip to content

Commit

Permalink
Implement napi_handle_scope and napi_escapable_handle_scope (#13756)
Browse files Browse the repository at this point in the history
  • Loading branch information
190n authored Sep 7, 2024
1 parent de5809b commit 084734d
Show file tree
Hide file tree
Showing 14 changed files with 887 additions and 193 deletions.
4 changes: 4 additions & 0 deletions src/bun.js/bindings/BunProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

#include "AsyncContextFrame.h"

#include "napi_handle_scope.h"

#ifndef WIN32
#include <errno.h>
#include <dlfcn.h>
Expand Down Expand Up @@ -406,6 +408,8 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
return JSC::JSValue::encode(JSC::JSValue {});
}

NapiHandleScope handleScope(globalObject);

EncodedJSValue exportsValue = JSC::JSValue::encode(exports);
JSC::JSValue resultValue = JSValue::decode(napi_register_module_v1(globalObject, exportsValue));

Expand Down
8 changes: 8 additions & 0 deletions src/bun.js/bindings/ZigGlobalObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
#include "libusockets.h"
#include "ModuleLoader.h"
#include "napi_external.h"
#include "napi_handle_scope.h"
#include "napi.h"
#include "NodeHTTP.h"
#include "NodeVM.h"
Expand Down Expand Up @@ -2901,6 +2902,10 @@ void GlobalObject::finishCreation(VM& vm)
Bun::NapiPrototype::createStructure(init.vm, init.owner, init.owner->objectPrototype()));
});

m_NapiHandleScopeImplStructure.initLater([](const JSC::LazyProperty<JSC::JSGlobalObject, Structure>::Initializer& init) {
init.set(Bun::NapiHandleScopeImpl::createStructure(init.vm, init.owner));
});

m_cachedNodeVMGlobalObjectStructure.initLater(
[](const JSC::LazyProperty<JSC::JSGlobalObject, Structure>::Initializer& init) {
init.set(WebCore::createNodeVMGlobalObjectStructure(init.vm));
Expand Down Expand Up @@ -3582,6 +3587,8 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
visitor.append(thisObject->m_pendingNapiModuleAndExports[0]);
visitor.append(thisObject->m_pendingNapiModuleAndExports[1]);

visitor.append(thisObject->m_currentNapiHandleScopeImpl);

thisObject->m_asyncBoundFunctionStructure.visit(visitor);
thisObject->m_bunObject.visit(visitor);
thisObject->m_cachedNodeVMGlobalObjectStructure.visit(visitor);
Expand Down Expand Up @@ -3620,6 +3627,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_NapiExternalStructure.visit(visitor);
thisObject->m_NAPIFunctionStructure.visit(visitor);
thisObject->m_NapiPrototypeStructure.visit(visitor);
thisObject->m_NapiHandleScopeImplStructure.visit(visitor);
thisObject->m_nativeMicrotaskTrampoline.visit(visitor);
thisObject->m_navigatorObject.visit(visitor);
thisObject->m_NodeVMScriptClassStructure.visit(visitor);
Expand Down
9 changes: 9 additions & 0 deletions src/bun.js/bindings/ZigGlobalObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Performance;

namespace Bun {
class InternalModuleRegistry;
class NapiHandleScopeImpl;
} // namespace Bun

namespace v8 {
Expand Down Expand Up @@ -283,6 +284,7 @@ class GlobalObject : public Bun::GlobalScope {
Structure* NapiExternalStructure() const { return m_NapiExternalStructure.getInitializedOnMainThread(this); }
Structure* NapiPrototypeStructure() const { return m_NapiPrototypeStructure.getInitializedOnMainThread(this); }
Structure* NAPIFunctionStructure() const { return m_NAPIFunctionStructure.getInitializedOnMainThread(this); }
Structure* NapiHandleScopeImplStructure() const { return m_NapiHandleScopeImplStructure.getInitializedOnMainThread(this); }

Structure* JSSQLStatementStructure() const { return m_JSSQLStatementStructure.getInitializedOnMainThread(this); }

Expand Down Expand Up @@ -405,6 +407,11 @@ class GlobalObject : public Bun::GlobalScope {
// When a napi module initializes on dlopen, we need to know what the value is
mutable JSC::WriteBarrier<Unknown> m_pendingNapiModuleAndExports[2];

// The handle scope where all new NAPI values will be created. You must not pass any napi_values
// back to a NAPI function without putting them in the handle scope, as the NAPI function may
// move them off the stack which will cause them to get collected if not in the handle scope.
JSC::WriteBarrier<Bun::NapiHandleScopeImpl> m_currentNapiHandleScopeImpl;

// The original, unmodified Error.prepareStackTrace.
//
// We set a default value for this to mimick Node.js behavior It is a
Expand Down Expand Up @@ -564,6 +571,8 @@ class GlobalObject : public Bun::GlobalScope {
LazyProperty<JSGlobalObject, Structure> m_NapiExternalStructure;
LazyProperty<JSGlobalObject, Structure> m_NapiPrototypeStructure;
LazyProperty<JSGlobalObject, Structure> m_NAPIFunctionStructure;
LazyProperty<JSGlobalObject, Structure> m_NapiHandleScopeImplStructure;

LazyProperty<JSGlobalObject, Structure> m_JSSQLStatementStructure;
LazyProperty<JSGlobalObject, v8::GlobalInternals> m_V8GlobalInternals;

Expand Down
Loading

0 comments on commit 084734d

Please sign in to comment.