Compare commits

...

12 Commits

Author SHA1 Message Date
Kai Tamkun
93e622e782 Fix some warnings 2024-12-09 23:10:32 -08:00
Kai Tamkun
dac4c8623d Opt out of C++ warnings by default instead of opting in 2024-12-09 16:30:44 -08:00
Kai Tamkun
12de2d58c2 Don't use a random number 2024-12-09 15:09:12 -08:00
Kai Tamkun
4b97c78dff Undo changes to isolate usage 2024-12-09 15:00:51 -08:00
Kai Tamkun
f92e2d5d37 Add napi instance data test 2024-12-09 14:38:42 -08:00
Kai Tamkun
890fb04a09 Implement feedback 2024-12-06 18:56:30 -08:00
Kai Tamkun
f99d1bce54 Don't undef dlsym on Windows too early 2024-11-26 17:56:02 -08:00
Kai Tamkun
57a3f839e5 Move instance data to napi envs 2024-11-26 17:47:20 -08:00
Kai Tamkun
b98fe402be Make constructors work 2024-11-26 17:35:22 -08:00
Kai Tamkun
85499c8709 Splitting napi envs mostly works now, save for one napi test 2024-11-26 17:22:29 -08:00
Kai Tamkun
bfc423eeb9 More work on splitting napi envs 2024-11-26 16:08:01 -08:00
Kai Tamkun
9e9d137ca2 Initial work on splitting up napi envs 2024-11-26 14:42:32 -08:00
36 changed files with 879 additions and 489 deletions

View File

@@ -777,35 +777,22 @@ if(NOT WIN32)
endif()
target_compile_options(${bun} PUBLIC
-Werror=return-type
-Werror=return-stack-address
-Werror=implicit-function-declaration
-Werror=uninitialized
-Werror=conditional-uninitialized
-Werror=suspicious-memaccess
-Werror=int-conversion
-Werror=nonnull
-Werror=move
-Werror=sometimes-uninitialized
-Werror=unused
-Wall
-Wextra
-Wno-unused-function
-Wno-nullability-completeness
-Wno-unused-parameter
-Wno-sign-compare
-Werror
)
else()
# Leave -Werror=unused off in release builds so we avoid errors from being used in ASSERT
target_compile_options(${bun} PUBLIC ${LTO_FLAG}
-Werror=return-type
-Werror=return-stack-address
-Werror=implicit-function-declaration
-Werror=uninitialized
-Werror=conditional-uninitialized
-Werror=suspicious-memaccess
-Werror=int-conversion
-Werror=nonnull
-Werror=move
-Werror=sometimes-uninitialized
-Wall
-Wextra
-Wno-nullability-completeness
-Wno-unused-parameter
-Wno-sign-compare
-Werror
)
endif()

View File

@@ -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;
}
}
@@ -803,12 +805,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),
@@ -1129,6 +1133,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.?;
@@ -1148,7 +1155,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),
@@ -1240,6 +1247,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.?;
@@ -1253,7 +1262,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),
@@ -1562,7 +1571,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();
@@ -1585,7 +1594,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);
@@ -1694,7 +1705,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);
@@ -2553,3 +2566,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;
}

View File

@@ -30,11 +30,10 @@ RefPtr<JSC::SourceProvider> createBuiltinsSourceProvider();
JSHeapData::JSHeapData(Heap& heap)
: m_heapCellTypeForJSWorkerGlobalScope(JSC::IsoHeapCellType::Args<Zig::GlobalObject>())
, m_domBuiltinConstructorSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMBuiltinConstructorBase)
, m_domConstructorSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMConstructorBase)
, m_domNamespaceObjectSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMObject)
, m_subspaces(makeUnique<ExtendedDOMIsoSubspaces>())
, m_domConstructorSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMConstructorBase)
, m_domBuiltinConstructorSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMBuiltinConstructorBase)
, m_domNamespaceObjectSpace ISO_SUBSPACE_INIT(heap, heap.cellHeapCellType, JSDOMObject)
{
}
@@ -44,8 +43,8 @@ JSVMClientData::JSVMClientData(VM& vm, RefPtr<SourceProvider> sourceProvider)
: m_builtinNames(vm)
, m_builtinFunctions(vm, sourceProvider, m_builtinNames)
, m_heapData(JSHeapData::ensureHeapData(vm.heap))
, CLIENT_ISO_SUBSPACE_INIT(m_domBuiltinConstructorSpace)
, CLIENT_ISO_SUBSPACE_INIT(m_domConstructorSpace)
, CLIENT_ISO_SUBSPACE_INIT(m_domBuiltinConstructorSpace)
, CLIENT_ISO_SUBSPACE_INIT(m_domNamespaceObjectSpace)
, m_clientSubspaces(makeUnique<ExtendedDOMClientIsoSubspaces>())
{

View File

@@ -16,9 +16,9 @@ public:
using BunInspectorSocket = uWS::WebSocket<isSSL, true, BunInspectorConnection*>;
BunInspectorConnection(BunInspectorSocket* ws, JSC::JSGlobalObject* globalObject)
: ws(ws)
: pendingMessages()
, globalObject(globalObject)
, pendingMessages()
, ws(ws)
{
}

View File

@@ -394,22 +394,16 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
return JSValue::encode(jsUndefined());
}
JSC::EncodedJSValue (*napi_register_module_v1)(JSC::JSGlobalObject* globalObject,
JSC::EncodedJSValue exports);
napi_value (*napi_register_module_v1)(napi_env env, napi_value 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)>(
napi_register_module_v1 = reinterpret_cast<napi_value (*)(napi_env, napi_value)>(
dlsym(handle, "napi_register_module_v1"));
#if OS(WINDOWS)
#undef dlsym
#endif
if (!napi_register_module_v1) {
#if OS(WINDOWS)
FreeLibrary(handle);
@@ -420,10 +414,35 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
return {};
}
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
#endif
NapiHandleScope handleScope(globalObject);
int module_version = 8;
if (node_api_module_get_api_version_v1) {
module_version = node_api_module_get_api_version_v1();
}
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);
EncodedJSValue exportsValue = JSC::JSValue::encode(exports);
JSC::JSValue resultValue = JSValue::decode(napi_register_module_v1(globalObject, exportsValue));
JSC::JSValue resultValue = JSValue::decode(reinterpret_cast<EncodedJSValue>(napi_register_module_v1(env, reinterpret_cast<napi_value>(exportsValue))));
RETURN_IF_EXCEPTION(scope, {});

View File

