mirror of
https://github.com/oven-sh/bun
synced 2026-02-03 23:48:52 +00:00
Compare commits
9 Commits
ciro/fix-a
...
kai/napi-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a7a70ff9f | ||
|
|
fd0eb10b76 | ||
|
|
e848f7a85b | ||
|
|
f99d1bce54 | ||
|
|
57a3f839e5 | ||
|
|
b98fe402be | ||
|
|
85499c8709 | ||
|
|
bfc423eeb9 | ||
|
|
9e9d137ca2 |
@@ -73,6 +73,8 @@ const URL = @import("../../url.zig").URL;
|
||||
const VirtualMachine = JSC.VirtualMachine;
|
||||
const IOTask = JSC.IOTask;
|
||||
|
||||
const napi = @import("../../napi/napi.zig");
|
||||
|
||||
const TCC = @import("../../tcc.zig");
|
||||
extern fn pthread_jit_write_protect_np(enable: bool) callconv(.C) void;
|
||||
|
||||
@@ -446,7 +448,7 @@ pub const FFI = struct {
|
||||
|
||||
for (this.symbols.map.values()) |*symbol| {
|
||||
if (symbol.needsNapiEnv()) {
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", globalThis);
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", globalThis.makeNapiEnvForFFI());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -800,12 +802,14 @@ pub const FFI = struct {
|
||||
// we are unable to free memory safely in certain cases here.
|
||||
}
|
||||
|
||||
const napi_env = makeNapiEnvIfNeeded(compile_c.symbols.map.values(), globalThis);
|
||||
|
||||
var obj = JSC.JSValue.createEmptyObject(globalThis, compile_c.symbols.map.count());
|
||||
for (compile_c.symbols.map.values()) |*function| {
|
||||
const function_name = function.base_name.?;
|
||||
const allocator = bun.default_allocator;
|
||||
|
||||
function.compile(allocator, globalThis) catch |err| {
|
||||
function.compile(allocator, napi_env) catch |err| {
|
||||
if (!globalThis.hasException()) {
|
||||
const ret = JSC.toInvalidArguments("{s} when translating symbol \"{s}\"", .{
|
||||
@errorName(err),
|
||||
@@ -1126,6 +1130,9 @@ pub const FFI = struct {
|
||||
var obj = JSC.JSValue.createEmptyObject(global, size);
|
||||
obj.protect();
|
||||
defer obj.unprotect();
|
||||
|
||||
const napi_env = makeNapiEnvIfNeeded(symbols.values(), global);
|
||||
|
||||
for (symbols.values()) |*function| {
|
||||
const function_name = function.base_name.?;
|
||||
|
||||
@@ -1145,7 +1152,7 @@ pub const FFI = struct {
|
||||
function.symbol_from_dynamic_library = resolved_symbol;
|
||||
}
|
||||
|
||||
function.compile(allocator, global) catch |err| {
|
||||
function.compile(allocator, napi_env) catch |err| {
|
||||
const ret = JSC.toInvalidArguments("{s} when compiling symbol \"{s}\" in \"{s}\"", .{
|
||||
bun.asByteSlice(@errorName(err)),
|
||||
bun.asByteSlice(function_name),
|
||||
@@ -1237,6 +1244,8 @@ pub const FFI = struct {
|
||||
var obj = JSValue.createEmptyObject(global, symbols.count());
|
||||
obj.ensureStillAlive();
|
||||
defer obj.ensureStillAlive();
|
||||
const napi_env = makeNapiEnvIfNeeded(symbols.values(), global);
|
||||
|
||||
for (symbols.values()) |*function| {
|
||||
const function_name = function.base_name.?;
|
||||
|
||||
@@ -1250,7 +1259,7 @@ pub const FFI = struct {
|
||||
return ret;
|
||||
}
|
||||
|
||||
function.compile(allocator, global) catch |err| {
|
||||
function.compile(allocator, napi_env) catch |err| {
|
||||
const ret = JSC.toInvalidArguments("{s} when compiling symbol \"{s}\"", .{
|
||||
bun.asByteSlice(@errorName(err)),
|
||||
bun.asByteSlice(function_name),
|
||||
@@ -1559,7 +1568,7 @@ pub const FFI = struct {
|
||||
pub fn compile(
|
||||
this: *Function,
|
||||
allocator: std.mem.Allocator,
|
||||
globalObject: *JSC.JSGlobalObject,
|
||||
napiEnv: ?*napi.NapiEnv,
|
||||
) !void {
|
||||
var source_code = std.ArrayList(u8).init(allocator);
|
||||
var source_code_writer = source_code.writer();
|
||||
@@ -1582,7 +1591,9 @@ pub const FFI = struct {
|
||||
|
||||
_ = TCC.tcc_set_output_type(state, TCC.TCC_OUTPUT_MEMORY);
|
||||
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", globalObject);
|
||||
if (napiEnv) |env| {
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", env);
|
||||
}
|
||||
|
||||
CompilerRT.define(state);
|
||||
|
||||
@@ -1691,7 +1702,9 @@ pub const FFI = struct {
|
||||
|
||||
_ = TCC.tcc_set_output_type(state, TCC.TCC_OUTPUT_MEMORY);
|
||||
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", js_context);
|
||||
if (this.needsNapiEnv()) {
|
||||
_ = TCC.tcc_add_symbol(state, "Bun__thisFFIModuleNapiEnv", js_context.makeNapiEnvForFFI());
|
||||
}
|
||||
|
||||
CompilerRT.define(state);
|
||||
|
||||
@@ -2550,3 +2563,13 @@ const CompilerRT = struct {
|
||||
};
|
||||
|
||||
pub const Bun__FFI__cc = FFI.Bun__FFI__cc;
|
||||
|
||||
fn makeNapiEnvIfNeeded(functions: []const FFI.Function, globalThis: *JSGlobalObject) ?*napi.NapiEnv {
|
||||
for (functions) |function| {
|
||||
if (function.needsNapiEnv()) {
|
||||
return globalThis.makeNapiEnvForFFI();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -394,17 +394,14 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
JSC::EncodedJSValue (*napi_register_module_v1)(JSC::JSGlobalObject* globalObject,
|
||||
JSC::EncodedJSValue exports);
|
||||
#if OS(WINDOWS)
|
||||
#define dlsym GetProcAddress
|
||||
#endif
|
||||
|
||||
// TODO(@190n) look for node_register_module_vXYZ according to BuildOptions.reported_nodejs_version
|
||||
// (bun/src/env.zig:36) and the table at https://github.com/nodejs/node/blob/main/doc/abi_version_registry.json
|
||||
napi_register_module_v1 = reinterpret_cast<JSC::EncodedJSValue (*)(JSC::JSGlobalObject*,
|
||||
JSC::EncodedJSValue)>(
|
||||
dlsym(handle, "napi_register_module_v1"));
|
||||
auto napi_register_module_v1 = reinterpret_cast<napi_value (*)(napi_env, napi_value)>(dlsym(handle, "napi_register_module_v1"));
|
||||
auto node_api_module_get_api_version_v1 = reinterpret_cast<int32_t (*)()>(dlsym(handle, "node_api_module_get_api_version_v1"));
|
||||
|
||||
#if OS(WINDOWS)
|
||||
#undef dlsym
|
||||
@@ -420,10 +417,31 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
|
||||
return {};
|
||||
}
|
||||
|
||||
// TODO(@heimskr): get the API version without node_api_module_get_api_version_v1 a different way
|
||||
int module_version = 8;
|
||||
if (node_api_module_get_api_version_v1) {
|
||||
module_version = node_api_module_get_api_version_v1();
|
||||
}
|
||||
|
||||
NapiHandleScope handleScope(globalObject);
|
||||
|
||||
EncodedJSValue exportsValue = JSC::JSValue::encode(exports);
|
||||
JSC::JSValue resultValue = JSValue::decode(napi_register_module_v1(globalObject, exportsValue));
|
||||
|
||||
napi_module nmodule {
|
||||
.nm_version = module_version,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = "file://",
|
||||
.nm_register_func = nullptr,
|
||||
.nm_modname = "[no modname]",
|
||||
.nm_priv = nullptr,
|
||||
.reserved = {},
|
||||
};
|
||||
|
||||
static_assert(sizeof(napi_value) == sizeof(EncodedJSValue), "EncodedJSValue must be reinterpretable as a pointer");
|
||||
|
||||
auto env = globalObject->makeNapiEnv(nmodule);
|
||||
|
||||
JSC::JSValue resultValue = JSValue::decode(reinterpret_cast<EncodedJSValue>(napi_register_module_v1(env, reinterpret_cast<napi_value>(exportsValue))));
|
||||
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
|
||||
@@ -1204,9 +1204,8 @@ GlobalObject::GlobalObject(JSC::VM& vm, JSC::Structure* structure, WebCore::Scri
|
||||
|
||||
GlobalObject::~GlobalObject()
|
||||
{
|
||||
if (napiInstanceDataFinalizer) {
|
||||
napi_finalize finalizer = reinterpret_cast<napi_finalize>(napiInstanceDataFinalizer);
|
||||
finalizer(toNapi(this), napiInstanceData, napiInstanceDataFinalizerHint);
|
||||
for (const auto& env : m_napiEnvs) {
|
||||
env->cleanup();
|
||||
}
|
||||
|
||||
if (auto* ctx = scriptExecutionContext()) {
|
||||
@@ -2487,6 +2486,11 @@ extern "C" JSC__JSValue ZigGlobalObject__readableStreamToBlob(Zig::GlobalObject*
|
||||
return JSC::JSValue::encode(call(globalObject, function, callData, JSC::jsUndefined(), arguments));
|
||||
}
|
||||
|
||||
extern "C" napi_env ZigGlobalObject__makeNapiEnvForFFI(Zig::GlobalObject* globalObject)
|
||||
{
|
||||
return globalObject->makeNapiEnvForFFI();
|
||||
}
|
||||
|
||||
JSC_DECLARE_HOST_FUNCTION(functionReadableStreamToArrayBuffer);
|
||||
JSC_DEFINE_HOST_FUNCTION(functionReadableStreamToArrayBuffer, (JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
@@ -4354,6 +4358,26 @@ 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));
|
||||
return m_napiEnvs.last().get();
|
||||
}
|
||||
|
||||
napi_env GlobalObject::makeNapiEnvForFFI()
|
||||
{
|
||||
auto out = makeNapiEnv(napi_module {
|
||||
.nm_version = 9,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = "ffi://",
|
||||
.nm_register_func = nullptr,
|
||||
.nm_modname = "[ffi]",
|
||||
.nm_priv = nullptr,
|
||||
.reserved = {},
|
||||
});
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "ZigGeneratedClasses+lazyStructureImpl.h"
|
||||
#include "ZigGlobalObject.lut.h"
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ class GlobalInternals;
|
||||
#include "BunHttp2CommonStrings.h"
|
||||
#include "BunGlobalScope.h"
|
||||
|
||||
typedef struct napi_env__* napi_env;
|
||||
struct napi_module;
|
||||
|
||||
namespace WebCore {
|
||||
class WorkerGlobalScope;
|
||||
class SubtleCrypto;
|
||||
@@ -446,13 +449,6 @@ public:
|
||||
// To do that, we count the number of times we register a module.
|
||||
int napiModuleRegisterCallCount = 0;
|
||||
|
||||
// NAPI instance data
|
||||
// This is not a correct implementation
|
||||
// Addon modules can override each other's data
|
||||
void* napiInstanceData = nullptr;
|
||||
void* napiInstanceDataFinalizer = nullptr;
|
||||
void* napiInstanceDataFinalizerHint = nullptr;
|
||||
|
||||
// Used by napi_type_tag_object to associate a 128-bit type ID with JS objects.
|
||||
// Should only use JSCell* keys and NapiTypeTag values.
|
||||
LazyProperty<JSGlobalObject, JSC::JSWeakMap> m_napiTypeTags;
|
||||
@@ -573,6 +569,10 @@ public:
|
||||
|
||||
bool hasOverridenModuleResolveFilenameFunction = false;
|
||||
|
||||
WTF::Vector<std::unique_ptr<napi_env__>> m_napiEnvs;
|
||||
napi_env makeNapiEnv(const napi_module&);
|
||||
napi_env makeNapiEnvForFFI();
|
||||
|
||||
private:
|
||||
DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock);
|
||||
WebCore::SubtleCrypto* m_subtleCrypto = nullptr;
|
||||
|
||||
@@ -23,6 +23,7 @@ const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
const napi = @import("../../napi/napi.zig");
|
||||
|
||||
pub const JSObject = extern struct {
|
||||
pub const shim = Shimmer("JSC", "JSObject", @This());
|
||||
@@ -3417,6 +3418,12 @@ pub const JSGlobalObject = opaque {
|
||||
return ZigGlobalObject__readableStreamToFormData(this, value, content_type);
|
||||
}
|
||||
|
||||
extern fn ZigGlobalObject__makeNapiEnvForFFI(*JSGlobalObject) *napi.NapiEnv;
|
||||
|
||||
pub fn makeNapiEnvForFFI(this: *JSGlobalObject) *napi.NapiEnv {
|
||||
return ZigGlobalObject__makeNapiEnvForFFI(this);
|
||||
}
|
||||
|
||||
pub inline fn assertOnJSThread(this: *JSGlobalObject) void {
|
||||
if (bun.Environment.allow_assert) this.bunVM().assertOnJSThread();
|
||||
}
|
||||
|
||||
@@ -84,6 +84,26 @@ using namespace Zig;
|
||||
#define NAPI_PREMABLE
|
||||
#endif
|
||||
|
||||
// Usage: `return napi_set_last_error(napi_ok);`
|
||||
//
|
||||
// Sets the global extended error info to indicate the passed-in status, and then returns it.
|
||||
// All NAPI functions should call this in all places where they return, even if there is no error,
|
||||
// because the extended error info should always reflect the most recent API call. The only
|
||||
// exception is napi_get_last_error_info, which should return napi_ok without overwriting the
|
||||
// extended error info.
|
||||
//
|
||||
// Usually, you should use the above macros instead of this function.
|
||||
//
|
||||
// This is not part of Node-API, it's a convenience function for Bun.
|
||||
extern "C" napi_status napi_set_last_error(napi_env env, napi_status status)
|
||||
{
|
||||
if (env) {
|
||||
// napi_get_last_error_info will fill in the other fields if they are requested
|
||||
env->m_lastNapiErrorInfo.error_code = status;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
namespace Napi {
|
||||
|
||||
JSC::SourceCode generateSourceCode(WTF::String keyString, JSC::VM& vm, JSC::JSObject* object, JSC::JSGlobalObject* globalObject)
|
||||
@@ -135,7 +155,7 @@ public:
|
||||
auto finalizer = weakValue->finalizer;
|
||||
if (finalizer.finalize_cb) {
|
||||
weakValue->finalizer.finalize_cb = nullptr;
|
||||
finalizer.call(weakValue->globalObject.get(), weakValue->data);
|
||||
finalizer.call(weakValue->env, weakValue->data);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -146,11 +166,11 @@ static NapiRefWeakHandleOwner& weakValueHandleOwner()
|
||||
return jscWeakValueHandleOwner;
|
||||
}
|
||||
|
||||
void NapiFinalizer::call(JSC::JSGlobalObject* globalObject, void* data)
|
||||
void NapiFinalizer::call(napi_env env, void* data)
|
||||
{
|
||||
if (this->finalize_cb) {
|
||||
NAPI_PREMABLE
|
||||
this->finalize_cb(toNapi(globalObject), data, this->finalize_hint);
|
||||
this->finalize_cb(env, data, this->finalize_hint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +202,7 @@ void NapiRef::unref()
|
||||
|
||||
void NapiRef::clear()
|
||||
{
|
||||
this->finalizer.call(this->globalObject.get(), this->data);
|
||||
this->finalizer.call(this->env, this->data);
|
||||
this->globalObject.clear();
|
||||
this->weakValueRef.clear();
|
||||
this->strongRef.clear();
|
||||
@@ -432,7 +452,6 @@ public:
|
||||
{
|
||||
ASSERT(jsCast<NAPIFunction*>(callframe->jsCallee()));
|
||||
auto* function = static_cast<NAPIFunction*>(callframe->jsCallee());
|
||||
auto* env = toNapi(globalObject);
|
||||
auto* callback = reinterpret_cast<napi_callback>(function->m_method);
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
@@ -446,28 +465,29 @@ public:
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
Bun::NapiHandleScope handleScope(jsCast<Zig::GlobalObject*>(globalObject));
|
||||
|
||||
auto result = callback(env, NAPICallFrame::toNapiCallbackInfo(frame));
|
||||
auto result = callback(function->m_env, NAPICallFrame::toNapiCallbackInfo(frame));
|
||||
|
||||
RELEASE_AND_RETURN(scope, JSC::JSValue::encode(toJS(result)));
|
||||
}
|
||||
|
||||
NAPIFunction(JSC::VM& vm, JSC::NativeExecutable* exec, JSGlobalObject* globalObject, Structure* structure, Zig::CFFIFunction method, void* dataPtr)
|
||||
NAPIFunction(JSC::VM& vm, JSC::NativeExecutable* exec, JSGlobalObject* globalObject, Structure* structure, Zig::CFFIFunction method, void* dataPtr, napi_env env)
|
||||
: Base(vm, exec, globalObject, structure)
|
||||
, m_method(method)
|
||||
, m_env(env)
|
||||
, m_dataPtr(dataPtr)
|
||||
, m_method(method)
|
||||
{
|
||||
}
|
||||
|
||||
static NAPIFunction* create(JSC::VM& vm, Zig::GlobalObject* globalObject, unsigned length, const WTF::String& name, Zig::CFFIFunction method, void* dataPtr)
|
||||
static NAPIFunction* create(JSC::VM& vm, Zig::GlobalObject* globalObject, unsigned length, const WTF::String& name, Zig::CFFIFunction method, void* dataPtr, napi_env env)
|
||||
{
|
||||
|
||||
auto* structure = globalObject->NAPIFunctionStructure();
|
||||
NativeExecutable* executable = vm.getHostFunction(&NAPIFunction::call, ImplementationVisibility::Public, &NAPIFunction::call, name);
|
||||
NAPIFunction* functionObject = new (NotNull, JSC::allocateCell<NAPIFunction>(vm)) NAPIFunction(vm, executable, globalObject, structure, method, dataPtr);
|
||||
NAPIFunction* functionObject = new (NotNull, JSC::allocateCell<NAPIFunction>(vm)) NAPIFunction(vm, executable, globalObject, structure, method, dataPtr, env);
|
||||
functionObject->finishCreation(vm, executable, length, name);
|
||||
return functionObject;
|
||||
}
|
||||
|
||||
napi_env m_env = nullptr;
|
||||
void* m_dataPtr = nullptr;
|
||||
Zig::CFFIFunction m_method = nullptr;
|
||||
|
||||
@@ -501,8 +521,9 @@ Structure* Zig::createNAPIFunctionStructure(VM& vm, JSC::JSGlobalObject* globalO
|
||||
return NAPIFunction::createStructure(vm, globalObject, prototype);
|
||||
}
|
||||
|
||||
static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* to, void* inheritedDataPtr, napi_property_descriptor property, bool isInstance, JSC::ThrowScope& scope)
|
||||
static void defineNapiProperty(napi_env env, JSC::JSObject* to, void* inheritedDataPtr, napi_property_descriptor property, bool isInstance, JSC::ThrowScope& scope)
|
||||
{
|
||||
Zig::GlobalObject* globalObject = env->globalObject();
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
void* dataPtr = property.data;
|
||||
if (!dataPtr) {
|
||||
@@ -535,7 +556,7 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
|
||||
JSC::JSValue value;
|
||||
auto method = reinterpret_cast<Zig::CFFIFunction>(property.method);
|
||||
|
||||
auto* function = NAPIFunction::create(vm, globalObject, 1, propertyName.isSymbol() ? String() : propertyName.string(), method, dataPtr);
|
||||
auto* function = NAPIFunction::create(vm, globalObject, 1, propertyName.isSymbol() ? String() : propertyName.string(), method, dataPtr, env);
|
||||
value = JSC::JSValue(function);
|
||||
|
||||
to->putDirect(vm, propertyName, value, getPropertyAttributes(property));
|
||||
@@ -550,7 +571,7 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
|
||||
auto setterProperty = reinterpret_cast<CFFIFunction>(property.setter);
|
||||
|
||||
if (getterProperty) {
|
||||
getter = NAPIFunction::create(vm, globalObject, 0, makeString("get "_s, propertyName.isSymbol() ? String() : propertyName.string()), getterProperty, dataPtr);
|
||||
getter = NAPIFunction::create(vm, globalObject, 0, makeString("get "_s, propertyName.isSymbol() ? String() : propertyName.string()), getterProperty, dataPtr, env);
|
||||
} else {
|
||||
JSC::JSNativeStdFunction* getterFunction = JSC::JSNativeStdFunction::create(
|
||||
globalObject->vm(), globalObject, 0, String(), [](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> JSC::EncodedJSValue {
|
||||
@@ -560,7 +581,7 @@ static void defineNapiProperty(Zig::GlobalObject* globalObject, JSC::JSObject* t
|
||||
}
|
||||
|
||||
if (setterProperty) {
|
||||
setter = NAPIFunction::create(vm, globalObject, 1, makeString("set "_s, propertyName.isSymbol() ? String() : propertyName.string()), setterProperty, dataPtr);
|
||||
setter = NAPIFunction::create(vm, globalObject, 1, makeString("set "_s, propertyName.isSymbol() ? String() : propertyName.string()), setterProperty, dataPtr, env);
|
||||
} else {
|
||||
JSC::JSNativeStdFunction* setterFunction = JSC::JSNativeStdFunction::create(
|
||||
globalObject->vm(), globalObject, 1, String(), [](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> JSC::EncodedJSValue {
|
||||
@@ -900,12 +921,12 @@ node_api_create_external_string_latin1(napi_env env,
|
||||
}
|
||||
|
||||
length = length == NAPI_AUTO_LENGTH ? strlen(str) : length;
|
||||
WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create({ reinterpret_cast<const LChar*>(str), static_cast<unsigned int>(length) }, finalize_hint, [finalize_callback](void* hint, void* str, unsigned length) {
|
||||
WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create({ reinterpret_cast<const LChar*>(str), static_cast<unsigned int>(length) }, finalize_hint, [finalize_callback, env](void* hint, void* str, unsigned length) {
|
||||
if (finalize_callback) {
|
||||
#if NAPI_VERBOSE
|
||||
printf("[napi] string finalize_callback\n");
|
||||
#endif
|
||||
finalize_callback(toNapi(defaultGlobalObject()), nullptr, hint);
|
||||
finalize_callback(env, nullptr, hint);
|
||||
}
|
||||
});
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
@@ -937,13 +958,13 @@ node_api_create_external_string_utf16(napi_env env,
|
||||
}
|
||||
|
||||
length = length == NAPI_AUTO_LENGTH ? std::char_traits<char16_t>::length(str) : length;
|
||||
WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create({ reinterpret_cast<const UChar*>(str), static_cast<unsigned int>(length) }, finalize_hint, [finalize_callback](void* hint, void* str, unsigned length) {
|
||||
WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create({ reinterpret_cast<const UChar*>(str), static_cast<unsigned int>(length) }, finalize_hint, [finalize_callback, env](void* hint, void* str, unsigned length) {
|
||||
#if NAPI_VERBOSE
|
||||
printf("[napi] string finalize_callback\n");
|
||||
#endif
|
||||
|
||||
if (finalize_callback) {
|
||||
finalize_callback(toNapi(defaultGlobalObject()), nullptr, hint);
|
||||
finalize_callback(env, nullptr, hint);
|
||||
}
|
||||
});
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
@@ -959,6 +980,7 @@ extern "C" size_t Bun__napi_module_register_count;
|
||||
extern "C" void napi_module_register(napi_module* mod)
|
||||
{
|
||||
auto* globalObject = defaultGlobalObject();
|
||||
napi_env env = globalObject->makeNapiEnv(*mod);
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto keyStr = WTF::String::fromUTF8(mod->nm_modname);
|
||||
globalObject->napiModuleRegisterCallCount++;
|
||||
@@ -988,7 +1010,7 @@ extern "C" void napi_module_register(napi_module* mod)
|
||||
JSC::Strong<JSC::JSObject> strongObject = { vm, object };
|
||||
|
||||
Bun::NapiHandleScope handleScope(globalObject);
|
||||
JSValue resultValue = toJS(mod->nm_register_func(toNapi(globalObject), toNapi(object, globalObject)));
|
||||
JSValue resultValue = toJS(mod->nm_register_func(env, toNapi(object, globalObject)));
|
||||
|
||||
RETURN_IF_EXCEPTION(scope, void());
|
||||
|
||||
@@ -1033,8 +1055,6 @@ extern "C" napi_status napi_wrap(napi_env env,
|
||||
return napi_object_expected;
|
||||
}
|
||||
|
||||
auto* globalObject = toJS(env);
|
||||
|
||||
NapiRef** refPtr = nullptr;
|
||||
if (auto* val = jsDynamicCast<NapiPrototype*>(value)) {
|
||||
refPtr = &val->napiRef;
|
||||
@@ -1053,7 +1073,7 @@ extern "C" napi_status napi_wrap(napi_env env,
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
auto* ref = new NapiRef(globalObject, 0);
|
||||
auto* ref = new NapiRef(env, 0);
|
||||
|
||||
ref->weakValueRef.set(value, weakValueHandleOwner(), ref);
|
||||
|
||||
@@ -1158,7 +1178,7 @@ extern "C" napi_status napi_create_function(napi_env env, const char* utf8name,
|
||||
}
|
||||
|
||||
auto method = reinterpret_cast<Zig::CFFIFunction>(cb);
|
||||
auto* function = NAPIFunction::create(vm, globalObject, length, name, method, data);
|
||||
auto* function = NAPIFunction::create(vm, globalObject, length, name, method, data, env);
|
||||
|
||||
ASSERT(function->isCallable());
|
||||
*result = toNapi(JSC::JSValue(function), globalObject);
|
||||
@@ -1280,7 +1300,7 @@ napi_define_properties(napi_env env, napi_value object, size_t property_count,
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < property_count; i++) {
|
||||
defineNapiProperty(globalObject, objectObject, inheritedDataPtr, properties[i], true, throwScope);
|
||||
defineNapiProperty(env, objectObject, inheritedDataPtr, properties[i], true, throwScope);
|
||||
|
||||
RETURN_IF_EXCEPTION(throwScope, napi_generic_failure);
|
||||
}
|
||||
@@ -1377,7 +1397,7 @@ extern "C" napi_status napi_create_reference(napi_env env, napi_value value,
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
|
||||
auto* ref = new NapiRef(globalObject, initial_refcount);
|
||||
auto* ref = new NapiRef(env, initial_refcount);
|
||||
if (initial_refcount > 0) {
|
||||
ref->strongRef.set(globalObject->vm(), val);
|
||||
}
|
||||
@@ -1814,8 +1834,7 @@ void NapiClass::visitChildrenImpl(JSCell* cell, Visitor& visitor)
|
||||
|
||||
DEFINE_VISIT_CHILDREN(NapiClass);
|
||||
|
||||
JSC_DEFINE_HOST_FUNCTION(NapiClass_ConstructorFunction,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
JSC_HOST_CALL_ATTRIBUTES JSC::EncodedJSValue NapiClass_ConstructorFunction(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
@@ -1853,12 +1872,12 @@ JSC_DEFINE_HOST_FUNCTION(NapiClass_ConstructorFunction,
|
||||
frame.newTarget = newTarget;
|
||||
Bun::NapiHandleScope handleScope(jsCast<Zig::GlobalObject*>(globalObject));
|
||||
|
||||
napi->constructor()(globalObject, reinterpret_cast<JSC::CallFrame*>(NAPICallFrame::toNapiCallbackInfo(frame)));
|
||||
napi->constructor()(napi->env(), NAPICallFrame::toNapiCallbackInfo(frame));
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
RELEASE_AND_RETURN(scope, JSValue::encode(frame.thisValue()));
|
||||
}
|
||||
|
||||
NapiClass* NapiClass::create(VM& vm, Zig::GlobalObject* globalObject, const char* utf8name,
|
||||
NapiClass* NapiClass::create(VM& vm, napi_env env, const char* utf8name,
|
||||
size_t length,
|
||||
napi_callback constructor,
|
||||
void* data,
|
||||
@@ -1867,8 +1886,9 @@ NapiClass* NapiClass::create(VM& vm, Zig::GlobalObject* globalObject, const char
|
||||
{
|
||||
WTF::String name = WTF::String::fromUTF8({ utf8name, length }).isolatedCopy();
|
||||
NativeExecutable* executable = vm.getHostFunction(NapiClass_ConstructorFunction, ImplementationVisibility::Public, NapiClass_ConstructorFunction, name);
|
||||
auto* globalObject = toJS(env);
|
||||
Structure* structure = globalObject->NapiClassStructure();
|
||||
NapiClass* napiClass = new (NotNull, allocateCell<NapiClass>(vm)) NapiClass(vm, executable, globalObject, structure);
|
||||
NapiClass* napiClass = new (NotNull, allocateCell<NapiClass>(vm)) NapiClass(vm, executable, env, structure);
|
||||
napiClass->finishCreation(vm, executable, length, name, constructor, data, property_count, properties);
|
||||
return napiClass;
|
||||
}
|
||||
@@ -1880,7 +1900,7 @@ void NapiClass::finishCreation(VM& vm, NativeExecutable* executable, unsigned le
|
||||
{
|
||||
Base::finishCreation(vm, executable, length, name);
|
||||
ASSERT(inherits(info()));
|
||||
this->m_constructor = reinterpret_cast<CFFIFunction>(constructor);
|
||||
this->m_constructor = constructor;
|
||||
auto globalObject = reinterpret_cast<Zig::GlobalObject*>(this->globalObject());
|
||||
|
||||
this->putDirect(vm, vm.propertyNames->name, jsString(vm, name), JSC::PropertyAttribute::DontEnum | 0);
|
||||
@@ -1893,9 +1913,9 @@ void NapiClass::finishCreation(VM& vm, NativeExecutable* executable, unsigned le
|
||||
const napi_property_descriptor& property = properties[i];
|
||||
|
||||
if (property.attributes & napi_static) {
|
||||
defineNapiProperty(globalObject, this, nullptr, property, true, throwScope);
|
||||
defineNapiProperty(m_env, this, nullptr, property, true, throwScope);
|
||||
} else {
|
||||
defineNapiProperty(globalObject, prototype, nullptr, property, false, throwScope);
|
||||
defineNapiProperty(m_env, prototype, nullptr, property, false, throwScope);
|
||||
}
|
||||
|
||||
if (throwScope.exception())
|
||||
@@ -2004,7 +2024,7 @@ extern "C" napi_status napi_define_class(napi_env env,
|
||||
if (len == NAPI_AUTO_LENGTH) {
|
||||
len = strlen(utf8name);
|
||||
}
|
||||
NapiClass* napiClass = NapiClass::create(vm, globalObject, utf8name, len, constructor, data, property_count, properties);
|
||||
NapiClass* napiClass = NapiClass::create(vm, env, utf8name, len, constructor, data, property_count, properties);
|
||||
JSC::JSValue value = JSC::JSValue(napiClass);
|
||||
JSC::EnsureStillAliveScope ensureStillAlive1(value);
|
||||
if (data != nullptr) {
|
||||
@@ -2088,12 +2108,12 @@ extern "C" napi_status napi_create_external_buffer(napi_env env, size_t length,
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
|
||||
auto arrayBuffer = ArrayBuffer::createFromBytes({ reinterpret_cast<const uint8_t*>(data), length }, createSharedTask<void(void*)>([globalObject, finalize_hint, finalize_cb](void* p) {
|
||||
auto arrayBuffer = ArrayBuffer::createFromBytes({ reinterpret_cast<const uint8_t*>(data), length }, createSharedTask<void(void*)>([finalize_hint, finalize_cb, env](void* p) {
|
||||
#if NAPI_VERBOSE
|
||||
printf("[napi] buffer finalize_callback\n");
|
||||
#endif
|
||||
if (finalize_cb != nullptr) {
|
||||
finalize_cb(toNapi(globalObject), p, finalize_hint);
|
||||
finalize_cb(env, p, finalize_hint);
|
||||
}
|
||||
}));
|
||||
auto* subclassStructure = globalObject->JSBufferSubclassStructure();
|
||||
@@ -2116,12 +2136,12 @@ extern "C" napi_status napi_create_external_arraybuffer(napi_env env, void* exte
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
auto arrayBuffer = ArrayBuffer::createFromBytes({ reinterpret_cast<const uint8_t*>(external_data), byte_length }, createSharedTask<void(void*)>([globalObject, finalize_hint, finalize_cb](void* p) {
|
||||
auto arrayBuffer = ArrayBuffer::createFromBytes({ reinterpret_cast<const uint8_t*>(external_data), byte_length }, createSharedTask<void(void*)>([finalize_hint, finalize_cb, env](void* p) {
|
||||
#if NAPI_VERBOSE
|
||||
printf("[napi] arraybuffer finalize_callback\n");
|
||||
#endif
|
||||
if (finalize_cb != nullptr) {
|
||||
finalize_cb(toNapi(globalObject), p, finalize_hint);
|
||||
finalize_cb(env, p, finalize_hint);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -2393,7 +2413,7 @@ extern "C" napi_status napi_create_external(napi_env env, void* data,
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
|
||||
auto* structure = globalObject->NapiExternalStructure();
|
||||
JSValue value = Bun::NapiExternal::create(vm, structure, data, finalize_hint, reinterpret_cast<void*>(finalize_cb));
|
||||
JSValue value = Bun::NapiExternal::create(vm, structure, data, finalize_hint, env, reinterpret_cast<void*>(finalize_cb));
|
||||
JSC::EnsureStillAliveScope ensureStillAlive(value);
|
||||
*result = toNapi(value, globalObject);
|
||||
return napi_ok;
|
||||
@@ -2556,12 +2576,11 @@ extern "C" napi_status napi_get_instance_data(napi_env env,
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
if (UNLIKELY(data == nullptr)) {
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
|
||||
*data = globalObject->napiInstanceData;
|
||||
*data = env->getInstanceData();
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
@@ -2616,13 +2635,7 @@ extern "C" napi_status napi_set_instance_data(napi_env env,
|
||||
void* finalize_hint)
|
||||
{
|
||||
NAPI_PREMABLE
|
||||
|
||||
Zig::GlobalObject* globalObject = toJS(env);
|
||||
globalObject->napiInstanceData = data;
|
||||
|
||||
globalObject->napiInstanceDataFinalizer = reinterpret_cast<void*>(finalize_cb);
|
||||
globalObject->napiInstanceDataFinalizerHint = finalize_hint;
|
||||
|
||||
env->setInstanceData(data, finalize_cb, finalize_hint);
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
@@ -2824,3 +2837,8 @@ extern "C" napi_status napi_check_object_type_tag(napi_env env, napi_value value
|
||||
}
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
extern "C" JSGlobalObject* NapiEnv__globalObject(napi_env env)
|
||||
{
|
||||
return env->globalObject();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "headers-handwritten.h"
|
||||
#include "BunClientData.h"
|
||||
#include <JavaScriptCore/CallFrame.h>
|
||||
#include "js_native_api.h"
|
||||
#include "node_api.h"
|
||||
#include <JavaScriptCore/JSWeakValue.h>
|
||||
#include "JSFFIFunction.h"
|
||||
#include "ZigGlobalObject.h"
|
||||
@@ -22,6 +22,56 @@ namespace Napi {
|
||||
JSC::SourceCode generateSourceCode(WTF::String keyString, JSC::VM& vm, JSC::JSObject* object, JSC::JSGlobalObject* globalObject);
|
||||
}
|
||||
|
||||
struct napi_env__ {
|
||||
public:
|
||||
napi_env__(Zig::GlobalObject* globalObject, const napi_module& napiModule)
|
||||
: m_globalObject(globalObject)
|
||||
, m_napiModule(napiModule)
|
||||
{
|
||||
}
|
||||
|
||||
inline Zig::GlobalObject* globalObject() const { return m_globalObject; }
|
||||
inline const napi_module& napiModule() const { return m_napiModule; }
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
if (m_instanceDataFinalizer) {
|
||||
m_instanceDataFinalizer(this, m_instanceData, m_instanceDataFinalizerHint);
|
||||
}
|
||||
}
|
||||
|
||||
void setInstanceData(void* data, napi_finalize finalizer, void* hint)
|
||||
{
|
||||
m_instanceData = data;
|
||||
m_instanceDataFinalizer = finalizer;
|
||||
m_instanceDataFinalizerHint = hint;
|
||||
}
|
||||
|
||||
inline void* getInstanceData() const
|
||||
{
|
||||
return m_instanceData;
|
||||
}
|
||||
|
||||
// Almost all NAPI functions should set error_code to the status they're returning right before
|
||||
// they return it
|
||||
napi_extended_error_info m_lastNapiErrorInfo = {
|
||||
.error_message = "",
|
||||
// Not currently used by Bun -- always nullptr
|
||||
.engine_reserved = nullptr,
|
||||
// Not currently used by Bun -- always zero
|
||||
.engine_error_code = 0,
|
||||
.error_code = napi_ok,
|
||||
};
|
||||
|
||||
private:
|
||||
Zig::GlobalObject* m_globalObject = nullptr;
|
||||
napi_module m_napiModule;
|
||||
|
||||
void* m_instanceData = nullptr;
|
||||
napi_finalize m_instanceDataFinalizer = nullptr;
|
||||
void* m_instanceDataFinalizerHint = nullptr;
|
||||
};
|
||||
|
||||
namespace Zig {
|
||||
|
||||
using namespace JSC;
|
||||
@@ -33,7 +83,7 @@ static inline JSValue toJS(napi_value val)
|
||||
|
||||
static inline Zig::GlobalObject* toJS(napi_env val)
|
||||
{
|
||||
return reinterpret_cast<Zig::GlobalObject*>(val);
|
||||
return val->globalObject();
|
||||
}
|
||||
|
||||
static inline napi_value toNapi(JSC::JSValue val, Zig::GlobalObject* globalObject)
|
||||
@@ -46,17 +96,12 @@ static inline napi_value toNapi(JSC::JSValue val, Zig::GlobalObject* globalObjec
|
||||
return reinterpret_cast<napi_value>(JSC::JSValue::encode(val));
|
||||
}
|
||||
|
||||
static inline napi_env toNapi(JSC::JSGlobalObject* val)
|
||||
{
|
||||
return reinterpret_cast<napi_env>(val);
|
||||
}
|
||||
|
||||
class NapiFinalizer {
|
||||
public:
|
||||
void* finalize_hint = nullptr;
|
||||
napi_finalize finalize_cb;
|
||||
|
||||
void call(JSC::JSGlobalObject* globalObject, void* data);
|
||||
void call(napi_env env, void* data);
|
||||
};
|
||||
|
||||
// This is essentially JSC::JSWeakValue, except with a JSCell* instead of a
|
||||
@@ -147,12 +192,11 @@ public:
|
||||
void unref();
|
||||
void clear();
|
||||
|
||||
NapiRef(JSC::JSGlobalObject* global, uint32_t count)
|
||||
NapiRef(napi_env env, uint32_t count)
|
||||
: env(env)
|
||||
, globalObject(JSC::Weak<JSC::JSGlobalObject>(env->globalObject()))
|
||||
, refCount(count)
|
||||
{
|
||||
globalObject = JSC::Weak<JSC::JSGlobalObject>(global);
|
||||
strongRef = {};
|
||||
weakValueRef.clear();
|
||||
refCount = count;
|
||||
}
|
||||
|
||||
JSC::JSValue value() const
|
||||
@@ -172,6 +216,7 @@ public:
|
||||
weakValueRef.clear();
|
||||
}
|
||||
|
||||
napi_env env = nullptr;
|
||||
JSC::Weak<JSC::JSGlobalObject> globalObject;
|
||||
NapiWeakValue weakValueRef;
|
||||
JSC::Strong<JSC::Unknown> strongRef;
|
||||
@@ -210,7 +255,7 @@ public:
|
||||
|
||||
DECLARE_EXPORT_INFO;
|
||||
|
||||
JS_EXPORT_PRIVATE static NapiClass* create(VM&, Zig::GlobalObject*, const char* utf8name,
|
||||
JS_EXPORT_PRIVATE static NapiClass* create(VM&, napi_env, const char* utf8name,
|
||||
size_t length,
|
||||
napi_callback constructor,
|
||||
void* data,
|
||||
@@ -223,18 +268,22 @@ public:
|
||||
return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
|
||||
}
|
||||
|
||||
CFFIFunction constructor()
|
||||
napi_callback constructor()
|
||||
{
|
||||
return m_constructor;
|
||||
}
|
||||
|
||||
void* dataPtr = nullptr;
|
||||
CFFIFunction m_constructor = nullptr;
|
||||
napi_callback m_constructor = nullptr;
|
||||
NapiRef* napiRef = nullptr;
|
||||
napi_env m_env = nullptr;
|
||||
|
||||
inline napi_env env() const { return m_env; }
|
||||
|
||||
private:
|
||||
NapiClass(VM& vm, NativeExecutable* executable, JSC::JSGlobalObject* global, Structure* structure)
|
||||
: Base(vm, executable, global, structure)
|
||||
NapiClass(VM& vm, NativeExecutable* executable, napi_env env, Structure* structure)
|
||||
: Base(vm, executable, env->globalObject(), structure)
|
||||
, m_env(env)
|
||||
{
|
||||
}
|
||||
void finishCreation(VM&, NativeExecutable*, unsigned length, const String& name, napi_callback constructor,
|
||||
|
||||
@@ -5,10 +5,10 @@ namespace Bun {
|
||||
|
||||
NapiExternal::~NapiExternal()
|
||||
{
|
||||
if (finalizer) {
|
||||
if (m_finalizer) {
|
||||
// We cannot call globalObject() here because it is in a finalizer.
|
||||
// https://github.com/oven-sh/bun/issues/13001#issuecomment-2290022312
|
||||
reinterpret_cast<napi_finalize>(finalizer)(toNapi(this->napi_env), m_value, m_finalizerHint);
|
||||
reinterpret_cast<napi_finalize>(m_finalizer)(m_env, m_value, m_finalizerHint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include "BunBuiltinNames.h"
|
||||
#include "BunClientData.h"
|
||||
#include "napi.h"
|
||||
|
||||
namespace Bun {
|
||||
|
||||
@@ -47,11 +46,11 @@ public:
|
||||
JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
|
||||
}
|
||||
|
||||
static NapiExternal* create(JSC::VM& vm, JSC::Structure* structure, void* value, void* finalizer_hint, void* finalizer)
|
||||
static NapiExternal* create(JSC::VM& vm, JSC::Structure* structure, void* value, void* finalizer_hint, napi_env env, void* finalizer)
|
||||
{
|
||||
NapiExternal* accessor = new (NotNull, JSC::allocateCell<NapiExternal>(vm)) NapiExternal(vm, structure);
|
||||
|
||||
accessor->finishCreation(vm, value, finalizer_hint, finalizer);
|
||||
accessor->finishCreation(vm, value, finalizer_hint, env, finalizer);
|
||||
|
||||
#if BUN_DEBUG
|
||||
if (auto* callFrame = vm.topCallFrame) {
|
||||
@@ -75,23 +74,23 @@ public:
|
||||
return accessor;
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM& vm, void* value, void* finalizer_hint, void* finalizer)
|
||||
void finishCreation(JSC::VM& vm, void* value, void* finalizer_hint, napi_env env, void* finalizer)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
m_value = value;
|
||||
m_finalizerHint = finalizer_hint;
|
||||
napi_env = this->globalObject();
|
||||
this->finalizer = finalizer;
|
||||
m_env = env;
|
||||
m_finalizer = finalizer;
|
||||
}
|
||||
|
||||
static void destroy(JSC::JSCell* cell);
|
||||
|
||||
void* value() const { return m_value; }
|
||||
|
||||
void* m_value;
|
||||
void* m_finalizerHint;
|
||||
void* finalizer;
|
||||
JSGlobalObject* napi_env;
|
||||
void* m_value = nullptr;
|
||||
void* m_finalizerHint = nullptr;
|
||||
void* m_finalizer = nullptr;
|
||||
napi_env m_env = nullptr;
|
||||
|
||||
#if BUN_DEBUG
|
||||
String sourceOriginURL = String();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "napi_handle_scope.h"
|
||||
|
||||
#include "ZigGlobalObject.h"
|
||||
#include "napi.h"
|
||||
|
||||
namespace Bun {
|
||||
|
||||
@@ -127,19 +128,19 @@ NapiHandleScope::~NapiHandleScope()
|
||||
NapiHandleScope::close(m_globalObject, m_impl);
|
||||
}
|
||||
|
||||
extern "C" NapiHandleScopeImpl* NapiHandleScope__open(Zig::GlobalObject* globalObject, bool escapable)
|
||||
extern "C" NapiHandleScopeImpl* NapiHandleScope__open(napi_env env, bool escapable)
|
||||
{
|
||||
return NapiHandleScope::open(globalObject, escapable);
|
||||
return NapiHandleScope::open(env->globalObject(), escapable);
|
||||
}
|
||||
|
||||
extern "C" void NapiHandleScope__close(Zig::GlobalObject* globalObject, NapiHandleScopeImpl* current)
|
||||
extern "C" void NapiHandleScope__close(napi_env env, NapiHandleScopeImpl* current)
|
||||
{
|
||||
return NapiHandleScope::close(globalObject, current);
|
||||
return NapiHandleScope::close(env->globalObject(), current);
|
||||
}
|
||||
|
||||
extern "C" void NapiHandleScope__append(Zig::GlobalObject* globalObject, JSC::EncodedJSValue value)
|
||||
extern "C" void NapiHandleScope__append(napi_env env, JSC::EncodedJSValue value)
|
||||
{
|
||||
globalObject->m_currentNapiHandleScopeImpl.get()->append(JSC::JSValue::decode(value));
|
||||
env->globalObject()->m_currentNapiHandleScopeImpl.get()->append(JSC::JSValue::decode(value));
|
||||
}
|
||||
|
||||
extern "C" bool NapiHandleScope__escape(NapiHandleScopeImpl* handleScope, JSC::EncodedJSValue value)
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "BunClientData.h"
|
||||
#include "root.h"
|
||||
|
||||
typedef struct napi_env__* napi_env;
|
||||
|
||||
namespace Bun {
|
||||
|
||||
// An array of write barriers (so that newly-added objects are not lost by GC) to JSValues. Unlike
|
||||
@@ -80,14 +82,14 @@ private:
|
||||
};
|
||||
|
||||
// Create a new handle scope in the given environment
|
||||
extern "C" NapiHandleScopeImpl* NapiHandleScope__open(Zig::GlobalObject* globalObject, bool escapable);
|
||||
extern "C" NapiHandleScopeImpl* NapiHandleScope__open(napi_env env, bool escapable);
|
||||
|
||||
// Pop the most recently created handle scope in the given environment and restore the old one.
|
||||
// Asserts that `current` is the active handle scope.
|
||||
extern "C" void NapiHandleScope__close(Zig::GlobalObject* globalObject, NapiHandleScopeImpl* current);
|
||||
extern "C" void NapiHandleScope__close(napi_env env, NapiHandleScopeImpl* current);
|
||||
|
||||
// Store a value in the active handle scope in the given environment
|
||||
extern "C" void NapiHandleScope__append(Zig::GlobalObject* globalObject, JSC::EncodedJSValue value);
|
||||
extern "C" void NapiHandleScope__append(napi_env env, JSC::EncodedJSValue value);
|
||||
|
||||
// Put a value from the current handle scope into its escape slot reserved in the outer handle
|
||||
// scope. Returns false if the current handle scope is not escapable or if escape has already been
|
||||
|
||||
@@ -12,7 +12,7 @@ Local<External> External::New(Isolate* isolate, void* value)
|
||||
auto globalObject = isolate->globalObject();
|
||||
auto& vm = globalObject->vm();
|
||||
auto structure = globalObject->NapiExternalStructure();
|
||||
Bun::NapiExternal* val = Bun::NapiExternal::create(vm, structure, value, nullptr, nullptr);
|
||||
Bun::NapiExternal* val = Bun::NapiExternal::create(vm, structure, value, nullptr, nullptr, nullptr);
|
||||
return isolate->currentHandleScope()->createLocal<External>(vm, val);
|
||||
}
|
||||
|
||||
|
||||
1034
src/napi/napi.zig
1034
src/napi/napi.zig
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user