@@ -117,10 +117,10 @@ BunString fromJS(JSC::JSGlobalObject* globalObject, JSValue value)
{
WTF::String str = value.toWTFString(globalObject);
if (UNLIKELY(str.isNull())) {
return { BunStringTag::Dead };
return { BunStringTag::Dead, { ZigStringEmpty } };
}
if (UNLIKELY(str.length() == 0)) {
return { BunStringTag::Empty };
return { BunStringTag::Empty, { ZigStringEmpty } };
}
auto impl = str.releaseImpl();
@@ -147,10 +147,10 @@ BunString toStringRef(JSC::JSGlobalObject* globalObject, JSValue value)
{
auto str = value.toWTFString(globalObject);
if (UNLIKELY(str.isNull())) {
return { BunStringTag::Dead };
return { BunStringTag::Dead, { ZigStringEmpty } };
}
if (UNLIKELY(str.length() == 0)) {
return { BunStringTag::Empty };
return { BunStringTag::Empty, { ZigStringEmpty } };
}
StringImpl* impl = str.impl();
@@ -163,21 +163,21 @@ BunString toStringRef(JSC::JSGlobalObject* globalObject, JSValue value)
BunString toString(WTF::String& wtfString)
{
if (wtfString.isEmpty())
return { BunStringTag::Empty };
return { BunStringTag::Empty, { ZigStringEmpty } };
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
}
BunString toString(const WTF::String& wtfString)
{
if (wtfString.isEmpty())
return { BunStringTag::Empty };
return { BunStringTag::Empty, { ZigStringEmpty } };
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
}
BunString toString(WTF::StringImpl* wtfString)
{
if (wtfString->isEmpty())
return { BunStringTag::Empty };
return { BunStringTag::Empty, { ZigStringEmpty } };
return { BunStringTag::WTFStringImpl, { .wtf = wtfString } };
}
@@ -185,7 +185,7 @@ BunString toString(WTF::StringImpl* wtfString)
BunString toStringRef(WTF::String& wtfString)
{
if (wtfString.isEmpty())
return { BunStringTag::Empty };
return { BunStringTag::Empty, { ZigStringEmpty } };
wtfString.impl()->ref();
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
@@ -193,7 +193,7 @@ BunString toStringRef(WTF::String& wtfString)
BunString toStringRef(const WTF::String& wtfString)
{
if (wtfString.isEmpty())
return { BunStringTag::Empty };
return { BunStringTag::Empty, { ZigStringEmpty } };
wtfString.impl()->ref();
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
@@ -201,7 +201,7 @@ BunString toStringRef(const WTF::String& wtfString)
BunString toStringRef(WTF::StringImpl* wtfString)
{
if (wtfString->isEmpty())
return { BunStringTag::Empty };
return { BunStringTag::Empty, { ZigStringEmpty } };
wtfString->ref();
@@ -229,7 +229,7 @@ extern "C" BunString BunString__fromUTF16Unitialized(size_t length)
UChar* ptr;
auto impl = WTF::StringImpl::tryCreateUninitialized(length, ptr);
if (UNLIKELY(!impl)) {
return { .tag = BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
}
return { BunStringTag::WTFStringImpl, { .wtf = impl.leakRef() } };
}
@@ -240,7 +240,7 @@ extern "C" BunString BunString__fromLatin1Unitialized(size_t length)
LChar* ptr;
auto impl = WTF::StringImpl::tryCreateUninitialized(length, ptr);
if (UNLIKELY(!impl)) {
return { .tag = BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
}
return { BunStringTag::WTFStringImpl, { .wtf = impl.leakRef() } };
}
@@ -253,7 +253,7 @@ extern "C" BunString BunString__fromUTF8(const char* bytes, size_t length)
UChar* ptr;
auto impl = WTF::StringImpl::tryCreateUninitialized(static_cast<unsigned int>(u16Length), ptr);
if (UNLIKELY(!impl)) {
return { .tag = BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
}
RELEASE_ASSERT(simdutf::convert_utf8_to_utf16(bytes, length, ptr) == u16Length);
impl->ref();
@@ -262,7 +262,7 @@ extern "C" BunString BunString__fromUTF8(const char* bytes, size_t length)
auto str = WTF::String::fromUTF8ReplacingInvalidSequences(std::span { reinterpret_cast<const LChar*>(bytes), length });
if (UNLIKELY(str.isNull())) {
return { .tag = BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
}
str.impl()->ref();
return Bun::toString(str);
@@ -274,7 +274,7 @@ extern "C" BunString BunString__fromLatin1(const char* bytes, size_t length)
LChar* ptr;
auto impl = WTF::StringImpl::tryCreateUninitialized(length, ptr);
if (UNLIKELY(!impl)) {
return { .tag = BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
}
memcpy(ptr, bytes, length);
@@ -289,7 +289,7 @@ extern "C" BunString BunString__fromUTF16ToLatin1(const char16_t* bytes, size_t
LChar* ptr = nullptr;
auto impl = WTF::StringImpl::tryCreateUninitialized(outLength, ptr);
if (UNLIKELY(!impl)) {
return { BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
}
size_t latin1_length = simdutf::convert_valid_utf16le_to_latin1(bytes, length, reinterpret_cast<char*>(ptr));
@@ -303,7 +303,7 @@ extern "C" BunString BunString__fromUTF16(const char16_t* bytes, size_t length)
UChar* ptr;
auto impl = WTF::StringImpl::tryCreateUninitialized(length, ptr);
if (UNLIKELY(!impl)) {
return { .tag = BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
}
memcpy(ptr, bytes, length * sizeof(char16_t));
return { BunStringTag::WTFStringImpl, { .wtf = impl.leakRef() } };
@@ -434,14 +434,14 @@ extern "C" BunString URL__getHrefFromJS(EncodedJSValue encodedValue, JSC::JSGlob
auto throwScope = DECLARE_THROW_SCOPE(globalObject->vm());
JSC::JSValue value = JSC::JSValue::decode(encodedValue);
auto str = value.toWTFString(globalObject);
RETURN_IF_EXCEPTION(throwScope, { BunStringTag::Dead });
RETURN_IF_EXCEPTION(throwScope, (BunString { BunStringTag::Dead, { Zig::ZigStringEmpty } }));
if (str.isEmpty()) {
return { BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
}
auto url = WTF::URL(str);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
return Bun::toStringRef(url.string());
}
@@ -451,7 +451,7 @@ extern "C" BunString URL__getHref(BunString* input)
auto&& str = input->toWTFString();
auto url = WTF::URL(str);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
return Bun::toStringRef(url.string());
}
@@ -461,7 +461,7 @@ extern "C" BunString URL__pathFromFileURL(BunString* input)
auto&& str = input->toWTFString();
auto url = WTF::URL(str);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
return Bun::toStringRef(url.fileSystemPath());
}
@@ -472,7 +472,7 @@ extern "C" BunString URL__getHrefJoin(BunString* baseStr, BunString* relativeStr
auto relative = relativeStr->toWTFString();
auto url = WTF::URL(WTF::URL(base), relative);
if (!url.isValid() || url.isEmpty())
return { BunStringTag::Dead };
return { BunStringTag::Dead, { Zig::ZigStringEmpty } };
return Bun::toStringRef(url.string());
}

View File

@@ -34,6 +34,7 @@
#include "JavaScriptCore/Synchronousness.h"
#include "JavaScriptCore/JSCast.h"
#include <JavaScriptCore/JSMapInlines.h>
#include "helpers.h"
#include "root.h"
#include "JavaScriptCore/SourceCode.h"
#include "headers-handwritten.h"
@@ -1028,7 +1029,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo
BunString specifierStr = Bun::toString(specifier);
BunString referrerStr = Bun::toString(referrer);
BunString typeAttributeStr = { BunStringTag::Dead };
BunString typeAttributeStr = { BunStringTag::Dead, { ZigStringEmpty } };
String typeAttribute = String();
// We need to be able to wire in the "type" import attribute from bundled code..

View File

@@ -40,8 +40,8 @@ void Bun__LifecycleAgentStopPreventingExit(Inspector::InspectorLifecycleAgent* a
InspectorLifecycleAgent::InspectorLifecycleAgent(JSC::JSGlobalObject& globalObject)
: InspectorAgentBase("LifecycleReporter"_s)
, m_globalObject(globalObject)
, m_backendDispatcher(LifecycleReporterBackendDispatcher::create(m_globalObject.inspectorController().backendDispatcher(), this))
, m_frontendDispatcher(makeUnique<LifecycleReporterFrontendDispatcher>(const_cast<FrontendRouter&>(m_globalObject.inspectorController().frontendRouter())))
, m_backendDispatcher(LifecycleReporterBackendDispatcher::create(m_globalObject.inspectorController().backendDispatcher(), this))
{
}

View File

@@ -68,8 +68,8 @@ void Bun__TestReporterAgentReportTestEnd(Inspector::InspectorTestReporterAgent*
InspectorTestReporterAgent::InspectorTestReporterAgent(JSC::JSGlobalObject& globalObject)
: InspectorAgentBase("TestReporter"_s)
, m_globalObject(globalObject)
, m_backendDispatcher(TestReporterBackendDispatcher::create(m_globalObject.inspectorController().backendDispatcher(), this))
, m_frontendDispatcher(makeUnique<TestReporterFrontendDispatcher>(const_cast<FrontendRouter&>(m_globalObject.inspectorController().frontendRouter())))
, m_backendDispatcher(TestReporterBackendDispatcher::create(m_globalObject.inspectorController().backendDispatcher(), this))
{
}

View File

@@ -1996,7 +1996,7 @@ JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocWithoutTypeChecks, JSUint8Array
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
IGNORE_WARNINGS_END
JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
return { allocBuffer(lexicalGlobalObject, byteLength) };
return { allocBuffer(lexicalGlobalObject, byteLength), nullptr };
}
JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int byteLength))
@@ -2006,7 +2006,7 @@ JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeWithoutTypeChecks, JSUint
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
IGNORE_WARNINGS_END
JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
return { allocBufferUnsafe(lexicalGlobalObject, byteLength) };
return { allocBufferUnsafe(lexicalGlobalObject, byteLength), nullptr };
}
JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeSlowWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int byteLength))
@@ -2016,7 +2016,7 @@ JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocUnsafeSlowWithoutTypeChecks, JS
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
IGNORE_WARNINGS_END
JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
return { allocBufferUnsafe(lexicalGlobalObject, byteLength) };
return { allocBufferUnsafe(lexicalGlobalObject, byteLength), nullptr };
}
JSC_ANNOTATE_HOST_FUNCTION(JSBufferConstructorConstruct, JSBufferConstructor::construct);

View File

@@ -78,7 +78,7 @@ public:
return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
}
const CFFIFunction function() const { return m_function; }
inline CFFIFunction function() const { return m_function; }
#if OS(WINDOWS)
@@ -86,14 +86,14 @@ public:
#endif
void* dataPtr;
void* dataPtr = nullptr;
private:
JSFFIFunction(VM&, NativeExecutable*, JSGlobalObject*, Structure*, CFFIFunction&&);
void finishCreation(VM&, NativeExecutable*, unsigned length, const String& name);
DECLARE_VISIT_CHILDREN;
CFFIFunction m_function;
CFFIFunction m_function = nullptr;
};
} // namespace JSC

View File

@@ -18,8 +18,8 @@ using namespace JSC;
class JSPropertyIterator {
public:
JSPropertyIterator(JSC::VM& m_vm, RefPtr<JSC::PropertyNameArrayData> m_properties)
: vm(m_vm)
, properties(m_properties)
: properties(m_properties)
, vm(m_vm)
{
}

View File

@@ -31,7 +31,7 @@ extern "C" SerializedValueSlice Bun__serializeJSValue(JSGlobalObject* globalObje
if (serialized.hasException()) {
WebCore::propagateException(*globalObject, scope,
serialized.releaseException());
RELEASE_AND_RETURN(scope, { 0 });
RELEASE_AND_RETURN(scope, (SerializedValueSlice { nullptr, 0, nullptr }));
}
auto serializedValue = serialized.releaseReturnValue();

View File

@@ -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"

View File

@@ -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__>, 0> 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;

View File

@@ -252,7 +252,7 @@ void SourceProvider::freeSourceCode()
void SourceProvider::updateCache(const UnlinkedFunctionExecutable* executable, const SourceCode&,
CodeSpecializationKind kind,
const UnlinkedFunctionCodeBlock* codeBlock)
const UnlinkedFunctionCodeBlock* codeBlock) const
{
// if (!m_resolvedSource.bytecodecache_fd || !m_cachedBytecode)
return;
@@ -263,7 +263,7 @@ void SourceProvider::updateCache(const UnlinkedFunctionExecutable* executable, c
m_cachedBytecode->addFunctionUpdate(executable, kind, *cachedBytecode);
}
void SourceProvider::cacheBytecode(const BytecodeCacheGenerator& generator)
void SourceProvider::cacheBytecode(const BytecodeCacheGenerator& generator) const
{
// if (!m_resolvedSource.bytecodecache_fd)
return;
@@ -275,7 +275,7 @@ void SourceProvider::cacheBytecode(const BytecodeCacheGenerator& generator)
m_cachedBytecode->addGlobalUpdate(*update);
}
void SourceProvider::commitCachedBytecode()
void SourceProvider::commitCachedBytecode() const
{
// if (!m_resolvedSource.bytecodecache_fd || !m_cachedBytecode || !m_cachedBytecode->hasUpdates())
return;

View File

@@ -51,9 +51,9 @@ public:
};
void updateCache(const UnlinkedFunctionExecutable* executable, const SourceCode&,
CodeSpecializationKind kind, const UnlinkedFunctionCodeBlock* codeBlock);
void cacheBytecode(const BytecodeCacheGenerator& generator);
void commitCachedBytecode();
CodeSpecializationKind kind, const UnlinkedFunctionCodeBlock* codeBlock) const final;
void cacheBytecode(const BytecodeCacheGenerator& generator) const final;
void commitCachedBytecode() const final;
bool isBytecodeCacheEnabled() const;
void readOrGenerateByteCodeCache(JSC::VM& vm, const JSC::SourceCode& sourceCode);
ResolvedSource m_resolvedSource;
@@ -73,7 +73,7 @@ private:
}
Zig::GlobalObject* m_globalObject;
RefPtr<JSC::CachedBytecode> m_cachedBytecode;
mutable RefPtr<JSC::CachedBytecode> m_cachedBytecode;
Ref<WTF::StringImpl> m_source;
unsigned m_hash = 0;
};

View File

@@ -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());
@@ -3519,6 +3520,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();
}

View File

@@ -1,12 +1,13 @@
#include "root.h"
typedef struct FFIFields {
struct FFIFields {
uint32_t JSArrayBufferView__offsetOfLength;
uint32_t JSArrayBufferView__offsetOfByteOffset;
uint32_t JSArrayBufferView__offsetOfVector;
uint32_t JSCell__offsetOfType;
} FFIFields;
extern "C" FFIFields Bun__FFI__offsets = { 0 };
};
FFIFields Bun__FFI__offsets = { 0, 0, 0, 0 };
extern "C" void Bun__FFI__ensureOffsetsAreLoaded()
{

View File

@@ -12,10 +12,10 @@ namespace WTF {
class String;
}
typedef struct ZigString {
struct ZigString {
const unsigned char* ptr;
size_t len;
} ZigString;
};
#ifndef __cplusplus
typedef uint8_t BunStringTag;
@@ -30,10 +30,10 @@ class StringImpl;
class String;
}
typedef union BunStringImpl {
union BunStringImpl {
ZigString zig;
WTF::StringImpl* wtf;
} BunStringImpl;
};
enum class BunStringTag : uint8_t {
Dead = 0,
@@ -44,7 +44,7 @@ enum class BunStringTag : uint8_t {
};
#endif
typedef struct BunString {
struct BunString {
BunStringTag tag;
BunStringImpl impl;
@@ -67,30 +67,29 @@ typedef struct BunString {
// This one usually will clone the raw bytes.
WTF::String toWTFString() const;
};
} BunString;
typedef struct ZigErrorType {
struct ZigErrorType {
ZigErrorCode code;
void* ptr;
} ZigErrorType;
typedef union ErrorableZigStringResult {
};
union ErrorableZigStringResult {
ZigString value;
ZigErrorType err;
} ErrorableZigStringResult;
typedef struct ErrorableZigString {
};
struct ErrorableZigString {
ErrorableZigStringResult result;
bool success;
} ErrorableZigString;
typedef union ErrorableStringResult {
};
union ErrorableStringResult {
BunString value;
ZigErrorType err;
} ErrorableStringResult;
typedef struct ErrorableString {
};
struct ErrorableString {
ErrorableStringResult result;
bool success;
} ErrorableString;
typedef struct ResolvedSource {
};
struct ResolvedSource {
BunString specifier;
BunString source_code;
BunString source_url;
@@ -103,25 +102,25 @@ typedef struct ResolvedSource {
bool already_bundled;
uint8_t* bytecode_cache;
size_t bytecode_cache_size;
} ResolvedSource;
};
static const uint32_t ResolvedSourceTagPackageJSONTypeModule = 1;
typedef union ErrorableResolvedSourceResult {
union ErrorableResolvedSourceResult {
ResolvedSource value;
ZigErrorType err;
} ErrorableResolvedSourceResult;
typedef struct ErrorableResolvedSource {
};
struct ErrorableResolvedSource {
ErrorableResolvedSourceResult result;
bool success;
} ErrorableResolvedSource;
};
typedef struct SystemError {
struct SystemError {
int errno_;
BunString code;
BunString message;
BunString path;
BunString syscall;
int fd;
} SystemError;
};
typedef void* ArrayBufferSink;
@@ -143,7 +142,7 @@ const ZigStackFrameCode ZigStackFrameCodeConstructor = 6;
extern "C" void __attribute((__noreturn__)) Bun__panic(const char* message, size_t length);
#define BUN_PANIC(message) Bun__panic(message, sizeof(message) - 1)
typedef struct ZigStackFramePosition {
struct ZigStackFramePosition {
int32_t line_zero_based;
int32_t column_zero_based;
int32_t byte_position;
@@ -156,17 +155,17 @@ typedef struct ZigStackFramePosition {
{
return OrdinalNumber::fromZeroBasedInt(this->line_zero_based);
}
} ZigStackFramePosition;
};
typedef struct ZigStackFrame {
struct ZigStackFrame {
BunString function_name;
BunString source_url;
ZigStackFramePosition position;
ZigStackFrameCode code_type;
bool remapped;
} ZigStackFrame;
};
typedef struct ZigStackTrace {
struct ZigStackTrace {
BunString* source_lines_ptr;
OrdinalNumber* source_lines_numbers;
uint8_t source_lines_len;
@@ -174,9 +173,9 @@ typedef struct ZigStackTrace {
ZigStackFrame* frames_ptr;
uint8_t frames_len;
JSC::SourceProvider* referenced_source_provider;
} ZigStackTrace;
};
typedef struct ZigException {
struct ZigException {
unsigned char code;
uint16_t runtime_type;
int errno_;
@@ -189,7 +188,7 @@ typedef struct ZigException {
void* exception;
bool remapped;
int fd;
} ZigException;
};
typedef uint8_t JSErrorCode;
const JSErrorCode JSErrorCodeError = 0;
@@ -254,10 +253,10 @@ const ReadableEvent ReadableEventUser = 254;
#ifndef STRING_POINTER
#define STRING_POINTER
typedef struct StringPointer {
struct StringPointer {
uint32_t off;
uint32_t len;
} StringPointer;
};
#endif
typedef void WebSocketHTTPClient;
@@ -268,9 +267,7 @@ typedef void WebSocketClientTLS;
#ifndef __cplusplus
typedef struct Bun__ArrayBuffer Bun__ArrayBuffer;
typedef struct Uint8Array_alias Uint8Array_alias;
#endif
#ifdef __cplusplus
#else
extern "C" void Bun__WTFStringImpl__deref(WTF::StringImpl* impl);
extern "C" void Bun__WTFStringImpl__ref(WTF::StringImpl* impl);
@@ -298,7 +295,7 @@ BunString toStringView(WTF::StringView view);
using Uint8Array_alias = JSC::JSUint8Array;
typedef struct {
struct Bun__ArrayBuffer {
char* ptr;
size_t offset;
size_t len;
@@ -306,7 +303,7 @@ typedef struct {
uint8_t cell_type;
int64_t _value;
bool shared;
} Bun__ArrayBuffer;
};
#include "SyntheticModuleType.h"

View File

@@ -206,11 +206,10 @@ static const JSC::JSValue toJSStringValueGC(ZigString str, JSC::JSGlobalObject*
return JSC::JSValue(toJSStringGC(str, global));
}
static const ZigString ZigStringEmpty = ZigString { (unsigned char*)"", 0 };
static const unsigned char __dot_char = '.';
static const ZigString ZigStringCwd = ZigString { &__dot_char, 1 };
static const BunString BunStringCwd = BunString { BunStringTag::StaticZigString, ZigStringCwd };
static const BunString BunStringEmpty = BunString { BunStringTag::Empty, nullptr };
static const ZigString ZigStringEmpty = ZigString { reinterpret_cast<const unsigned char*>(""), 0 };
static const ZigString ZigStringCwd = ZigString { reinterpret_cast<const unsigned char*>("."), 1 };
static const BunString BunStringCwd = BunString { BunStringTag::StaticZigString, { ZigStringCwd } };
static const BunString BunStringEmpty = BunString { BunStringTag::Empty, { ZigStringEmpty } };
static const unsigned char* taggedUTF16Ptr(const UChar* ptr)
{

View File

@@ -120,7 +120,7 @@ JSC::SourceCode generateSourceCode(WTF::String keyString, JSC::VM& vm, JSC::JSOb
static inline Zig::GlobalObject* defaultGlobalObject(napi_env env)
{
if (env) {
return defaultGlobalObject(toJS(env));
return defaultGlobalObject(env->globalObject());
}
return defaultGlobalObject();
@@ -135,7 +135,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 +146,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 +182,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 +432,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 +445,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 +501,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 +536,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 +551,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 +561,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 {
@@ -596,7 +597,7 @@ extern "C" napi_status napi_set_property(napi_env env, napi_value target,
return napi_object_expected;
}
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
auto* object = targetValue.toObject(globalObject);
@@ -636,7 +637,7 @@ extern "C" napi_status napi_has_property(napi_env env, napi_value object,
return napi_invalid_arg;
}
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
auto* target = toJS(object).toObject(globalObject);
@@ -690,7 +691,7 @@ extern "C" napi_status napi_get_property(napi_env env, napi_value object,
return napi_object_expected;
}
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
@@ -712,7 +713,7 @@ extern "C" napi_status napi_delete_property(napi_env env, napi_value object,
{
NAPI_PREMABLE
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
@@ -739,7 +740,7 @@ extern "C" napi_status napi_has_own_property(napi_env env, napi_value object,
return napi_invalid_arg;
}
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
@@ -760,7 +761,7 @@ extern "C" napi_status napi_set_named_property(napi_env env, napi_value object,
{
NAPI_PREMABLE
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
auto target = toJS(object).toObject(globalObject);
@@ -792,7 +793,7 @@ extern "C" napi_status napi_create_arraybuffer(napi_env env,
{
NAPI_PREMABLE
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
if (UNLIKELY(!globalObject || !result)) {
return napi_invalid_arg;
}
@@ -840,7 +841,7 @@ extern "C" napi_status napi_has_named_property(napi_env env, napi_value object,
return napi_invalid_arg;
}
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
@@ -866,7 +867,7 @@ extern "C" napi_status napi_get_named_property(napi_env env, napi_value object,
return napi_invalid_arg;
}
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
@@ -900,15 +901,15 @@ 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);
Zig::GlobalObject* globalObject = env->globalObject();
JSString* out = JSC::jsString(globalObject->vm(), WTF::String(impl));
ensureStillAliveHere(out);
@@ -937,16 +938,16 @@ 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);
Zig::GlobalObject* globalObject = env->globalObject();
JSString* out = JSC::jsString(globalObject->vm(), WTF::String(impl));
ensureStillAliveHere(out);
@@ -959,6 +960,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 +990,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 +1035,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 +1053,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);
@@ -1149,7 +1149,7 @@ extern "C" napi_status napi_create_function(napi_env env, const char* utf8name,
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
auto name = WTF::String();
@@ -1158,7 +1158,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);
@@ -1178,7 +1178,7 @@ extern "C" napi_status napi_get_cb_info(
NAPI_PREMABLE
JSC::CallFrame* callFrame = reinterpret_cast<JSC::CallFrame*>(cbinfo);
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
if (NAPICallFrame* frame = NAPICallFrame::get(callFrame).value_or(nullptr)) {
NAPICallFrame::extract(*frame, argc, argv, this_arg, data, globalObject);
@@ -1261,7 +1261,7 @@ napi_define_properties(napi_env env, napi_value object, size_t property_count,
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
JSC::JSValue objectValue = toJS(object);
@@ -1280,7 +1280,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);
}
@@ -1310,7 +1310,7 @@ static JSC::ErrorInstance* createErrorWithCode(JSC::JSGlobalObject* globalObject
// used to implement napi_throw_*_error
static napi_status throwErrorWithCStrings(napi_env env, const char* code_utf8, const char* msg_utf8, JSC::ErrorType type)
{
auto* globalObject = toJS(env);
auto* globalObject = env->globalObject();
auto& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -1340,7 +1340,7 @@ static napi_status createErrorWithNapiValues(napi_env env, napi_value code, napi
return napi_string_expected;
}
auto* globalObject = toJS(env);
auto* globalObject = env->globalObject();
auto wtf_code = js_code.isEmpty() ? WTF::String() : js_code.getString(globalObject);
auto wtf_message = js_message.getString(globalObject);
@@ -1375,9 +1375,9 @@ extern "C" napi_status napi_create_reference(napi_env env, napi_value value,
return napi_object_expected;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
auto* ref = new NapiRef(globalObject, initial_refcount);
auto* ref = new NapiRef(env, initial_refcount);
if (initial_refcount > 0) {
ref->strongRef.set(globalObject->vm(), val);
}
@@ -1409,7 +1409,7 @@ extern "C" napi_status napi_add_finalizer(napi_env env, napi_value js_object,
if (UNLIKELY(!env)) {
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
JSC::JSValue objectValue = toJS(js_object);
@@ -1455,7 +1455,7 @@ extern "C" napi_status napi_get_reference_value(napi_env env, napi_ref ref,
return napi_invalid_arg;
}
NapiRef* napiRef = toJS(ref);
*result = toNapi(napiRef->value(), toJS(env));
*result = toNapi(napiRef->value(), env->globalObject());
return napi_ok;
}
@@ -1523,7 +1523,7 @@ extern "C" napi_status napi_detach_arraybuffer(napi_env env,
napi_value arraybuffer)
{
NAPI_PREMABLE
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
JSC::JSArrayBuffer* jsArrayBuffer = JSC::jsDynamicCast<JSC::JSArrayBuffer*>(toJS(arraybuffer));
@@ -1553,9 +1553,9 @@ extern "C" napi_status napi_adjust_external_memory(napi_env env,
}
if (change_in_bytes > 0) {
toJS(env)->vm().heap.deprecatedReportExtraMemory(change_in_bytes);
env->globalObject()->vm().heap.deprecatedReportExtraMemory(change_in_bytes);
}
*adjusted_value = toJS(env)->vm().heap.extraMemorySize();
*adjusted_value = env->globalObject()->vm().heap.extraMemorySize();
return napi_ok;
}
@@ -1567,7 +1567,7 @@ extern "C" napi_status napi_is_exception_pending(napi_env env, bool* result)
return napi_invalid_arg;
}
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
*result = globalObject->vm().exceptionForInspection() != nullptr;
return napi_ok;
}
@@ -1580,7 +1580,7 @@ extern "C" napi_status napi_get_and_clear_last_exception(napi_env env,
return napi_invalid_arg;
}
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
if (scope.exception()) {
*result = toNapi(JSC::JSValue(scope.exception()->value()), globalObject);
@@ -1595,7 +1595,7 @@ extern "C" napi_status napi_fatal_exception(napi_env env,
napi_value err)
{
NAPI_PREMABLE
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
JSC::JSValue value = toJS(err);
JSC::JSObject* obj = value.getObject();
if (UNLIKELY(obj == nullptr || !obj->isErrorInstance())) {
@@ -1610,7 +1610,7 @@ extern "C" napi_status napi_fatal_exception(napi_env env,
extern "C" napi_status napi_throw(napi_env env, napi_value error)
{
NAPI_PREMABLE
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -1629,7 +1629,7 @@ extern "C" napi_status node_api_symbol_for(napi_env env,
size_t length, napi_value* result)
{
NAPI_PREMABLE
auto* globalObject = toJS(env);
auto* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
if (UNLIKELY(!result || !utf8description)) {
return napi_invalid_arg;
@@ -1694,7 +1694,7 @@ extern "C" napi_status napi_object_freeze(napi_env env, napi_value object_value)
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -1713,7 +1713,7 @@ extern "C" napi_status napi_object_freeze(napi_env env, napi_value object_value)
extern "C" napi_status napi_object_seal(napi_env env, napi_value object_value)
{
NAPI_PREMABLE
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -1739,7 +1739,7 @@ extern "C" napi_status napi_get_global(napi_env env, napi_value* result)
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
*result = toNapi(globalObject->globalThis(), globalObject);
return napi_ok;
}
@@ -1767,12 +1767,12 @@ extern "C" napi_status napi_get_new_target(napi_env env,
CallFrame* callFrame = reinterpret_cast<JSC::CallFrame*>(cbinfo);
if (NAPICallFrame* frame = NAPICallFrame::get(callFrame).value_or(nullptr)) {
*result = toNapi(frame->newTarget, toJS(env));
*result = toNapi(frame->newTarget, env->globalObject());
return napi_ok;
}
JSC::JSValue newTarget = callFrame->newTarget();
*result = toNapi(newTarget, toJS(env));
*result = toNapi(newTarget, env->globalObject());
return napi_ok;
}
@@ -1787,7 +1787,7 @@ extern "C" napi_status napi_create_dataview(napi_env env, size_t length,
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -1814,8 +1814,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 +1852,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 +1866,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 = env->globalObject();
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 +1880,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 +1893,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())
@@ -1929,7 +1929,7 @@ extern "C" napi_status napi_get_all_property_names(
jsc_property_mode = PropertyNameMode::Symbols;
}
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
auto objectValue = toJS(objectNapi);
auto* object = objectValue.getObject();
@@ -1954,7 +1954,7 @@ napi_get_last_error_info(napi_env env, const napi_extended_error_info** result)
return napi_invalid_arg;
}
auto globalObject = toJS(env);
auto globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
auto lastException = vm.lastException();
if (!lastException) {
@@ -1998,13 +1998,13 @@ extern "C" napi_status napi_define_class(napi_env env,
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
size_t len = length;
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) {
@@ -2023,7 +2023,7 @@ extern "C" napi_status napi_coerce_to_string(napi_env env, napi_value value,
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -2052,7 +2052,7 @@ extern "C" napi_status napi_get_property_names(napi_env env, napi_value object,
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
JSC::JSValue jsValue = toJS(object);
@@ -2086,14 +2086,14 @@ extern "C" napi_status napi_create_external_buffer(napi_env env, size_t length,
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
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();
@@ -2113,15 +2113,15 @@ extern "C" napi_status napi_create_external_arraybuffer(napi_env env, void* exte
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
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);
}
}));
@@ -2140,7 +2140,7 @@ extern "C" napi_status napi_create_double(napi_env env, double value,
return napi_invalid_arg;
}
*result = toNapi(jsDoubleNumber(value), toJS(env));
*result = toNapi(jsDoubleNumber(value), env->globalObject());
return napi_ok;
}
@@ -2149,7 +2149,7 @@ extern "C" napi_status napi_get_value_double(napi_env env, napi_value value,
{
NAPI_PREMABLE
auto* globalObject = toJS(env);
auto* globalObject = env->globalObject();
JSC::JSValue jsValue = toJS(value);
if (UNLIKELY(result == nullptr || !globalObject)) {
@@ -2173,7 +2173,7 @@ extern "C" napi_status napi_get_value_int32(napi_env env, napi_value value, int3
{
NAPI_PREMABLE
auto* globalObject = toJS(env);
auto* globalObject = env->globalObject();
JSC::JSValue jsValue = toJS(value);
if (UNLIKELY(result == nullptr || !globalObject)) {
@@ -2197,7 +2197,7 @@ extern "C" napi_status napi_get_value_uint32(napi_env env, napi_value value, uin
{
NAPI_PREMABLE
auto* globalObject = toJS(env);
auto* globalObject = env->globalObject();
JSC::JSValue jsValue = toJS(value);
if (UNLIKELY(result == nullptr || !globalObject)) {
@@ -2221,7 +2221,7 @@ extern "C" napi_status napi_get_value_int64(napi_env env, napi_value value, int6
{
NAPI_PREMABLE
auto* globalObject = toJS(env);
auto* globalObject = env->globalObject();
JSC::JSValue jsValue = toJS(value);
if (UNLIKELY(result == nullptr || !globalObject)) {
@@ -2258,7 +2258,7 @@ extern "C" napi_status napi_get_value_string_utf8(napi_env env,
{
NAPI_PREMABLE
JSGlobalObject* globalObject = toJS(env);
JSGlobalObject* globalObject = env->globalObject();
JSValue jsValue = toJS(napiValue);
if (!jsValue || !jsValue.isString()) {
@@ -2332,10 +2332,10 @@ extern "C" napi_status napi_get_element(napi_env env, napi_value objectValue,
JSObject* object = jsValue.getObject();
auto scope = DECLARE_THROW_SCOPE(object->vm());
JSValue element = object->getIndex(toJS(env), index);
JSValue element = object->getIndex(env->globalObject(), index);
RETURN_IF_EXCEPTION(scope, napi_generic_failure);
*result = toNapi(element, toJS(env));
*result = toNapi(element, env->globalObject());
return napi_ok;
}
@@ -2354,7 +2354,7 @@ extern "C" napi_status napi_delete_element(napi_env env, napi_value objectValue,
auto scope = DECLARE_THROW_SCOPE(object->vm());
if (LIKELY(result)) {
*result = JSObject::deletePropertyByIndex(object, toJS(env), index);
*result = JSObject::deletePropertyByIndex(object, env->globalObject(), index);
}
RETURN_IF_EXCEPTION(scope, napi_generic_failure);
@@ -2369,7 +2369,7 @@ extern "C" napi_status napi_create_object(napi_env env, napi_value* result)
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
JSValue value = JSValue(NapiPrototype::create(vm, globalObject->NapiPrototypeStructure()));
@@ -2389,11 +2389,11 @@ extern "C" napi_status napi_create_external(napi_env env, void* data,
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
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;
@@ -2550,18 +2550,16 @@ extern "C" napi_status napi_get_value_external(napi_env env, napi_value value,
return napi_ok;
}
// TODO: make this per addon instead of globally shared for ALL addons
extern "C" napi_status napi_get_instance_data(napi_env env,
void** data)
{
NAPI_PREMABLE
Zig::GlobalObject* globalObject = toJS(env);
if (UNLIKELY(data == nullptr)) {
return napi_invalid_arg;
}
*data = globalObject->napiInstanceData;
*data = env->getInstanceData();
return napi_ok;
}
@@ -2570,7 +2568,7 @@ extern "C" napi_status napi_run_script(napi_env env, napi_value script,
{
NAPI_PREMABLE
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
if (UNLIKELY(result == nullptr)) {
return napi_invalid_arg;
}
@@ -2616,13 +2614,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;
}
@@ -2638,7 +2630,7 @@ extern "C" napi_status napi_create_bigint_words(napi_env env,
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
auto* bigint = JSC::JSBigInt::tryCreateWithLength(vm, word_count);
if (UNLIKELY(!bigint)) {
@@ -2666,7 +2658,7 @@ extern "C" napi_status napi_create_symbol(napi_env env, napi_value description,
{
NAPI_PREMABLE
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
if (UNLIKELY(result == nullptr || globalObject == nullptr)) {
@@ -2705,7 +2697,7 @@ extern "C" napi_status napi_new_instance(napi_env env, napi_value constructor,
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -2738,7 +2730,7 @@ extern "C" napi_status napi_call_function(napi_env env, napi_value recv_napi,
{
NAPI_PREMABLE
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSC::VM& vm = globalObject->vm();
JSC::JSValue funcValue = toJS(func_napi);
@@ -2784,7 +2776,7 @@ extern "C" napi_status napi_type_tag_object(napi_env env, napi_value value, cons
if (!env || !value || !type_tag) {
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSObject* js_object = toJS(value).getObject();
if (!js_object) {
return napi_object_expected;
@@ -2808,7 +2800,7 @@ extern "C" napi_status napi_check_object_type_tag(napi_env env, napi_value value
if (!env || !value || !type_tag) {
return napi_invalid_arg;
}
Zig::GlobalObject* globalObject = toJS(env);
Zig::GlobalObject* globalObject = env->globalObject();
JSObject* js_object = toJS(value).getObject();
if (!js_object) {
return napi_object_expected;
@@ -2824,3 +2816,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();
}

View File

@@ -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,45 @@ 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;
}
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;
@@ -31,11 +70,6 @@ static inline JSValue toJS(napi_value val)
return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(val));
}
static inline Zig::GlobalObject* toJS(napi_env val)
{
return reinterpret_cast<Zig::GlobalObject*>(val);
}
static inline napi_value toNapi(JSC::JSValue val, Zig::GlobalObject* globalObject)
{
if (val.isCell()) {
@@ -46,17 +80,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 +176,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 +200,7 @@ public:
weakValueRef.clear();
}
napi_env env = nullptr;
JSC::Weak<JSC::JSGlobalObject> globalObject;
NapiWeakValue weakValueRef;
JSC::Strong<JSC::Unknown> strongRef;
@@ -210,7 +239,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 +252,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,

View File

@@ -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);
}
}

View File

@@ -1,11 +1,10 @@
#pragma once
#include "root.h"
#include "BunBuiltinNames.h"
#include "BunClientData.h"
#include "napi.h"
namespace Bun {
@@ -47,11 +46,12 @@ public:
JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
}
static NapiExternal* create(JSC::VM& vm, JSC::Structure* structure, void* value, void* finalizer_hint, void* finalizer)
// env is needed only if a finalizer is passed, otherwise it may be null
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 +75,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();

View File

@@ -1,6 +1,7 @@
#include "napi_handle_scope.h"
#include "ZigGlobalObject.h"
#include "napi.h"
namespace Bun {
@@ -117,8 +118,8 @@ void NapiHandleScope::close(Zig::GlobalObject* globalObject, NapiHandleScopeImpl
}
NapiHandleScope::NapiHandleScope(Zig::GlobalObject* globalObject)
: m_globalObject(globalObject)
, m_impl(NapiHandleScope::open(globalObject, false))
: m_impl(NapiHandleScope::open(globalObject, false))
, m_globalObject(globalObject)
{
}
@@ -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)

View File

@@ -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

View File

@@ -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);
}

View File

@@ -90,13 +90,13 @@ private:
void finishCreation(JSC::VM& vm);
GlobalInternals(JSC::VM& vm, JSC::Structure* structure, Zig::GlobalObject* globalObject)
: Base(vm, structure)
, m_globalObject(globalObject)
, m_currentHandleScope(nullptr)
, m_undefinedValue(Oddball::Kind::kUndefined)
, m_nullValue(Oddball::Kind::kNull)
, m_trueValue(Oddball::Kind::kTrue)
, m_falseValue(Oddball::Kind::kFalse)
, m_isolate(this)
, m_globalObject(globalObject)
{
}
};

View File

@@ -44,9 +44,9 @@ class PerformanceEntry : public RefCounted<PerformanceEntry> {
public:
virtual ~PerformanceEntry();
const String& name() const { return m_name; }
const double startTime() const { return m_startTime; }
const double duration() const { return m_duration; }
inline const String& name() const { return m_name; }
inline double startTime() const { return m_startTime; }
inline double duration() const { return m_duration; }
enum class Type : uint8_t {
Navigation = 1 << 0,

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,17 @@
"NAPI_DISABLE_CPP_EXCEPTIONS",
"NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT=1",
],
}
},
{
"target_name": "second_addon",
"sources": ["second_addon.c"],
"include_dirs": ["<!@(node -p \"require('node-addon-api').include\")"],
"libraries": [],
"dependencies": ["<!(node -p \"require('node-addon-api').gyp\")"],
"defines": [
"NAPI_DISABLE_CPP_EXCEPTIONS",
"NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT=1",
],
},
]
}

View File

@@ -1013,6 +1013,39 @@ static napi_value try_add_tag(const Napi::CallbackInfo &info) {
return Napi::Boolean::New(env, status == napi_ok);
}
// set_instance_data(number)
static napi_value set_instance_data(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
napi_value object = info[0];
static int32_t data;
assert(napi_get_value_int32(env, object, &data) == napi_ok);
assert(napi_set_instance_data(env, &data, nullptr, nullptr) == napi_ok);
return env.Undefined();
}
// get_instance_data(): number | null
static napi_value get_instance_data(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
void *data_ptr = nullptr;
assert(napi_get_instance_data(env, &data_ptr) == napi_ok);
if (data_ptr == nullptr) {
return env.Null();
}
napi_value out;
assert(napi_create_int32(env, *(int32_t *)data_ptr, &out) == napi_ok);
return out;
}
// reset_instance_data()
static napi_value reset_instance_data(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
assert(napi_set_instance_data(env, nullptr, nullptr, nullptr) == napi_ok);
return env.Undefined();
}
Napi::Value RunCallback(const Napi::CallbackInfo &info) {
Napi::Env env = info.Env();
// this function is invoked without the GC callback
@@ -1079,6 +1112,10 @@ Napi::Object InitAll(Napi::Env env, Napi::Object exports1) {
exports.Set("add_tag", Napi::Function::New(env, add_tag));
exports.Set("try_add_tag", Napi::Function::New(env, try_add_tag));
exports.Set("check_tag", Napi::Function::New(env, check_tag));
exports.Set("set_instance_data", Napi::Function::New(env, set_instance_data));
exports.Set("get_instance_data", Napi::Function::New(env, get_instance_data));
exports.Set("reset_instance_data",
Napi::Function::New(env, reset_instance_data));
return exports;
}

View File

@@ -1,4 +1,5 @@
const nativeTests = require("./build/Release/napitests.node");
const secondAddon = require("./build/Release/second_addon.node");
nativeTests.test_napi_class_constructor_handle_scope = () => {
const NapiClass = nativeTests.get_class_with_constructor();
@@ -270,4 +271,19 @@ nativeTests.test_type_tag = () => {
console.log("o2 matches o2:", nativeTests.check_tag(o2, 3, 4));
};
nativeTests.test_instance_data = () => {
const first_data = 1337;
const results = [];
results.push(nativeTests.get_instance_data() === null);
results.push(nativeTests.set_instance_data(first_data) === undefined);
results.push(nativeTests.get_instance_data() === first_data);
results.push(secondAddon.get_instance_data() === 42);
results.push(secondAddon.get_instance_data() !== nativeTests.get_instance_data());
console.log(results.join(" "));
nativeTests.reset_instance_data();
};
module.exports = nativeTests;

View File

@@ -0,0 +1,46 @@
#include <js_native_api.h>
#include <node_api.h>
#include <stdint.h>
#include <stdio.h>
#define NODE_API_CALL(env, call) \
do { \
napi_status status = (call); \
if (status != napi_ok) { \
const napi_extended_error_info *error_info = NULL; \
napi_get_last_error_info((env), &error_info); \
const char *err_message = error_info->error_message; \
bool is_pending; \
napi_is_exception_pending((env), &is_pending); \
/* If an exception is already pending, don't rethrow it */ \
if (!is_pending) { \
const char *message = \
(err_message == NULL) ? "empty error message" : err_message; \
napi_throw_error((env), NULL, message); \
} \
return NULL; \
} \
} while (0)
static napi_value get_instance_data(napi_env env, napi_callback_info info) {
void *data_ptr = NULL;
NODE_API_CALL(env, napi_get_instance_data(env, &data_ptr));
napi_value out;
NODE_API_CALL(env, napi_create_int32(env, *(int32_t *)data_ptr, &out));
return out;
}
/* napi_value */ NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) {
napi_value get_instance_data_function;
NODE_API_CALL(env, napi_create_function(env, "get_instance_data",
NAPI_AUTO_LENGTH, get_instance_data,
NULL, &get_instance_data_function));
NODE_API_CALL(env, napi_set_named_property(env, exports, "get_instance_data",
get_instance_data_function));
static int32_t instance_data = 42;
NODE_API_CALL(env, napi_set_instance_data(env, &instance_data, NULL, NULL));
return exports;
}

View File

@@ -319,6 +319,12 @@ describe("napi", () => {
checkSameOutput("test_type_tag", []);
});
});
describe("instance data", () => {
it("works with multiple envs", () => {
checkSameOutput("test_instance_data", []);
});
});
});
function checkSameOutput(test: string, args: any[] | string) {