diff options
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | src/api/schema.d.ts | 3 | ||||
-rw-r--r-- | src/api/schema.js | 4 | ||||
-rw-r--r-- | src/api/schema.peechy | 1 | ||||
-rw-r--r-- | src/api/schema.zig | 3 | ||||
-rw-r--r-- | src/bun_js.zig | 2 | ||||
-rw-r--r-- | src/bundler.zig | 2 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/JSFFIFunction.cpp | 2 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/JSFFIFunction.h | 2 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/Process.cpp | 57 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/ZigGlobalObject.cpp | 4 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/bindings.zig | 9 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/headers-cpp.h | 2 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/headers.h | 503 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/napi.cpp | 156 | ||||
-rw-r--r-- | src/javascript/jsc/javascript.zig | 19 | ||||
-rw-r--r-- | src/javascript/jsc/rare_data.zig | 6 | ||||
-rw-r--r-- | src/napi/napi.zig | 491 | ||||
-rw-r--r-- | src/options.zig | 66 | ||||
-rw-r--r-- | src/symbols.txt | 105 |
20 files changed, 1022 insertions, 424 deletions
@@ -210,7 +210,7 @@ LINUX_INCLUDE_DIRS := -I$(JSC_INCLUDE_DIR) \ UWS_INCLUDE_DIR := -I$(BUN_DEPS_DIR)/uws/uSockets/src -I$(BUN_DEPS_DIR)/uws/src -I$(BUN_DEPS_DIR) -INCLUDE_DIRS := $(UWS_INCLUDE_DIR) -I$(BUN_DEPS_DIR)/mimalloc/include +INCLUDE_DIRS := $(UWS_INCLUDE_DIR) -I$(BUN_DEPS_DIR)/mimalloc/include -Isrc/napi ifeq ($(OS_NAME),linux) @@ -345,7 +345,7 @@ BUN_LLD_FLAGS_WITHOUT_JSC = $(ARCHIVE_FILES) \ -BUN_LLD_FLAGS = $(BUN_LLD_FLAGS_WITHOUT_JSC) $(JSC_BINDINGS) ${ICU_FLAGS} +BUN_LLD_FLAGS = $(BUN_LLD_FLAGS_WITHOUT_JSC) $(JSC_BINDINGS) ${ICU_FLAGS} -exported_symbols_list $(realpath src/symbols.txt) CLANG_VERSION = $(shell $(CC) --version | awk '/version/ {for(i=1; i<=NF; i++){if($$i=="version"){split($$(i+1),v,".");print v[1]}}}') @@ -1127,6 +1127,7 @@ wasm-return1: +EMIT_LLVM_FOR_RELEASE= # We do this outside of build.zig for performance reasons # The C compilation stuff with build.zig is really slow and we don't need to run this as often as the rest @@ -1136,7 +1137,7 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(OPTIMIZATION_LEVEL) \ -fno-exceptions \ -ferror-limit=1000 \ - -emit-llvm \ + $(EMIT_LLVM_FOR_RELEASE) \ -g3 -c -o $@ $< $(OBJ_DIR)/%.o: $(SRC_DIR)/webcore/%.cpp @@ -1145,7 +1146,7 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/webcore/%.cpp $(OPTIMIZATION_LEVEL) \ -fno-exceptions \ -ferror-limit=1000 \ - -emit-llvm \ + $(EMIT_LLVM_FOR_RELEASE) \ -g3 -c -o $@ $< sizegen: diff --git a/src/api/schema.d.ts b/src/api/schema.d.ts index 1bc604beb..f2f6d5b8f 100644 --- a/src/api/schema.d.ts +++ b/src/api/schema.d.ts @@ -23,6 +23,7 @@ export const enum Loader { json = 7, toml = 8, wasm = 9, + napi = 10, } export const LoaderKeys: { 1: "jsx"; @@ -43,6 +44,8 @@ export const LoaderKeys: { toml: "toml"; 9: "wasm"; wasm: "wasm"; + 10: "napi"; + napi: "napi"; }; export const enum FrameworkEntryPointType { client = 1, diff --git a/src/api/schema.js b/src/api/schema.js index 2117e8c6d..1db65f2ca 100644 --- a/src/api/schema.js +++ b/src/api/schema.js @@ -8,6 +8,7 @@ const Loader = { 7: 7, 8: 8, 9: 9, + 10: 10, jsx: 1, js: 2, ts: 3, @@ -17,6 +18,7 @@ const Loader = { json: 7, toml: 8, wasm: 9, + napi: 10, }; const LoaderKeys = { 1: "jsx", @@ -28,6 +30,7 @@ const LoaderKeys = { 7: "json", 8: "toml", 9: "wasm", + 10: "napi", jsx: "jsx", js: "js", ts: "ts", @@ -37,6 +40,7 @@ const LoaderKeys = { json: "json", toml: "toml", wasm: "wasm", + napi: "napi", }; const FrameworkEntryPointType = { 1: 1, diff --git a/src/api/schema.peechy b/src/api/schema.peechy index 9dce08756..f9188987a 100644 --- a/src/api/schema.peechy +++ b/src/api/schema.peechy @@ -10,6 +10,7 @@ smol Loader { json = 7; toml = 8; wasm = 9; + napi = 10; } smol FrameworkEntryPointType { diff --git a/src/api/schema.zig b/src/api/schema.zig index bbec8a98c..f6837c58d 100644 --- a/src/api/schema.zig +++ b/src/api/schema.zig @@ -359,6 +359,9 @@ pub const Api = struct { /// wasm wasm, + /// napi + napi, + _, pub fn jsonStringify(self: *const @This(), opts: anytype, o: anytype) !void { diff --git a/src/bun_js.zig b/src/bun_js.zig index 69fe006c6..29f152049 100644 --- a/src/bun_js.zig +++ b/src/bun_js.zig @@ -161,6 +161,8 @@ pub const Run = struct { this.vm.onExit(); + if (!JSC.is_bindgen) JSC.napi.fixDeadCodeElimination(); + Global.exit(0); } }; diff --git a/src/bundler.zig b/src/bundler.zig index 3cfc91690..5b1f970bb 100644 --- a/src/bundler.zig +++ b/src/bundler.zig @@ -835,7 +835,7 @@ pub const Bundler = struct { output_file.value = .{ .move = file_op }; }, - .wasm, .file => { + .wasm, .file, .napi => { var hashed_name = try bundler.linker.getHashedFilename(file_path, null); var pathname = try bundler.allocator.alloc(u8, hashed_name.len + file_path.name.ext.len); std.mem.copy(u8, pathname, hashed_name); diff --git a/src/javascript/jsc/bindings/JSFFIFunction.cpp b/src/javascript/jsc/bindings/JSFFIFunction.cpp index 9e988a344..1f146350e 100644 --- a/src/javascript/jsc/bindings/JSFFIFunction.cpp +++ b/src/javascript/jsc/bindings/JSFFIFunction.cpp @@ -47,6 +47,8 @@ JSFFIFunction::JSFFIFunction(VM& vm, NativeExecutable* executable, JSGlobalObjec : Base(vm, executable, globalObject, structure) , m_function(WTFMove(function)) { + // used in NAPI + dataPtr = nullptr; } template<typename Visitor> diff --git a/src/javascript/jsc/bindings/JSFFIFunction.h b/src/javascript/jsc/bindings/JSFFIFunction.h index 421adc3ff..4d6818db8 100644 --- a/src/javascript/jsc/bindings/JSFFIFunction.h +++ b/src/javascript/jsc/bindings/JSFFIFunction.h @@ -74,6 +74,8 @@ public: const FFIFunction function() { return m_function; } + void* dataPtr; + private: JSFFIFunction(VM&, NativeExecutable*, JSGlobalObject*, Structure*, FFIFunction&&); void finishCreation(VM&, NativeExecutable*, unsigned length, const String& name); diff --git a/src/javascript/jsc/bindings/Process.cpp b/src/javascript/jsc/bindings/Process.cpp index 52e5909ec..a450c8a46 100644 --- a/src/javascript/jsc/bindings/Process.cpp +++ b/src/javascript/jsc/bindings/Process.cpp @@ -1,6 +1,8 @@ #include "Process.h" #include "JavaScriptCore/JSMicrotask.h" #include "JavaScriptCore/ObjectConstructor.h" +#include "node_api.h" +#include <dlfcn.h> #pragma mark - Node.js Process @@ -103,6 +105,54 @@ static JSC_DEFINE_HOST_FUNCTION(Process_functionNextTick, return JSC::JSValue::encode(JSC::jsUndefined()); } +static JSC_DECLARE_HOST_FUNCTION(Process_functionDlopen); +static JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen, + (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) +{ + auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); + JSC::VM& vm = globalObject->vm(); + + auto argCount = callFrame->argumentCount(); + if (argCount < 2) { + + JSC::throwTypeError(globalObject, scope, "dlopen requires 2 arguments"_s); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + JSC::JSValue moduleValue = callFrame->uncheckedArgument(0); + if (!moduleValue.isObject()) { + JSC::throwTypeError(globalObject, scope, "dlopen requires an object as first argument"_s); + return JSC::JSValue::encode(JSC::JSValue {}); + } + JSC::Identifier exportsSymbol = JSC::Identifier::fromString(vm, "exports"_s); + JSC::JSObject* exports = moduleValue.getObject()->getIfPropertyExists(globalObject, exportsSymbol).getObject(); + + WTF::String filename = callFrame->uncheckedArgument(1).toWTFString(globalObject); + CString utf8 = filename.utf8(); + void* handle = dlopen(utf8.data(), RTLD_LAZY); + + if (!handle) { + WTF::String msg = WTF::String::fromUTF8(dlerror()); + JSC::throwTypeError(globalObject, scope, msg); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + JSC::EncodedJSValue (*napi_register_module_v1)(JSC::JSGlobalObject * globalObject, + JSC::EncodedJSValue exports); + + napi_register_module_v1 = reinterpret_cast<JSC::EncodedJSValue (*)(JSC::JSGlobalObject*, + JSC::EncodedJSValue)>( + dlsym(handle, "napi_register_module_v1")); + + if (!napi_register_module_v1) { + dlclose(handle); + JSC::throwTypeError(globalObject, scope, "dlopen failed to napi_register_module_v1"_s); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + return napi_register_module_v1(globalObject, JSC::JSValue::encode(exports)); +} + static JSC_DECLARE_HOST_FUNCTION(Process_functionExit); static JSC_DEFINE_HOST_FUNCTION(Process_functionExit, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) @@ -164,10 +214,15 @@ void Process::finishCreation(JSC::VM& vm) static_cast<unsigned>(JSC::PropertyAttribute::CustomValue)); this->putDirect(vm, clientData->builtinNames().nextTickPublicName(), - JSC::JSFunction::create(vm, JSC::jsCast<JSC::JSGlobalObject*>(globalObject()), 0, + JSC::JSFunction::create(vm, JSC::jsCast<JSC::JSGlobalObject*>(globalObject()), 1, WTF::String("nextTick"), Process_functionNextTick), 0); + this->putDirect(vm, JSC::Identifier::fromString(vm, "dlopen"_s), + JSC::JSFunction::create(vm, JSC::jsCast<JSC::JSGlobalObject*>(globalObject()), 1, + WTF::String("dlopen"_s), Process_functionDlopen), + 0); + this->putDirect(vm, clientData->builtinNames().cwdPublicName(), JSC::JSFunction::create(vm, JSC::jsCast<JSC::JSGlobalObject*>(globalObject()), 0, WTF::String("cwd"), Process_functionCwd), diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp index 7bdc6ad61..fa712aee2 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp +++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp @@ -1132,6 +1132,10 @@ JSC::JSValue GlobalObject::moduleLoaderEvaluate(JSGlobalObject* globalObject, JSValue sentValue, JSValue resumeMode) { + if (UNLIKELY(scriptFetcher && scriptFetcher.isObject())) { + return scriptFetcher; + } + JSC::JSValue result = moduleLoader->evaluateNonVirtual(globalObject, key, moduleRecordValue, scriptFetcher, sentValue, resumeMode); diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig index a496ec174..9b6fb3e99 100644 --- a/src/javascript/jsc/bindings/bindings.zig +++ b/src/javascript/jsc/bindings/bindings.zig @@ -2285,7 +2285,7 @@ pub const JSValue = enum(u64) { if (this.isEmptyOrUndefinedOrNull()) return false; - return JSC.C.JSValueIsInstanceOfConstructor(global.ref(), this.asObjectRef(), constructor.ref(), null); + return JSC.C.JSValueIsInstanceOfConstructor(global.ref(), this.asObjectRef(), constructor.asObjectRef(), null); } pub fn jsType( @@ -2333,7 +2333,8 @@ pub const JSValue = enum(u64) { extern fn JSBuffer__isBuffer(*JSGlobalObject, JSValue) bool; pub fn isBuffer(value: JSValue, global: *JSGlobalObject) bool { - return JSBuffer__isBuffer(value, global); + if (comptime JSC.is_bindgen) unreachable; + return JSBuffer__isBuffer(global, value); } pub fn asCheckLoaded(value: JSValue, comptime ZigType: type) ?*ZigType { @@ -2367,7 +2368,7 @@ pub const JSValue = enum(u64) { } } - pub fn createBufferWithCtx(globalObject: *JSGlobalObject, slice: []u8, ptr: *anyopaque, func: JSC.C.JSTypedArrayBytesDeallocator) JSValue { + pub fn createBufferWithCtx(globalObject: *JSGlobalObject, slice: []u8, ptr: ?*anyopaque, func: JSC.C.JSTypedArrayBytesDeallocator) JSValue { if (comptime JSC.is_bindgen) unreachable; @setRuntimeSafety(false); return JSBuffer__bufferFromPointerAndLengthAndDeinit(globalObject, slice.ptr, slice.len, ptr, func); @@ -3568,6 +3569,8 @@ pub const WTF = struct { /// Encode a byte array to a URL-safe base64 string for use with JS /// Memory is managed by JavaScriptCore instead of us pub fn toBase64URLStringValue(bytes: []const u8, globalObject: *JSGlobalObject) JSValue { + if (comptime JSC.is_bindgen) unreachable; + return WTF__toBase64URLStringValue(bytes.ptr, bytes.len, globalObject); } }; diff --git a/src/javascript/jsc/bindings/headers-cpp.h b/src/javascript/jsc/bindings/headers-cpp.h index 76f4f90d7..1384e090a 100644 --- a/src/javascript/jsc/bindings/headers-cpp.h +++ b/src/javascript/jsc/bindings/headers-cpp.h @@ -1,4 +1,4 @@ -//-- AUTOGENERATED FILE -- 1651633421 +//-- AUTOGENERATED FILE -- 1651766047 // clang-format off #pragma once diff --git a/src/javascript/jsc/bindings/headers.h b/src/javascript/jsc/bindings/headers.h index e098ddd2e..0aab07b9e 100644 --- a/src/javascript/jsc/bindings/headers.h +++ b/src/javascript/jsc/bindings/headers.h @@ -1,5 +1,5 @@ // clang-format: off -//-- AUTOGENERATED FILE -- 1651633421 +//-- AUTOGENERATED FILE -- 1651766047 #pragma once #include <stddef.h> @@ -7,11 +7,11 @@ #include <stdbool.h> #ifdef __cplusplus -#define AUTO_EXTERN_C extern "C" -#define AUTO_EXTERN_C_ZIG extern "C" __attribute__((weak)) + #define AUTO_EXTERN_C extern "C" + #define AUTO_EXTERN_C_ZIG extern "C" __attribute__((weak)) #else -#define AUTO_EXTERN_C -#define AUTO_EXTERN_C_ZIG __attribute__((weak)) + #define AUTO_EXTERN_C + #define AUTO_EXTERN_C_ZIG __attribute__((weak)) #endif #define ZIG_DECL AUTO_EXTERN_C_ZIG #define CPP_DECL AUTO_EXTERN_C @@ -26,287 +26,240 @@ typedef void* JSClassRef; #include "JavaScriptCore/JSClassRef.h" #endif #include "headers-handwritten.h" -typedef struct bJSC__SourceCode { - unsigned char bytes[24]; -} bJSC__SourceCode; -typedef char* bJSC__SourceCode_buf; -typedef struct bWTF__URL { - unsigned char bytes[40]; -} bWTF__URL; -typedef char* bWTF__URL_buf; -typedef struct bJSC__JSModuleRecord { - unsigned char bytes[216]; -} bJSC__JSModuleRecord; -typedef char* bJSC__JSModuleRecord_buf; -typedef struct bJSC__ThrowScope { - unsigned char bytes[8]; -} bJSC__ThrowScope; -typedef char* bJSC__ThrowScope_buf; -typedef struct bJSC__CallFrame { - unsigned char bytes[8]; -} bJSC__CallFrame; -typedef char* bJSC__CallFrame_buf; -typedef struct bJSC__JSFunction { - unsigned char bytes[32]; -} bJSC__JSFunction; -typedef char* bJSC__JSFunction_buf; -typedef struct bJSC__PropertyName { - unsigned char bytes[8]; -} bJSC__PropertyName; -typedef char* bJSC__PropertyName_buf; -typedef struct bJSC__JSGlobalObject { - unsigned char bytes[2312]; -} bJSC__JSGlobalObject; -typedef char* bJSC__JSGlobalObject_buf; -typedef struct bJSC__JSCell { - unsigned char bytes[8]; -} bJSC__JSCell; -typedef char* bJSC__JSCell_buf; -typedef struct bJSC__CatchScope { - unsigned char bytes[8]; -} bJSC__CatchScope; -typedef char* bJSC__CatchScope_buf; -typedef struct bWTF__String { - unsigned char bytes[8]; -} bWTF__String; -typedef char* bWTF__String_buf; -typedef struct bWTF__StringView { - unsigned char bytes[16]; -} bWTF__StringView; -typedef char* bWTF__StringView_buf; -typedef struct bJSC__JSModuleLoader { - unsigned char bytes[16]; -} bJSC__JSModuleLoader; -typedef char* bJSC__JSModuleLoader_buf; -typedef struct bInspector__ScriptArguments { - unsigned char bytes[32]; -} bInspector__ScriptArguments; -typedef char* bInspector__ScriptArguments_buf; -typedef struct bJSC__Exception { - unsigned char bytes[40]; -} bJSC__Exception; -typedef char* bJSC__Exception_buf; -typedef struct bJSC__VM { - unsigned char bytes[52168]; -} bJSC__VM; -typedef char* bJSC__VM_buf; -typedef struct bJSC__JSString { - unsigned char bytes[16]; -} bJSC__JSString; -typedef char* bJSC__JSString_buf; -typedef struct bJSC__SourceOrigin { - unsigned char bytes[48]; -} bJSC__SourceOrigin; -typedef char* bJSC__SourceOrigin_buf; -typedef struct bWTF__ExternalStringImpl { - unsigned char bytes[40]; -} bWTF__ExternalStringImpl; -typedef char* bWTF__ExternalStringImpl_buf; -typedef struct bJSC__JSInternalPromise { - unsigned char bytes[32]; -} bJSC__JSInternalPromise; -typedef char* bJSC__JSInternalPromise_buf; -typedef struct bWTF__StringImpl { - unsigned char bytes[24]; -} bWTF__StringImpl; -typedef char* bWTF__StringImpl_buf; -typedef struct bJSC__JSPromise { - unsigned char bytes[32]; -} bJSC__JSPromise; -typedef char* bJSC__JSPromise_buf; -typedef struct bJSC__JSObject { - unsigned char bytes[16]; -} bJSC__JSObject; -typedef char* bJSC__JSObject_buf; -typedef struct bJSC__Identifier { - unsigned char bytes[8]; -} bJSC__Identifier; -typedef char* bJSC__Identifier_buf; + typedef struct bJSC__SourceCode { unsigned char bytes[24]; } bJSC__SourceCode; + typedef char* bJSC__SourceCode_buf; + typedef struct bWTF__URL { unsigned char bytes[40]; } bWTF__URL; + typedef char* bWTF__URL_buf; + typedef struct bJSC__JSModuleRecord { unsigned char bytes[216]; } bJSC__JSModuleRecord; + typedef char* bJSC__JSModuleRecord_buf; + typedef struct bJSC__ThrowScope { unsigned char bytes[8]; } bJSC__ThrowScope; + typedef char* bJSC__ThrowScope_buf; + typedef struct bJSC__CallFrame { unsigned char bytes[8]; } bJSC__CallFrame; + typedef char* bJSC__CallFrame_buf; + typedef struct bJSC__JSFunction { unsigned char bytes[32]; } bJSC__JSFunction; + typedef char* bJSC__JSFunction_buf; + typedef struct bJSC__PropertyName { unsigned char bytes[8]; } bJSC__PropertyName; + typedef char* bJSC__PropertyName_buf; + typedef struct bJSC__JSGlobalObject { unsigned char bytes[2312]; } bJSC__JSGlobalObject; + typedef char* bJSC__JSGlobalObject_buf; + typedef struct bJSC__JSCell { unsigned char bytes[8]; } bJSC__JSCell; + typedef char* bJSC__JSCell_buf; + typedef struct bJSC__CatchScope { unsigned char bytes[8]; } bJSC__CatchScope; + typedef char* bJSC__CatchScope_buf; + typedef struct bWTF__String { unsigned char bytes[8]; } bWTF__String; + typedef char* bWTF__String_buf; + typedef struct bWTF__StringView { unsigned char bytes[16]; } bWTF__StringView; + typedef char* bWTF__StringView_buf; + typedef struct bJSC__JSModuleLoader { unsigned char bytes[16]; } bJSC__JSModuleLoader; + typedef char* bJSC__JSModuleLoader_buf; + typedef struct bInspector__ScriptArguments { unsigned char bytes[32]; } bInspector__ScriptArguments; + typedef char* bInspector__ScriptArguments_buf; + typedef struct bJSC__Exception { unsigned char bytes[40]; } bJSC__Exception; + typedef char* bJSC__Exception_buf; + typedef struct bJSC__VM { unsigned char bytes[52168]; } bJSC__VM; + typedef char* bJSC__VM_buf; + typedef struct bJSC__JSString { unsigned char bytes[16]; } bJSC__JSString; + typedef char* bJSC__JSString_buf; + typedef struct bJSC__SourceOrigin { unsigned char bytes[48]; } bJSC__SourceOrigin; + typedef char* bJSC__SourceOrigin_buf; + typedef struct bWTF__ExternalStringImpl { unsigned char bytes[40]; } bWTF__ExternalStringImpl; + typedef char* bWTF__ExternalStringImpl_buf; + typedef struct bJSC__JSInternalPromise { unsigned char bytes[32]; } bJSC__JSInternalPromise; + typedef char* bJSC__JSInternalPromise_buf; + typedef struct bWTF__StringImpl { unsigned char bytes[24]; } bWTF__StringImpl; + typedef char* bWTF__StringImpl_buf; + typedef struct bJSC__JSPromise { unsigned char bytes[32]; } bJSC__JSPromise; + typedef char* bJSC__JSPromise_buf; + typedef struct bJSC__JSObject { unsigned char bytes[16]; } bJSC__JSObject; + typedef char* bJSC__JSObject_buf; + typedef struct bJSC__Identifier { unsigned char bytes[8]; } bJSC__Identifier; + typedef char* bJSC__Identifier_buf; #ifndef __cplusplus -typedef bJSC__CatchScope JSC__CatchScope; // JSC::CatchScope -typedef struct JSC__GeneratorPrototype JSC__GeneratorPrototype; // JSC::GeneratorPrototype -typedef struct JSC__ArrayIteratorPrototype JSC__ArrayIteratorPrototype; // JSC::ArrayIteratorPrototype -typedef ErrorableResolvedSource ErrorableResolvedSource; -typedef struct JSC__JSPromisePrototype JSC__JSPromisePrototype; // JSC::JSPromisePrototype -typedef ErrorableZigString ErrorableZigString; -typedef bJSC__PropertyName JSC__PropertyName; // JSC::PropertyName -typedef bJSC__JSObject JSC__JSObject; // JSC::JSObject -typedef bWTF__ExternalStringImpl WTF__ExternalStringImpl; // WTF::ExternalStringImpl -typedef struct JSC__AsyncIteratorPrototype JSC__AsyncIteratorPrototype; // JSC::AsyncIteratorPrototype -typedef bJSC__JSModuleLoader JSC__JSModuleLoader; // JSC::JSModuleLoader -typedef struct JSC__AsyncGeneratorPrototype JSC__AsyncGeneratorPrototype; // JSC::AsyncGeneratorPrototype -typedef struct JSC__AsyncGeneratorFunctionPrototype JSC__AsyncGeneratorFunctionPrototype; // JSC::AsyncGeneratorFunctionPrototype -typedef bJSC__Identifier JSC__Identifier; // JSC::Identifier -typedef struct JSC__ArrayPrototype JSC__ArrayPrototype; // JSC::ArrayPrototype -typedef struct Zig__JSMicrotaskCallback Zig__JSMicrotaskCallback; // Zig::JSMicrotaskCallback -typedef bJSC__JSPromise JSC__JSPromise; // JSC::JSPromise -typedef struct JSC__SetIteratorPrototype JSC__SetIteratorPrototype; // JSC::SetIteratorPrototype -typedef SystemError SystemError; -typedef bJSC__JSCell JSC__JSCell; // JSC::JSCell -typedef bJSC__SourceOrigin JSC__SourceOrigin; // JSC::SourceOrigin -typedef bJSC__JSModuleRecord JSC__JSModuleRecord; // JSC::JSModuleRecord -typedef bWTF__String WTF__String; // WTF::String -typedef bWTF__URL WTF__URL; // WTF::URL -typedef struct JSC__IteratorPrototype JSC__IteratorPrototype; // JSC::IteratorPrototype -typedef Bun__Readable Bun__Readable; -typedef bJSC__JSInternalPromise JSC__JSInternalPromise; // JSC::JSInternalPromise -typedef Bun__Writable Bun__Writable; -typedef struct JSC__MapIteratorPrototype JSC__MapIteratorPrototype; // JSC::MapIteratorPrototype -typedef struct JSC__RegExpPrototype JSC__RegExpPrototype; // JSC::RegExpPrototype -typedef bJSC__CallFrame JSC__CallFrame; // JSC::CallFrame -typedef struct WebCore__FetchHeaders WebCore__FetchHeaders; // WebCore::FetchHeaders -typedef bWTF__StringView WTF__StringView; // WTF::StringView -typedef bJSC__ThrowScope JSC__ThrowScope; // JSC::ThrowScope -typedef bWTF__StringImpl WTF__StringImpl; // WTF::StringImpl -typedef bJSC__VM JSC__VM; // JSC::VM -typedef JSClassRef JSClassRef; -typedef Bun__ArrayBuffer Bun__ArrayBuffer; -typedef bJSC__JSGlobalObject JSC__JSGlobalObject; // JSC::JSGlobalObject -typedef bJSC__JSFunction JSC__JSFunction; // JSC::JSFunction -typedef struct JSC__AsyncFunctionPrototype JSC__AsyncFunctionPrototype; // JSC::AsyncFunctionPrototype -typedef ZigException ZigException; -typedef bJSC__SourceCode JSC__SourceCode; // JSC::SourceCode -typedef uint64_t JSC__JSValue; -typedef struct JSC__BigIntPrototype JSC__BigIntPrototype; // JSC::BigIntPrototype -typedef struct JSC__GeneratorFunctionPrototype JSC__GeneratorFunctionPrototype; // JSC::GeneratorFunctionPrototype -typedef ZigString ZigString; -typedef struct WebCore__DOMURL WebCore__DOMURL; // WebCore::DOMURL -typedef struct JSC__FunctionPrototype JSC__FunctionPrototype; // JSC::FunctionPrototype -typedef bInspector__ScriptArguments Inspector__ScriptArguments; // Inspector::ScriptArguments -typedef bJSC__Exception JSC__Exception; // JSC::Exception -typedef bJSC__JSString JSC__JSString; // JSC::JSString -typedef struct JSC__ObjectPrototype JSC__ObjectPrototype; // JSC::ObjectPrototype -typedef struct JSC__StringPrototype JSC__StringPrototype; // JSC::StringPrototype + typedef bJSC__CatchScope JSC__CatchScope; // JSC::CatchScope + typedef struct JSC__GeneratorPrototype JSC__GeneratorPrototype; // JSC::GeneratorPrototype + typedef struct JSC__ArrayIteratorPrototype JSC__ArrayIteratorPrototype; // JSC::ArrayIteratorPrototype + typedef ErrorableResolvedSource ErrorableResolvedSource; + typedef struct JSC__JSPromisePrototype JSC__JSPromisePrototype; // JSC::JSPromisePrototype + typedef ErrorableZigString ErrorableZigString; + typedef bJSC__PropertyName JSC__PropertyName; // JSC::PropertyName + typedef bJSC__JSObject JSC__JSObject; // JSC::JSObject + typedef bWTF__ExternalStringImpl WTF__ExternalStringImpl; // WTF::ExternalStringImpl + typedef struct JSC__AsyncIteratorPrototype JSC__AsyncIteratorPrototype; // JSC::AsyncIteratorPrototype + typedef bJSC__JSModuleLoader JSC__JSModuleLoader; // JSC::JSModuleLoader + typedef struct JSC__AsyncGeneratorPrototype JSC__AsyncGeneratorPrototype; // JSC::AsyncGeneratorPrototype + typedef struct JSC__AsyncGeneratorFunctionPrototype JSC__AsyncGeneratorFunctionPrototype; // JSC::AsyncGeneratorFunctionPrototype + typedef bJSC__Identifier JSC__Identifier; // JSC::Identifier + typedef struct JSC__ArrayPrototype JSC__ArrayPrototype; // JSC::ArrayPrototype + typedef struct Zig__JSMicrotaskCallback Zig__JSMicrotaskCallback; // Zig::JSMicrotaskCallback + typedef bJSC__JSPromise JSC__JSPromise; // JSC::JSPromise + typedef struct JSC__SetIteratorPrototype JSC__SetIteratorPrototype; // JSC::SetIteratorPrototype + typedef SystemError SystemError; + typedef bJSC__JSCell JSC__JSCell; // JSC::JSCell + typedef bJSC__SourceOrigin JSC__SourceOrigin; // JSC::SourceOrigin + typedef bJSC__JSModuleRecord JSC__JSModuleRecord; // JSC::JSModuleRecord + typedef bWTF__String WTF__String; // WTF::String + typedef bWTF__URL WTF__URL; // WTF::URL + typedef struct JSC__IteratorPrototype JSC__IteratorPrototype; // JSC::IteratorPrototype + typedef Bun__Readable Bun__Readable; + typedef bJSC__JSInternalPromise JSC__JSInternalPromise; // JSC::JSInternalPromise + typedef Bun__Writable Bun__Writable; + typedef struct JSC__MapIteratorPrototype JSC__MapIteratorPrototype; // JSC::MapIteratorPrototype + typedef struct JSC__RegExpPrototype JSC__RegExpPrototype; // JSC::RegExpPrototype + typedef bJSC__CallFrame JSC__CallFrame; // JSC::CallFrame + typedef struct WebCore__FetchHeaders WebCore__FetchHeaders; // WebCore::FetchHeaders + typedef bWTF__StringView WTF__StringView; // WTF::StringView + typedef bJSC__ThrowScope JSC__ThrowScope; // JSC::ThrowScope + typedef bWTF__StringImpl WTF__StringImpl; // WTF::StringImpl + typedef bJSC__VM JSC__VM; // JSC::VM + typedef JSClassRef JSClassRef; + typedef Bun__ArrayBuffer Bun__ArrayBuffer; + typedef bJSC__JSGlobalObject JSC__JSGlobalObject; // JSC::JSGlobalObject + typedef bJSC__JSFunction JSC__JSFunction; // JSC::JSFunction + typedef struct JSC__AsyncFunctionPrototype JSC__AsyncFunctionPrototype; // JSC::AsyncFunctionPrototype + typedef ZigException ZigException; + typedef bJSC__SourceCode JSC__SourceCode; // JSC::SourceCode + typedef uint64_t JSC__JSValue; + typedef struct JSC__BigIntPrototype JSC__BigIntPrototype; // JSC::BigIntPrototype + typedef struct JSC__GeneratorFunctionPrototype JSC__GeneratorFunctionPrototype; // JSC::GeneratorFunctionPrototype + typedef ZigString ZigString; + typedef struct WebCore__DOMURL WebCore__DOMURL; // WebCore::DOMURL + typedef struct JSC__FunctionPrototype JSC__FunctionPrototype; // JSC::FunctionPrototype + typedef bInspector__ScriptArguments Inspector__ScriptArguments; // Inspector::ScriptArguments + typedef bJSC__Exception JSC__Exception; // JSC::Exception + typedef bJSC__JSString JSC__JSString; // JSC::JSString + typedef struct JSC__ObjectPrototype JSC__ObjectPrototype; // JSC::ObjectPrototype + typedef struct JSC__StringPrototype JSC__StringPrototype; // JSC::StringPrototype #endif #ifdef __cplusplus -namespace JSC { -class JSCell; -class Exception; -class JSPromisePrototype; -class StringPrototype; -class GeneratorFunctionPrototype; -class ArrayPrototype; -class JSString; -class JSObject; -class AsyncIteratorPrototype; -class AsyncGeneratorFunctionPrototype; -class Identifier; -class JSPromise; -class RegExpPrototype; -class AsyncFunctionPrototype; -class CatchScope; -class VM; -class BigIntPrototype; -class SourceOrigin; -class ThrowScope; -class SetIteratorPrototype; -class AsyncGeneratorPrototype; -class PropertyName; -class MapIteratorPrototype; -class JSModuleRecord; -class JSInternalPromise; -class ArrayIteratorPrototype; -class JSFunction; -class JSModuleLoader; -class GeneratorPrototype; -class JSGlobalObject; -class SourceCode; -class FunctionPrototype; -class IteratorPrototype; -class CallFrame; -class ObjectPrototype; -} -namespace WTF { -class URL; -class StringImpl; -class String; -class StringView; -class ExternalStringImpl; -} -namespace Zig { -class JSMicrotaskCallback; -} -namespace WebCore { -class DOMURL; -class FetchHeaders; -} -namespace Inspector { -class ScriptArguments; -} - -typedef ErrorableResolvedSource ErrorableResolvedSource; -typedef ErrorableZigString ErrorableZigString; -typedef SystemError SystemError; -typedef Bun__Readable Bun__Readable; -typedef Bun__Writable Bun__Writable; -typedef JSClassRef JSClassRef; -typedef Bun__ArrayBuffer Bun__ArrayBuffer; -typedef ZigException ZigException; -typedef uint64_t JSC__JSValue; -typedef ZigString ZigString; -using JSC__JSCell = JSC::JSCell; -using JSC__Exception = JSC::Exception; -using JSC__JSPromisePrototype = JSC::JSPromisePrototype; -using JSC__StringPrototype = JSC::StringPrototype; -using JSC__GeneratorFunctionPrototype = JSC::GeneratorFunctionPrototype; -using JSC__ArrayPrototype = JSC::ArrayPrototype; -using JSC__JSString = JSC::JSString; -using JSC__JSObject = JSC::JSObject; -using JSC__AsyncIteratorPrototype = JSC::AsyncIteratorPrototype; -using JSC__AsyncGeneratorFunctionPrototype = JSC::AsyncGeneratorFunctionPrototype; -using JSC__Identifier = JSC::Identifier; -using JSC__JSPromise = JSC::JSPromise; -using JSC__RegExpPrototype = JSC::RegExpPrototype; -using JSC__AsyncFunctionPrototype = JSC::AsyncFunctionPrototype; -using JSC__CatchScope = JSC::CatchScope; -using JSC__VM = JSC::VM; -using JSC__BigIntPrototype = JSC::BigIntPrototype; -using JSC__SourceOrigin = JSC::SourceOrigin; -using JSC__ThrowScope = JSC::ThrowScope; -using JSC__SetIteratorPrototype = JSC::SetIteratorPrototype; -using JSC__AsyncGeneratorPrototype = JSC::AsyncGeneratorPrototype; -using JSC__PropertyName = JSC::PropertyName; -using JSC__MapIteratorPrototype = JSC::MapIteratorPrototype; -using JSC__JSModuleRecord = JSC::JSModuleRecord; -using JSC__JSInternalPromise = JSC::JSInternalPromise; -using JSC__ArrayIteratorPrototype = JSC::ArrayIteratorPrototype; -using JSC__JSFunction = JSC::JSFunction; -using JSC__JSModuleLoader = JSC::JSModuleLoader; -using JSC__GeneratorPrototype = JSC::GeneratorPrototype; -using JSC__JSGlobalObject = JSC::JSGlobalObject; -using JSC__SourceCode = JSC::SourceCode; -using JSC__FunctionPrototype = JSC::FunctionPrototype; -using JSC__IteratorPrototype = JSC::IteratorPrototype; -using JSC__CallFrame = JSC::CallFrame; -using JSC__ObjectPrototype = JSC::ObjectPrototype; -using WTF__URL = WTF::URL; -using WTF__StringImpl = WTF::StringImpl; -using WTF__String = WTF::String; -using WTF__StringView = WTF::StringView; -using WTF__ExternalStringImpl = WTF::ExternalStringImpl; -using Zig__JSMicrotaskCallback = Zig::JSMicrotaskCallback; -using WebCore__DOMURL = WebCore::DOMURL; -using WebCore__FetchHeaders = WebCore::FetchHeaders; -using Inspector__ScriptArguments = Inspector::ScriptArguments; + namespace JSC { + class JSCell; + class Exception; + class JSPromisePrototype; + class StringPrototype; + class GeneratorFunctionPrototype; + class ArrayPrototype; + class JSString; + class JSObject; + class AsyncIteratorPrototype; + class AsyncGeneratorFunctionPrototype; + class Identifier; + class JSPromise; + class RegExpPrototype; + class AsyncFunctionPrototype; + class CatchScope; + class VM; + class BigIntPrototype; + class SourceOrigin; + class ThrowScope; + class SetIteratorPrototype; + class AsyncGeneratorPrototype; + class PropertyName; + class MapIteratorPrototype; + class JSModuleRecord; + class JSInternalPromise; + class ArrayIteratorPrototype; + class JSFunction; + class JSModuleLoader; + class GeneratorPrototype; + class JSGlobalObject; + class SourceCode; + class FunctionPrototype; + class IteratorPrototype; + class CallFrame; + class ObjectPrototype; + } + namespace WTF { + class URL; + class StringImpl; + class String; + class StringView; + class ExternalStringImpl; + } + namespace Zig { + class JSMicrotaskCallback; + } + namespace WebCore { + class DOMURL; + class FetchHeaders; + } + namespace Inspector { + class ScriptArguments; + } + + typedef ErrorableResolvedSource ErrorableResolvedSource; + typedef ErrorableZigString ErrorableZigString; + typedef SystemError SystemError; + typedef Bun__Readable Bun__Readable; + typedef Bun__Writable Bun__Writable; + typedef JSClassRef JSClassRef; + typedef Bun__ArrayBuffer Bun__ArrayBuffer; + typedef ZigException ZigException; + typedef uint64_t JSC__JSValue; + typedef ZigString ZigString; + using JSC__JSCell = JSC::JSCell; + using JSC__Exception = JSC::Exception; + using JSC__JSPromisePrototype = JSC::JSPromisePrototype; + using JSC__StringPrototype = JSC::StringPrototype; + using JSC__GeneratorFunctionPrototype = JSC::GeneratorFunctionPrototype; + using JSC__ArrayPrototype = JSC::ArrayPrototype; + using JSC__JSString = JSC::JSString; + using JSC__JSObject = JSC::JSObject; + using JSC__AsyncIteratorPrototype = JSC::AsyncIteratorPrototype; + using JSC__AsyncGeneratorFunctionPrototype = JSC::AsyncGeneratorFunctionPrototype; + using JSC__Identifier = JSC::Identifier; + using JSC__JSPromise = JSC::JSPromise; + using JSC__RegExpPrototype = JSC::RegExpPrototype; + using JSC__AsyncFunctionPrototype = JSC::AsyncFunctionPrototype; + using JSC__CatchScope = JSC::CatchScope; + using JSC__VM = JSC::VM; + using JSC__BigIntPrototype = JSC::BigIntPrototype; + using JSC__SourceOrigin = JSC::SourceOrigin; + using JSC__ThrowScope = JSC::ThrowScope; + using JSC__SetIteratorPrototype = JSC::SetIteratorPrototype; + using JSC__AsyncGeneratorPrototype = JSC::AsyncGeneratorPrototype; + using JSC__PropertyName = JSC::PropertyName; + using JSC__MapIteratorPrototype = JSC::MapIteratorPrototype; + using JSC__JSModuleRecord = JSC::JSModuleRecord; + using JSC__JSInternalPromise = JSC::JSInternalPromise; + using JSC__ArrayIteratorPrototype = JSC::ArrayIteratorPrototype; + using JSC__JSFunction = JSC::JSFunction; + using JSC__JSModuleLoader = JSC::JSModuleLoader; + using JSC__GeneratorPrototype = JSC::GeneratorPrototype; + using JSC__JSGlobalObject = JSC::JSGlobalObject; + using JSC__SourceCode = JSC::SourceCode; + using JSC__FunctionPrototype = JSC::FunctionPrototype; + using JSC__IteratorPrototype = JSC::IteratorPrototype; + using JSC__CallFrame = JSC::CallFrame; + using JSC__ObjectPrototype = JSC::ObjectPrototype; + using WTF__URL = WTF::URL; + using WTF__StringImpl = WTF::StringImpl; + using WTF__String = WTF::String; + using WTF__StringView = WTF::StringView; + using WTF__ExternalStringImpl = WTF::ExternalStringImpl; + using Zig__JSMicrotaskCallback = Zig::JSMicrotaskCallback; + using WebCore__DOMURL = WebCore::DOMURL; + using WebCore__FetchHeaders = WebCore::FetchHeaders; + using Inspector__ScriptArguments = Inspector::ScriptArguments; #endif + #pragma mark - JSC::JSObject -CPP_DECL JSC__JSValue JSC__JSObject__create(JSC__JSGlobalObject* arg0, size_t arg1, void* arg2, void (*ArgFn3)(void* arg0, JSC__JSObject* arg1, JSC__JSGlobalObject* arg2)); +CPP_DECL JSC__JSValue JSC__JSObject__create(JSC__JSGlobalObject* arg0, size_t arg1, void* arg2, void (* ArgFn3)(void* arg0, JSC__JSObject* arg1, JSC__JSGlobalObject* arg2)); CPP_DECL size_t JSC__JSObject__getArrayLength(JSC__JSObject* arg0); CPP_DECL JSC__JSValue JSC__JSObject__getDirect(JSC__JSObject* arg0, JSC__JSGlobalObject* arg1, const ZigString* arg2); CPP_DECL JSC__JSValue JSC__JSObject__getIndex(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, uint32_t arg2); CPP_DECL void JSC__JSObject__putRecord(JSC__JSObject* arg0, JSC__JSGlobalObject* arg1, ZigString* arg2, ZigString* arg3, size_t arg4); -CPP_DECL JSC__JSValue ZigString__external(const ZigString* arg0, JSC__JSGlobalObject* arg1, void* arg2, void (*ArgFn3)(void* arg0, void* arg1, size_t arg2)); +CPP_DECL JSC__JSValue ZigString__external(const ZigString* arg0, JSC__JSGlobalObject* arg1, void* arg2, void (* ArgFn3)(void* arg0, void* arg1, size_t arg2)); CPP_DECL JSC__JSValue ZigString__to16BitValue(const ZigString* arg0, JSC__JSGlobalObject* arg1); CPP_DECL JSC__JSValue ZigString__toErrorInstance(const ZigString* arg0, JSC__JSGlobalObject* arg1); CPP_DECL JSC__JSValue ZigString__toExternalU16(const uint16_t* arg0, size_t arg1, JSC__JSGlobalObject* arg2); CPP_DECL JSC__JSValue ZigString__toExternalValue(const ZigString* arg0, JSC__JSGlobalObject* arg1); -CPP_DECL JSC__JSValue ZigString__toExternalValueWithCallback(const ZigString* arg0, JSC__JSGlobalObject* arg1, void (*ArgFn2)(void* arg0, void* arg1, size_t arg2)); +CPP_DECL JSC__JSValue ZigString__toExternalValueWithCallback(const ZigString* arg0, JSC__JSGlobalObject* arg1, void (* ArgFn2)(void* arg0, void* arg1, size_t arg2)); CPP_DECL JSC__JSValue ZigString__toValue(const ZigString* arg0, JSC__JSGlobalObject* arg1); CPP_DECL JSC__JSValue ZigString__toValueGC(const ZigString* arg0, JSC__JSGlobalObject* arg1); CPP_DECL WebCore__DOMURL* WebCore__DOMURL__cast_(JSC__JSValue JSValue0, JSC__VM* arg1); @@ -422,7 +375,7 @@ CPP_DECL JSC__JSValue JSC__JSFunction__constructWithArguments(JSC__JSValue JSVal CPP_DECL JSC__JSValue JSC__JSFunction__constructWithArgumentsAndNewTarget(JSC__JSValue JSValue0, JSC__JSValue JSValue1, JSC__JSGlobalObject* arg2, JSC__JSValue* arg3, size_t arg4, JSC__Exception** arg5, const unsigned char* arg6); CPP_DECL JSC__JSValue JSC__JSFunction__constructWithNewTarget(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, JSC__JSValue JSValue2, JSC__Exception** arg3, const unsigned char* arg4); CPP_DECL JSC__JSValue JSC__JSFunction__constructWithoutAnyArgumentsOrNewTarget(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, JSC__Exception** arg2, const unsigned char* arg3); -CPP_DECL JSC__JSFunction* JSC__JSFunction__createFromNative(JSC__JSGlobalObject* arg0, uint16_t arg1, const WTF__String* arg2, void* arg3, JSC__JSValue (*ArgFn4)(void* arg0, JSC__JSGlobalObject* arg1, JSC__CallFrame* arg2)); +CPP_DECL JSC__JSFunction* JSC__JSFunction__createFromNative(JSC__JSGlobalObject* arg0, uint16_t arg1, const WTF__String* arg2, void* arg3, JSC__JSValue (* ArgFn4)(void* arg0, JSC__JSGlobalObject* arg1, JSC__CallFrame* arg2)); CPP_DECL bWTF__String JSC__JSFunction__displayName(JSC__JSFunction* arg0, JSC__VM* arg1); CPP_DECL bWTF__String JSC__JSFunction__getName(JSC__JSFunction* arg0, JSC__VM* arg1); @@ -509,7 +462,7 @@ CPP_DECL size_t WTF__String__length(WTF__String* arg0); #pragma mark - JSC::JSValue -CPP_DECL void JSC__JSValue___then(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, void* arg2, void (*ArgFn3)(JSC__JSGlobalObject* arg0, void* arg1, JSC__JSValue JSValue2, size_t arg3), void (*ArgFn4)(JSC__JSGlobalObject* arg0, void* arg1, JSC__JSValue JSValue2, size_t arg3)); +CPP_DECL void JSC__JSValue___then(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, void* arg2, void (* ArgFn3)(JSC__JSGlobalObject* arg0, void* arg1, JSC__JSValue JSValue2, size_t arg3), void (* ArgFn4)(JSC__JSGlobalObject* arg0, void* arg1, JSC__JSValue JSValue2, size_t arg3)); CPP_DECL bool JSC__JSValue__asArrayBuffer_(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, Bun__ArrayBuffer* arg2); CPP_DECL JSC__JSCell* JSC__JSValue__asCell(JSC__JSValue JSValue0); CPP_DECL JSC__JSInternalPromise* JSC__JSValue__asInternalPromise(JSC__JSValue JSValue0); @@ -526,7 +479,7 @@ CPP_DECL JSC__JSValue JSC__JSValue__createStringArray(JSC__JSGlobalObject* arg0, CPP_DECL JSC__JSValue JSC__JSValue__createTypeError(const ZigString* arg0, const ZigString* arg1, JSC__JSGlobalObject* arg2); CPP_DECL bool JSC__JSValue__eqlCell(JSC__JSValue JSValue0, JSC__JSCell* arg1); CPP_DECL bool JSC__JSValue__eqlValue(JSC__JSValue JSValue0, JSC__JSValue JSValue1); -CPP_DECL void JSC__JSValue__forEach(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, void* arg2, void (*ArgFn3)(JSC__VM* arg0, JSC__JSGlobalObject* arg1, void* arg2, JSC__JSValue JSValue3)); +CPP_DECL void JSC__JSValue__forEach(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, void* arg2, void (* ArgFn3)(JSC__VM* arg0, JSC__JSGlobalObject* arg1, void* arg2, JSC__JSValue JSValue3)); CPP_DECL JSC__JSValue JSC__JSValue__fromEntries(JSC__JSGlobalObject* arg0, ZigString* arg1, ZigString* arg2, size_t arg3, bool arg4); CPP_DECL JSC__JSValue JSC__JSValue__fromInt64NoTruncate(JSC__JSGlobalObject* arg0, int64_t arg1); CPP_DECL JSC__JSValue JSC__JSValue__fromUInt64NoTruncate(JSC__JSGlobalObject* arg0, uint64_t arg1); @@ -613,13 +566,13 @@ CPP_DECL JSC__JSValue JSC__Exception__value(JSC__Exception* arg0); CPP_DECL void JSC__VM__clearExecutionTimeLimit(JSC__VM* arg0); CPP_DECL JSC__VM* JSC__VM__create(unsigned char HeapType0); -CPP_DECL void JSC__VM__deferGC(JSC__VM* arg0, void* arg1, void (*ArgFn2)(void* arg0)); +CPP_DECL void JSC__VM__deferGC(JSC__VM* arg0, void* arg1, void (* ArgFn2)(void* arg0)); CPP_DECL void JSC__VM__deinit(JSC__VM* arg0, JSC__JSGlobalObject* arg1); CPP_DECL void JSC__VM__deleteAllCode(JSC__VM* arg0, JSC__JSGlobalObject* arg1); CPP_DECL void JSC__VM__doWork(JSC__VM* arg0); CPP_DECL void JSC__VM__drainMicrotasks(JSC__VM* arg0); CPP_DECL bool JSC__VM__executionForbidden(JSC__VM* arg0); -CPP_DECL void JSC__VM__holdAPILock(JSC__VM* arg0, void* arg1, void (*ArgFn2)(void* arg0)); +CPP_DECL void JSC__VM__holdAPILock(JSC__VM* arg0, void* arg1, void (* ArgFn2)(void* arg0)); CPP_DECL bool JSC__VM__isEntered(JSC__VM* arg0); CPP_DECL bool JSC__VM__isJITEnabled(); CPP_DECL JSC__JSValue JSC__VM__runGC(JSC__VM* arg0, bool arg1); @@ -627,7 +580,7 @@ CPP_DECL void JSC__VM__setExecutionForbidden(JSC__VM* arg0, bool arg1); CPP_DECL void JSC__VM__setExecutionTimeLimit(JSC__VM* arg0, double arg1); CPP_DECL void JSC__VM__shrinkFootprint(JSC__VM* arg0); CPP_DECL bool JSC__VM__throwError(JSC__VM* arg0, JSC__JSGlobalObject* arg1, JSC__ThrowScope* arg2, const unsigned char* arg3, size_t arg4); -CPP_DECL void JSC__VM__whenIdle(JSC__VM* arg0, void (*ArgFn1)()); +CPP_DECL void JSC__VM__whenIdle(JSC__VM* arg0, void (* ArgFn1)()); #pragma mark - JSC::ThrowScope @@ -685,7 +638,7 @@ CPP_DECL size_t WTF__StringImpl__length(const WTF__StringImpl* arg0); CPP_DECL const uint16_t* WTF__ExternalStringImpl__characters16(const WTF__ExternalStringImpl* arg0); CPP_DECL const unsigned char* WTF__ExternalStringImpl__characters8(const WTF__ExternalStringImpl* arg0); -CPP_DECL bWTF__ExternalStringImpl WTF__ExternalStringImpl__create(const unsigned char* arg0, size_t arg1, void (*ArgFn2)(void* arg0, unsigned char* arg1, size_t arg2)); +CPP_DECL bWTF__ExternalStringImpl WTF__ExternalStringImpl__create(const unsigned char* arg0, size_t arg1, void (* ArgFn2)(void* arg0, unsigned char* arg1, size_t arg2)); CPP_DECL bool WTF__ExternalStringImpl__is16Bit(const WTF__ExternalStringImpl* arg0); CPP_DECL bool WTF__ExternalStringImpl__is8Bit(const WTF__ExternalStringImpl* arg0); CPP_DECL bool WTF__ExternalStringImpl__isEmpty(const WTF__ExternalStringImpl* arg0); @@ -797,6 +750,7 @@ CPP_DECL ZigException ZigException__fromException(JSC__Exception* arg0); #pragma mark - Zig::ConsoleClient + #ifdef __cplusplus ZIG_DECL void Zig__ConsoleClient__count(void* arg0, JSC__JSGlobalObject* arg1, const unsigned char* arg2, size_t arg3); @@ -817,6 +771,7 @@ ZIG_DECL void Zig__ConsoleClient__timeStamp(void* arg0, JSC__JSGlobalObject* arg #pragma mark - Bun__Timer + #ifdef __cplusplus ZIG_DECL JSC__JSValue Bun__Timer__clearInterval(JSC__JSGlobalObject* arg0, JSC__JSValue JSValue1); diff --git a/src/javascript/jsc/bindings/napi.cpp b/src/javascript/jsc/bindings/napi.cpp new file mode 100644 index 000000000..0c47d1a63 --- /dev/null +++ b/src/javascript/jsc/bindings/napi.cpp @@ -0,0 +1,156 @@ + +#include "node_api.h" +#include "root.h" +#include "ZigGlobalObject.h" +#include "helpers.h" +#include "JavaScriptCore/JSObjectInlines.h" +#include "JavaScriptCore/JSCellInlines.h" +#include "wtf/text/ExternalStringImpl.h" +#include "wtf/text/StringCommon.h" +#include "wtf/text/StringImpl.h" +#include "JavaScriptCore/JSMicrotask.h" +#include "JavaScriptCore/ObjectConstructor.h" +#include "JavaScriptCore/JSModuleLoader.h" +#include "wtf/text/StringView.h" +#include "wtf/text/StringBuilder.h" +#include "wtf/text/WTFString.h" + +#include "JavaScriptCore/AggregateError.h" +#include "JavaScriptCore/BytecodeIndex.h" +#include "JavaScriptCore/CallFrame.h" +#include "JavaScriptCore/CallFrameInlines.h" +#include "JavaScriptCore/ClassInfo.h" +#include "JavaScriptCore/CodeBlock.h" +#include "JavaScriptCore/CodeCache.h" +#include "JavaScriptCore/Completion.h" +#include "JavaScriptCore/Error.h" +#include "JavaScriptCore/ErrorInstance.h" +#include "JavaScriptCore/Exception.h" +#include "JavaScriptCore/ExceptionScope.h" +#include "JavaScriptCore/FunctionConstructor.h" +#include "JavaScriptCore/HashMapImpl.h" +#include "JavaScriptCore/HashMapImplInlines.h" +#include "JavaScriptCore/Heap.h" +#include "JavaScriptCore/Identifier.h" +#include "JavaScriptCore/InitializeThreading.h" +#include "JavaScriptCore/IteratorOperations.h" +#include "JavaScriptCore/JSArray.h" +#include "JavaScriptCore/JSInternalPromise.h" +#include "JavaScriptCore/ObjectConstructor.h" +#include "JSFFIFunction.h" + +#include <iostream> +using namespace JSC; + +// namespace Napi { +// class Reference +// } + +extern "C" Zig::GlobalObject* Bun__getDefaultGlobal(); + +extern "C" void napi_module_register(napi_module* mod) +{ + + auto* globalObject = Bun__getDefaultGlobal(); + JSC::VM& vm = globalObject->vm(); + JSC::JSObject* object = JSC::constructEmptyObject(globalObject); + auto result = reinterpret_cast<JSC::EncodedJSValue>( + mod->nm_register_func(reinterpret_cast<napi_env>(globalObject), reinterpret_cast<napi_value>(JSC::JSValue::encode(JSC::JSValue(object))))); + + auto keyString = WTF::String::fromUTF8(mod->nm_modname); + JSC::JSString* key = JSC::jsString(vm, keyString); + + JSC::JSArray* exportKeys = ownPropertyKeys(globalObject, object, PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Include, std::nullopt); + auto symbol = vm.symbolRegistry().symbolForKey("__BunTemporaryGlobal"_s); + JSC::Identifier ident = JSC::Identifier::fromUid(symbol); + WTF::StringBuilder sourceCodeBuilder = WTF::StringBuilder(); + // TODO: handle symbol collision + sourceCodeBuilder.append("var $$TempSymbol = Symbol.for('__BunTemporaryGlobal'), $$NativeModule = globalThis[$$TempSymbol]; globalThis[$$TempSymbol] = null;\n if (!$$NativeModule) { throw new Error('Assertion failure: Native module not found'); }\n\n"_s); + + for (unsigned i = 0; i < exportKeys->length(); i++) { + auto key = exportKeys->getIndexQuickly(i); + if (key.isSymbol()) { + continue; + } + auto keyString = key.toWTFString(globalObject); + sourceCodeBuilder.append(""_s); + // TODO: handle invalid identifiers + sourceCodeBuilder.append("export var "_s); + sourceCodeBuilder.append(keyString); + sourceCodeBuilder.append(" = $$NativeModule."_s); + sourceCodeBuilder.append(keyString); + sourceCodeBuilder.append(";\n"_s); + } + auto sourceCode = JSC::makeSource(sourceCodeBuilder.toString(), JSC::SourceOrigin(), keyString, WTF::TextPosition(), JSC::SourceProviderSourceType::Module); + globalObject->putDirect(vm, ident, object, JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::DontEnum); + globalObject->moduleLoader()->provideFetch(globalObject, key, WTFMove(sourceCode)); + auto promise = globalObject->moduleLoader()->loadAndEvaluateModule(globalObject, key, jsUndefined(), jsUndefined()); + vm.drainMicrotasks(); + promise->result(vm); +} + +extern "C" napi_status napi_create_function(napi_env env, const char* utf8name, + size_t length, napi_callback cb, + void* data, napi_value* result) +{ + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(env); + JSC::VM& vm = globalObject->vm(); + auto name = WTF::String::fromUTF8(utf8name, length); + // std::cout << "napi_create_function: " << utf8name << std::endl; + auto function = Zig::JSFFIFunction::create(vm, globalObject, 1, name, reinterpret_cast<Zig::FFIFunction>(cb)); + function->dataPtr = data; + JSC::JSValue functionValue = JSC::JSValue(function); + *reinterpret_cast<JSC::EncodedJSValue*>(result) = JSC::JSValue::encode(functionValue); + return napi_ok; +} + +extern "C" napi_status napi_get_cb_info( + napi_env env, // [in] NAPI environment handle + napi_callback_info cbinfo, // [in] Opaque callback-info handle + size_t* argc, // [in-out] Specifies the size of the provided argv array + // and receives the actual count of args. + napi_value* argv, // [out] Array of values + napi_value* this_arg, // [out] Receives the JS 'this' arg for the call + void** data) +{ + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(env); + JSC::VM& vm = globalObject->vm(); + JSC::CallFrame* callFrame = reinterpret_cast<JSC::CallFrame*>(cbinfo); + JSC::JSValue thisValue = callFrame->thisValue(); + *argc = callFrame->argumentCount(); + *reinterpret_cast<JSC::EncodedJSValue**>(argv) = reinterpret_cast<JSC::EncodedJSValue*>(callFrame->addressOfArgumentsStart()); + if (thisValue && this_arg != nullptr) { + *this_arg = reinterpret_cast<napi_value>(JSC::JSValue::encode(thisValue)); + } + + Zig::JSFFIFunction* ffiFunction = JSC::jsDynamicCast<Zig::JSFFIFunction*>(vm, JSC::JSValue(callFrame->jsCallee())); + if (data != nullptr) + *data = reinterpret_cast<void*>(ffiFunction->dataPtr); + return napi_ok; +} + +extern "C" napi_status napi_throw_error(napi_env env, + const char* code, + const char* msg) +{ + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(env); + + JSC::VM& vm = globalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + + auto message = WTF::String::fromUTF8(msg); + auto error = JSC::createError(globalObject, message); + JSC::throwException(globalObject, throwScope, error); + return napi_ok; +} + +extern "C" napi_status napi_create_reference(napi_env env, napi_value value, + uint32_t initial_refcount, + napi_ref* result) +{ + + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(env); + JSC::Strong<JSC::Unknown> data = { globalObject->vm(), JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(value)) }; + *reinterpret_cast<JSC::Strong<JSC::Unknown>*>(result) = data; + return napi_ok; +}
\ No newline at end of file diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig index c193f5090..494e212e0 100644 --- a/src/javascript/jsc/javascript.zig +++ b/src/javascript/jsc/javascript.zig @@ -84,7 +84,7 @@ const Config = @import("./config.zig"); const URL = @import("../../url.zig").URL; const Transpiler = @import("./api/transpiler.zig"); const Bun = JSC.API.Bun; - +const ThreadSafeFunction = JSC.napi.ThreadSafeFunction; pub const GlobalConstructors = [_]type{ WebCore.Blob.Constructor, WebCore.TextDecoder.Constructor, @@ -358,6 +358,7 @@ pub const Task = TaggedPointerUnion(.{ WriteFileTask, AnyTask, napi_async_work, + ThreadSafeFunction, // PromiseTask, // TimeoutTasklet, }); @@ -497,13 +498,23 @@ pub const AnyTask = struct { }; } - pub fn wrap(this: *anyopaque) void { - Callback(@ptrCast(*Type, @alignCast(@alignOf(Type), this))); + pub fn wrap(this: ?*anyopaque) void { + Callback(@ptrCast(*Type, @alignCast(@alignOf(Type), this.?))); } }; } }; +pub export fn Bun__getDefaultGlobal() *JSGlobalObject { + return JSC.VirtualMachine.vm.global; +} + +comptime { + if (!JSC.is_bindgen) { + _ = Bun__getDefaultGlobal; + } +} + // If you read JavascriptCore/API/JSVirtualMachine.mm - https://github.com/WebKit/WebKit/blob/acff93fb303baa670c055cb24c2bad08691a01a0/Source/JavaScriptCore/API/JSVirtualMachine.mm#L101 // We can see that it's sort of like std.mem.Allocator but for JSGlobalContextRef, to support Automatic Reference Counting // Its unavailable on Linux @@ -1291,6 +1302,8 @@ pub const VirtualMachine = struct { .hash = 0, }; }, + // provideFetch() should be called + .napi => unreachable, // .wasm => { // jsc_vm.transpiled_count += 1; // var fd: ?StoredFileDescriptorType = null; diff --git a/src/javascript/jsc/rare_data.zig b/src/javascript/jsc/rare_data.zig index 90b8861d4..3020dfc16 100644 --- a/src/javascript/jsc/rare_data.zig +++ b/src/javascript/jsc/rare_data.zig @@ -29,6 +29,10 @@ pub const CleanupHook = struct { return self.ctx == other.ctx and self.func == other.func and self.globalThis == other.globalThis; } + pub fn execute(self: CleanupHook) void { + self.func(self.ctx); + } + pub fn from( globalThis: *JSC.JSGlobalObject, ctx: ?*anyopaque, @@ -59,8 +63,6 @@ pub fn pushCleanupHook( } else { this.cleanup_hook.?.next = hook; } - - return hook; } pub fn boringEngine(rare: *RareData) *BoringSSL.ENGINE { diff --git a/src/napi/napi.zig b/src/napi/napi.zig index 0e7169f18..3ec0bac2b 100644 --- a/src/napi/napi.zig +++ b/src/napi/napi.zig @@ -15,7 +15,6 @@ pub const napi_handle_scope = napi_env; pub const napi_escapable_handle_scope = struct_napi_escapable_handle_scope__; pub const napi_callback_info = *JSC.CallFrame; pub const napi_deferred = *JSC.JSPromise; -pub const uv_loop_s = struct_uv_loop_s; pub const napi_value = JSC.JSValue; pub const struct_napi_ref__ = opaque {}; @@ -167,7 +166,7 @@ pub export fn napi_get_boolean(_: napi_env, value: bool, result: *napi_value) na return .ok; } pub export fn napi_create_object(env: napi_env, result: *napi_value) napi_status { - result.* = JSValue.c(JSC.C.JSObjectMake(env.ref(), null, null)); + result.* = JSValue.createEmptyObject(env, 0); return .ok; } pub export fn napi_create_array(env: napi_env, result: *napi_value) napi_status { @@ -193,7 +192,7 @@ pub export fn napi_create_array_with_length(env: napi_env, length: usize, result for (undefined_args) |_, i| { undefined_args[i] = JSValue.jsUndefined().asObjectRef(); } - result.* = JSValue.c(JSC.C.JSObjectMakeArray(env.ptr(), length, undefined_args.ptr, null)); + result.* = JSValue.c(JSC.C.JSObjectMakeArray(env.ref(), length, undefined_args.ptr, null)); return .ok; } @@ -216,7 +215,7 @@ pub export fn napi_create_int64(_: napi_env, value: i64, result: *napi_value) na pub export fn napi_create_string_latin1(env: napi_env, str: [*]const u8, length: usize, result: *napi_value) napi_status { var len = length; if (NAPI_AUTO_LENGTH == length) { - len = std.mem.sliceTo(str, 0).len; + len = std.mem.sliceTo(std.meta.assumeSentinel(str, 0), 0).len; } result.* = JSC.ZigString.init(str[0..len]).toValueGC(env); return .ok; @@ -224,7 +223,7 @@ pub export fn napi_create_string_latin1(env: napi_env, str: [*]const u8, length: pub export fn napi_create_string_utf8(env: napi_env, str: [*]const u8, length: usize, result: *napi_value) napi_status { var len = length; if (NAPI_AUTO_LENGTH == length) { - len = std.mem.sliceTo(str, 0).len; + len = std.mem.sliceTo(std.meta.assumeSentinel(str, 0), 0).len; } result.* = JSC.ZigString.init(str[0..len]).withEncoding().toValueGC(env); return .ok; @@ -232,15 +231,15 @@ pub export fn napi_create_string_utf8(env: napi_env, str: [*]const u8, length: u pub export fn napi_create_string_utf16(env: napi_env, str: [*]const char16_t, length: usize, result: *napi_value) napi_status { var len = length; if (NAPI_AUTO_LENGTH == length) { - len = std.mem.sliceTo(str, 0).len; + len = std.mem.sliceTo(std.meta.assumeSentinel(str, 0), 0).len; } - result.* = JSC.ZigString.from16(str, len, env).toValueGC(env); + result.* = JSC.ZigString.from16(str, len).toValueGC(env); return .ok; } pub export fn napi_create_symbol(env: napi_env, description: napi_value, result: *napi_value) napi_status { - var string_ref = JSC.C.JSValueToStringCopy(env, description, null); + var string_ref = JSC.C.JSValueToStringCopy(env.ref(), description.asObjectRef(), null); defer JSC.C.JSStringRelease(string_ref); - result.* = JSValue.c(JSC.C.JSValueMakeSymbol(env, string_ref)); + result.* = JSValue.c(JSC.C.JSValueMakeSymbol(env.ref(), string_ref)); return .ok; } // const wrapped_callback_function_class_def = JSC.C.JSClassDefinition{ @@ -277,7 +276,7 @@ pub export fn napi_create_symbol(env: napi_env, description: napi_value, result: // pub fn getWrappedCallbackFunctionClass(env: napi_env) JSC.C.JSClassRef {} // pub export fn napi_create_function(env: napi_env, utf8name: [*c]const u8, length: usize, cb: napi_callback, data: ?*anyopaque, result: *napi_value) napi_status { -// // JSC.C.JSObjectMakeFunctionWithCallback(ctx: JSContextRef, name: JSStringRef, callAsFunction: JSObjectCallAsFunctionCallback) +// JSC.C.JSObject // } pub export fn napi_create_error(env: napi_env, code: napi_value, msg: napi_value, result: *napi_value) napi_status { const system_error = JSC.SystemError{ @@ -291,7 +290,7 @@ pub extern fn napi_create_type_error(env: napi_env, code: napi_value, msg: napi_ pub extern fn napi_create_range_error(env: napi_env, code: napi_value, msg: napi_value, result: *napi_value) napi_status; pub export fn napi_typeof(env: napi_env, value: napi_value, result: *napi_valuetype) napi_status { if (value.isEmpty()) { - result.* = .undefined; + result.* = .@"undefined"; return .ok; } @@ -307,12 +306,12 @@ pub export fn napi_typeof(env: napi_env, value: napi_value, result: *napi_valuet //"bigint" = 9, if (value.isUndefined()) { - result.* = .undefined; + result.* = .@"undefined"; return .ok; } if (value.isNull()) { - result.* = .null; + result.* = .@"null"; return .ok; } @@ -341,10 +340,10 @@ pub export fn napi_typeof(env: napi_env, value: napi_value, result: *napi_valuet return .ok; } - if (value.jsType() == .JSProxy) { - result.* = .external; - return .ok; - } + // if (value.jsType() == .JSProxy) { + // result.* = .external; + // return .ok; + // } if (value.isObject()) { if (value.isCallable(env.vm())) { @@ -363,7 +362,7 @@ pub export fn napi_typeof(env: napi_env, value: napi_value, result: *napi_valuet return .invalid_arg; } pub export fn napi_get_value_double(_: napi_env, value: napi_value, result: *f64) napi_status { - result.* = value.to(f64); + result.* = value.asNumber(); return .ok; } pub export fn napi_get_value_int32(_: napi_env, value: napi_value, result: *i32) napi_status { @@ -426,20 +425,20 @@ pub export fn napi_get_value_string_utf16(env: napi_env, value: napi_value, buf: } const to_copy = @minimum(zig_str.len, bufsize); - @memcpy(buf[0..], zig_str.utf16SliceAligned().ptr, to_copy); + @memcpy(std.mem.sliceAsBytes(buf[0..bufsize]).ptr, std.mem.sliceAsBytes(zig_str.utf16SliceAligned()).ptr, to_copy * 2); result.* = to_copy; return .ok; } pub export fn napi_coerce_to_bool(_: napi_env, value: napi_value, result: *napi_value) napi_status { - result.* = value.to(bool); + result.* = JSValue.jsBoolean(value.to(bool)); return .ok; } pub export fn napi_coerce_to_number(env: napi_env, value: napi_value, result: *napi_value) napi_status { - result.* = JSValue.from(JSC.C.JSValueToNumber(env.ref(), value.asObjectRef(), TODO_EXCEPTION)); + result.* = JSC.JSValue.jsNumber(JSC.C.JSValueToNumber(env.ref(), value.asObjectRef(), TODO_EXCEPTION)); return .ok; } pub export fn napi_coerce_to_object(env: napi_env, value: napi_value, result: *napi_value) napi_status { - result.* = JSValue.from(JSC.C.JSValueToObject(env.ref(), value.asObjectRef(), TODO_EXCEPTION)); + result.* = JSValue.c(JSC.C.JSValueToObject(env.ref(), value.asObjectRef(), TODO_EXCEPTION)); return .ok; } // pub export fn napi_coerce_to_string(env: napi_env, value: napi_value, result: *napi_value) napi_status { @@ -452,7 +451,7 @@ pub export fn napi_get_prototype(env: napi_env, object: napi_value, result: *nap return .object_expected; } - result.* = JSValue.from(JSC.C.JSObjectGetPrototype(env.ref(), object.asObjectRef())); + result.* = JSValue.c(JSC.C.JSObjectGetPrototype(env.ref(), object.asObjectRef())); return .ok; } // TODO: bind JSC::ownKeys @@ -471,9 +470,16 @@ pub export fn napi_set_property(env: napi_env, object: napi_value, key: napi_val if (name.len == 0 or value.isEmpty()) { return .invalid_arg; } - var exception: ?JSC.C.JSValueRef = null; - JSC.C.JSObjectSetPropertyForKey(env.ref(), object.asObjectRef(), key.asObjectRef(), value, JSC.C.JSPropertyAttributes.kJSPropertyAttributeNone, &exception); - return if (exception == null) + var exception = [_]JSC.C.JSValueRef{null}; + JSC.C.JSObjectSetPropertyForKey( + env.ref(), + object.asObjectRef(), + key.asObjectRef(), + value.asObjectRef(), + JSC.C.JSPropertyAttributes.kJSPropertyAttributeNone, + &exception, + ); + return if (exception[0] == null) .ok else .generic_failure; @@ -489,10 +495,10 @@ pub export fn napi_has_property(env: napi_env, object: napi_value, key: napi_val return .invalid_arg; } // TODO: bind hasOwnProperty - result.* = object.get(env, &name_slice) != null; + result.* = object.get(env, name_slice.slice()) != null; return .ok; } -pub export fn napi_get_property(env: napi_env, object: napi_value, key: napi_value, result: ?*napi_value) napi_status { +pub export fn napi_get_property(env: napi_env, object: napi_value, key: napi_value, result: *napi_value) napi_status { if (!object.isObject()) { return .object_expected; } @@ -508,7 +514,7 @@ pub export fn napi_get_property(env: napi_env, object: napi_value, key: napi_val return .invalid_arg; } // TODO: DECLARE_THROW_SCOPE - result.* = object.get(env, &name_slice); + result.* = object.get(env, name_slice.slice()) orelse JSC.JSValue.@"undefined"; return .ok; } pub export fn napi_delete_property(env: napi_env, object: napi_value, key: napi_value, result: *bool) napi_status { @@ -520,7 +526,7 @@ pub export fn napi_delete_property(env: napi_env, object: napi_value, key: napi_ return .invalid_arg; } - result.* = JSC.C.JSObjectDeletePropertyForKey(env, object.asObjectRef(), key.asObjectRef(), null); + result.* = JSC.C.JSObjectDeletePropertyForKey(env.ref(), object.asObjectRef(), key.asObjectRef(), null); return .ok; } pub export fn napi_has_own_property(env: napi_env, object: napi_value, key: napi_value, result: *bool) napi_status { @@ -532,9 +538,11 @@ pub export fn napi_has_own_property(env: napi_env, object: napi_value, key: napi return .invalid_arg; } - result.* = JSC.C.JSObjectHasPropertyForKey(env, object.asObjectRef(), key.asObjectRef(), null); + result.* = JSC.C.JSObjectHasPropertyForKey(env.ref(), object.asObjectRef(), key.asObjectRef(), null); return .ok; } + +fn noop_finalizer(_: ?*anyopaque, _: JSC.C.JSStringRef, _: *anyopaque, _: usize) callconv(.C) void {} pub export fn napi_set_named_property(env: napi_env, object: napi_value, utf8name: [*c]const u8, value: napi_value) napi_status { if (!object.isObject()) { return .object_expected; @@ -548,9 +556,9 @@ pub export fn napi_set_named_property(env: napi_env, object: napi_value, utf8nam if (str.len == 0) return .invalid_arg; - var ext = JSC.C.JSStringCreateExternal(utf8name, str.len, null, null); + var ext = JSC.C.JSStringCreateExternal(utf8name, str.len, null, noop_finalizer); defer JSC.C.JSStringRelease(ext); - JSC.C.JSObjectSetProperty(env.ref(), object.asObjectRef, ext, value.asObjectRef(), 0, TODO_EXCEPTION); + JSC.C.JSObjectSetProperty(env.ref(), object.asObjectRef(), ext, value.asObjectRef(), 0, TODO_EXCEPTION); return .ok; } pub export fn napi_has_named_property(env: napi_env, object: napi_value, utf8name: [*c]const u8, result: *bool) napi_status { @@ -566,9 +574,9 @@ pub export fn napi_has_named_property(env: napi_env, object: napi_value, utf8nam if (str.len == 0) return .invalid_arg; - var ext = JSC.C.JSStringCreateExternal(utf8name, str.len, null, null); + var ext = JSC.C.JSStringCreateExternal(utf8name, str.len, null, noop_finalizer); defer JSC.C.JSStringRelease(ext); - result.* = JSC.C.JSObjectHasProperty(env.ref(), object.asObjectRef, ext); + result.* = JSC.C.JSObjectHasProperty(env.ref(), object.asObjectRef(), ext); return .ok; } pub export fn napi_get_named_property(env: napi_env, object: napi_value, utf8name: [*c]const u8, result: *napi_value) napi_status { @@ -584,9 +592,9 @@ pub export fn napi_get_named_property(env: napi_env, object: napi_value, utf8nam if (str.len == 0) return .invalid_arg; - var ext = JSC.C.JSStringCreateExternal(utf8name, str.len, null, null); + var ext = JSC.C.JSStringCreateExternal(utf8name, str.len, null, noop_finalizer); defer JSC.C.JSStringRelease(ext); - result.* = JSValue.from(JSC.C.JSObjectGetProperty(env.ref(), object.asObjectRef, ext, TODO_EXCEPTION)); + result.* = JSValue.c(JSC.C.JSObjectGetProperty(env.ref(), object.asObjectRef(), ext, TODO_EXCEPTION)); return .ok; } pub export fn napi_set_element(env: napi_env, object: napi_value, index: c_uint, value: napi_value) napi_status { @@ -595,7 +603,7 @@ pub export fn napi_set_element(env: napi_env, object: napi_value, index: c_uint, } if (value.isEmpty()) return .invalid_arg; - JSC.C.JSObjectSetPropertyAtIndex(env.ref(), object.asObjectRef(), index, value, TODO_EXCEPTION); + JSC.C.JSObjectSetPropertyAtIndex(env.ref(), object.asObjectRef(), index, value.asObjectRef(), TODO_EXCEPTION); return .ok; } pub export fn napi_has_element(env: napi_env, object: napi_value, index: c_uint, result: *bool) napi_status { @@ -614,15 +622,15 @@ pub export fn napi_get_element(env: napi_env, object: napi_value, index: u32, re result.* = JSC.JSObject.getIndex(object, env, index); return .ok; } -pub export fn napi_delete_element(env: napi_env, object: napi_value, index: u32, result: *bool) napi_status { - if (!object.jsType().isIndexable()) { - return .array_expected; - } +// pub export fn napi_delete_element(env: napi_env, object: napi_value, index: u32, result: *bool) napi_status { +// if (!object.jsType().isIndexable()) { +// return .array_expected; +// } - // TODO: this might be incorrect because I don't know if this API supports numbers, it may only support strings - result.* = JSC.C.JSObjectDeleteProperty(env.ref(), object.asObjectRef(), JSC.JSValue.jsNumber(index), TODO_EXCEPTION); - return .ok; -} +// // TODO: this might be incorrect because I don't know if this API supports numbers, it may only support strings +// // result.* = JSC.C.Delete(env.ref(), object.asObjectRef(), JSC.JSValue.jsNumber(index), TODO_EXCEPTION); +// return .ok; +// } pub extern fn napi_define_properties(env: napi_env, object: napi_value, property_count: usize, properties: [*c]const napi_property_descriptor) napi_status; pub export fn napi_is_array(_: napi_env, value: napi_value, result: *bool) napi_status { result.* = value.jsType().isArray(); @@ -642,18 +650,17 @@ pub export fn napi_strict_equals(env: napi_env, lhs: napi_value, rhs: napi_value return .ok; } pub export fn napi_call_function(env: napi_env, recv: napi_value, func: napi_value, argc: usize, argv: [*c]const napi_value, result: *napi_value) napi_status { + if (comptime JSC.is_bindgen) unreachable; var exception = [_]JSC.C.JSValueRef{null}; - result.* = JSValue.c( + result.* = JSC.C.JSObjectCallAsFunctionReturnValue( - env.ref(), - func.asObjectRef(), - recv.asObjectRef(), - argc, - @ptrCast([*]const JSC.C.JSValueRef, argv), - &exception, - ), + env.ref(), + func.asObjectRef(), + recv.asObjectRef(), + argc, + @ptrCast([*]const JSC.C.JSValueRef, argv), ); - if (exception.* != null) { + if (exception[0] != null) { return .generic_failure; } @@ -670,7 +677,7 @@ pub export fn napi_new_instance(env: napi_env, constructor: napi_value, argc: us &exception, ), ); - if (exception.* != null) { + if (exception[0] != null) { return .generic_failure; } @@ -683,7 +690,16 @@ pub export fn napi_instanceof(env: napi_env, object: napi_value, constructor: na } pub extern fn napi_get_cb_info(env: napi_env, cbinfo: napi_callback_info, argc: [*c]usize, argv: *napi_value, this_arg: *napi_value, data: [*]*anyopaque) napi_status; pub extern fn napi_get_new_target(env: napi_env, cbinfo: napi_callback_info, result: *napi_value) napi_status; -pub extern fn napi_define_class(env: napi_env, utf8name: [*c]const u8, length: usize, constructor: napi_callback, data: ?*anyopaque, property_count: usize, properties: [*c]const napi_property_descriptor, result: *napi_value) napi_status; +pub extern fn napi_define_class( + env: napi_env, + utf8name: [*c]const u8, + length: usize, + constructor: napi_callback, + data: ?*anyopaque, + property_count: usize, + properties: [*c]const napi_property_descriptor, + result: *napi_value, +) napi_status; pub extern fn napi_wrap(env: napi_env, js_object: napi_value, native_object: ?*anyopaque, finalize_cb: napi_finalize, finalize_hint: ?*anyopaque, result: [*c]napi_ref) napi_status; pub extern fn napi_unwrap(env: napi_env, js_object: napi_value, result: [*]*anyopaque) napi_status; pub extern fn napi_remove_wrap(env: napi_env, js_object: napi_value, result: [*]*anyopaque) napi_status; @@ -734,7 +750,8 @@ pub export fn napi_create_arraybuffer(env: napi_env, byte_length: usize, data: [ pub export fn napi_create_external_arraybuffer(env: napi_env, external_data: ?*anyopaque, byte_length: usize, finalize_cb: napi_finalize, finalize_hint: ?*anyopaque, result: *napi_value) napi_status { var external = JSC.ExternalBuffer.create( finalize_hint, - @ptrCast([*]u8, external_data).?[0..byte_length], + @ptrCast([*]u8, external_data.?)[0..byte_length], + env, finalize_cb, JSC.VirtualMachine.vm.allocator, ) catch { @@ -777,7 +794,7 @@ pub export fn napi_get_typedarray_info( byte_offset: *usize, ) napi_status { const array_buffer = arraybuffer.asArrayBuffer(env) orelse return .invalid_arg; - @"type" = napi_typedarray_type.fromJSType(array_buffer.typed_array_type) orelse return .invalid_arg; + @"type".* = napi_typedarray_type.fromJSType(array_buffer.typed_array_type) orelse return .invalid_arg; var slice = array_buffer.slice(); data.* = slice.ptr; @@ -830,11 +847,11 @@ pub export fn napi_is_promise(_: napi_env, value: napi_value, is_promise: *bool) } pub export fn napi_run_script(env: napi_env, script: napi_value, result: *napi_value) napi_status { // TODO: don't copy - var ref = JSC.C.JSValueToStringCopy(env, script.asObjectRef(), TODO_EXCEPTION); + var ref = JSC.C.JSValueToStringCopy(env.ref(), script.asObjectRef(), TODO_EXCEPTION); defer JSC.C.JSStringRelease(ref); var exception = [_]JSC.C.JSValueRef{null}; - const val = JSC.C.JSEvaluateScript(env.ref(), script, env, null, 0, &exception); + const val = JSC.C.JSEvaluateScript(env.ref(), ref, env.ref(), null, 0, &exception); if (exception[0] != null) { return .generic_failure; } @@ -844,8 +861,8 @@ pub export fn napi_run_script(env: napi_env, script: napi_value, result: *napi_v } pub extern fn napi_adjust_external_memory(env: napi_env, change_in_bytes: i64, adjusted_value: [*c]i64) napi_status; pub export fn napi_create_date(env: napi_env, time: f64, result: *napi_value) napi_status { - var args = [_]JSC.C.JSValueRef{JSC.JSValue.jsNumber(time)}; - result.* = JSC.C.JSObjectMakeDate(env.ref(), 1, &args, TODO_EXCEPTION); + var args = [_]JSC.C.JSValueRef{JSC.JSValue.jsNumber(time).asObjectRef()}; + result.* = JSValue.c(JSC.C.JSObjectMakeDate(env.ref(), 1, &args, TODO_EXCEPTION)); return .ok; } pub export fn napi_is_date(_: napi_env, value: napi_value, is_date: *bool) napi_status { @@ -857,7 +874,9 @@ pub export fn napi_get_date_value(env: napi_env, value: napi_value, result: *f64 return .date_expected; }; - result.* = JSValue.c(JSC.C.JSObjectCallAsFunction(env.ref(), getTimeFunction.asObjectRef(), value.asObjectRef, 0, null, TODO_EXCEPTION)).asNumber(); + result.* = JSValue.c( + JSC.C.JSObjectCallAsFunction(env.ref(), getTimeFunction.asObjectRef(), value.asObjectRef(), 0, null, TODO_EXCEPTION), + ).asNumber(); return .ok; } pub extern fn napi_add_finalizer(env: napi_env, js_object: napi_value, native_object: ?*anyopaque, finalize_cb: napi_finalize, finalize_hint: ?*anyopaque, result: [*c]napi_ref) napi_status; @@ -866,7 +885,7 @@ pub export fn napi_create_bigint_int64(env: napi_env, value: i64, result: *napi_ return .ok; } pub export fn napi_create_bigint_uint64(env: napi_env, value: u64, result: *napi_value) napi_status { - result.* = JSC.JSValue.fromUint64NoTruncate(env, value); + result.* = JSC.JSValue.fromUInt64NoTruncate(env, value); return .ok; } pub extern fn napi_create_bigint_words(env: napi_env, sign_bit: c_int, word_count: usize, words: [*c]const u64, result: *napi_value) napi_status; @@ -888,14 +907,15 @@ pub extern fn napi_detach_arraybuffer(env: napi_env, arraybuffer: napi_value) na pub extern fn napi_is_detached_arraybuffer(env: napi_env, value: napi_value, result: *bool) napi_status; pub extern fn napi_type_tag_object(env: napi_env, value: napi_value, type_tag: [*c]const napi_type_tag) napi_status; pub extern fn napi_check_object_type_tag(env: napi_env, value: napi_value, type_tag: [*c]const napi_type_tag, result: *bool) napi_status; -pub extern fn napi_object_freeze(env: napi_env, object: napi_value) napi_status; -pub extern fn napi_object_seal(env: napi_env, object: napi_value) napi_status; +// pub extern fn napi_object_freeze(env: napi_env, object: napi_value) napi_status; +// pub extern fn napi_object_seal(env: napi_env, object: napi_value) napi_status; pub const struct_napi_async_work__ = opaque {}; const WorkPool = @import("../work_pool.zig").WorkPool; +const WorkPoolTask = @import("../work_pool.zig").Task; /// must be globally allocated pub const napi_async_work = struct { - task: JSC.WorkPoolTask = .{ .callback = runFromThreadPool }, + task: WorkPoolTask = .{ .callback = runFromThreadPool }, completion_task: ?*anyopaque = null, event_loop: *JSC.VirtualMachine.EventLoop, global: napi_env, @@ -918,13 +938,14 @@ pub const napi_async_work = struct { work.* = .{ .global = global, .execute = execute, + .event_loop = JSC.VirtualMachine.vm.eventLoop(), .complete = complete, .ctx = ctx, }; return work; } - pub fn runFromThreadPool(task: *JSC.WorkPoolTask) void { + pub fn runFromThreadPool(task: *WorkPoolTask) void { var this = @fieldParentPtr(napi_async_work, "task", task); this.run(); @@ -942,24 +963,17 @@ pub const napi_async_work = struct { this.execute.?(this.global, this.ctx); this.status.store(@enumToInt(Status.completed), .SeqCst); - this.event_loop.enqueueTaskConcurrent(JSC.Task.from(JSC.Task.init(this))); + this.event_loop.enqueueTaskConcurrent(JSC.Task.init(this)); } pub fn schedule(this: *napi_async_work) void { if (this.scheduled) return; this.scheduled = true; - WorkPool.get().schedule(&this.task); + WorkPool.schedule(&this.task); } pub fn cancel(this: *napi_async_work) bool { - const prev_status = @intToEnum( - Status, - this.status.compareAndSwap(@enumToInt(Status.cancelled), @enumToInt(Status.pending), .SeqCst, .SeqCst), - ); - if (prev_status == Status.pending) { - return true; - } - return false; + return this.status.compareAndSwap(@enumToInt(Status.cancelled), @enumToInt(Status.pending), .SeqCst, .SeqCst) != null; } pub fn deinit(this: *napi_async_work) void { @@ -977,7 +991,7 @@ pub const napi_async_work = struct { napi_status.cancelled else napi_status.ok, - this.ctx, + this.ctx.?, ); } }; @@ -986,8 +1000,8 @@ pub const napi_threadsafe_function_release_mode = enum(c_uint) { release = 0, abort = 1, }; -pub const napi_tsfn_nonblocking: c_int = 0; -pub const napi_tsfn_blocking: c_int = 1; +pub const napi_tsfn_nonblocking = 0; +pub const napi_tsfn_blocking = 1; pub const napi_threadsafe_function_call_mode = c_uint; pub const napi_async_execute_callback = ?fn (napi_env, ?*anyopaque) callconv(.C) void; pub const napi_async_complete_callback = ?fn (napi_env, napi_status, ?*anyopaque) callconv(.C) void; @@ -1008,7 +1022,7 @@ pub const napi_node_version = extern struct { pub const struct_napi_async_cleanup_hook_handle__ = opaque {}; pub const napi_async_cleanup_hook_handle = ?*struct_napi_async_cleanup_hook_handle__; pub const napi_async_cleanup_hook = ?fn (napi_async_cleanup_hook_handle, ?*anyopaque) callconv(.C) void; -pub const struct_uv_loop_s = opaque {}; + pub const napi_addon_register_func = ?fn (napi_env, napi_value) callconv(.C) napi_value; pub const struct_napi_module = extern struct { nm_version: c_int, @@ -1020,13 +1034,42 @@ pub const struct_napi_module = extern struct { reserved: [4]?*anyopaque, }; pub const napi_module = struct_napi_module; -pub extern fn napi_module_register(mod: [*c]napi_module) void; -pub extern fn napi_fatal_error(location: [*c]const u8, location_len: usize, message: [*c]const u8, message_len: usize) noreturn; -pub extern fn napi_async_init(env: napi_env, async_resource: napi_value, async_resource_name: napi_value, result: [*c]napi_async_context) napi_status; -pub extern fn napi_async_destroy(env: napi_env, async_context: napi_async_context) napi_status; -pub extern fn napi_make_callback(env: napi_env, async_context: napi_async_context, recv: napi_value, func: napi_value, argc: usize, argv: [*c]const napi_value, result: *napi_value) napi_status; +// C++ +// pub export fn napi_module_register(mod: *napi_module) void { +// const register = mod.nm_register_func orelse return; +// var ref = JSC.C.JSObjectMake(JSC.VirtualMachine.vm.global, null, null); +// register(JSC.VirtualMachine.vm.global, JSC.JSValue.c(ref)); +// } +pub export fn napi_fatal_error(location: ?[*]const u8, location_len: usize, message: ?[*]const u8, message_len: usize) noreturn { + var message_: []const u8 = "fatal error"; + if (message_len > 0) { + if (message) |msg| { + message_ = msg[0..message_len]; + } + } + + if (location) |loc| { + if (location_len > 0) { + bun.Global.panic("napi: {s}\n {s}", .{ message_, loc[0..location_len] }); + } + } + + bun.Global.panic("napi: {s}", .{message_}); +} + +// pub extern fn napi_async_init(_: napi_env, _: napi_value, _: napi_value, result: ?*fake_async_hook) napi_status; +// { + +// } +// pub extern fn napi_async_destroy(_: napi_env, _: ?*anyopaque) napi_status; // + +// pub export fn napi_make_callback(env: napi_env, _: ?*anyopaque, recv: napi_value, func: napi_value, argc: usize, argv: [*c]const napi_value, result: *napi_value) napi_status { +// // TODO: potentially make this run on next tick? +// // there is some nuance with task queue order here i don't fully understand right now +// // JSC.C.JSObjectCallAsFunction(env.ref(), func.asObjectRef(), recv.asObjectRef(), argc, @ptrCast([*]const JSC.C.JSValueRef), exception: ExceptionRef) +// } pub export fn napi_create_buffer(env: napi_env, length: usize, data: [*]*anyopaque, result: *napi_value) napi_status { - var buf = JSC.ExternalBuffer.create(null, @ptrCast([*]u8, data.?)[0..length], env, null, JSC.VirtualMachine.vm.allocator) catch { + var buf = JSC.ExternalBuffer.create(null, @ptrCast([*]u8, data)[0..length], env, null, JSC.VirtualMachine.vm.allocator) catch { return .generic_failure; }; @@ -1042,7 +1085,7 @@ pub export fn napi_create_external_buffer(env: napi_env, length: usize, data: ?* return .ok; } pub export fn napi_create_buffer_copy(env: napi_env, length: usize, data: [*]u8, result_data: ?*?*anyopaque, result: *napi_value) napi_status { - var duped = JSC.VirtualMachine.vm.allocator.alloc(u8, data[0..length]) catch { + var duped = JSC.VirtualMachine.vm.allocator.alloc(u8, length) catch { return .generic_failure; }; @memcpy(duped.ptr, data, length); @@ -1065,7 +1108,7 @@ pub export fn napi_get_buffer_info(env: napi_env, value: napi_value, data: *[*]u }; data.* = array_buf.ptr; - length.* = array_buf.length; + length.* = array_buf.byte_len; return .ok; } pub export fn napi_create_async_work( @@ -1075,7 +1118,7 @@ pub export fn napi_create_async_work( execute: napi_async_execute_callback, complete: napi_async_complete_callback, data: ?*anyopaque, - result: *napi_async_work, + result: **napi_async_work, ) napi_status { result.* = napi_async_work.create(env, execute, complete, data) catch { return .generic_failure; @@ -1085,6 +1128,7 @@ pub export fn napi_create_async_work( pub export fn napi_delete_async_work(env: napi_env, work: *napi_async_work) napi_status { std.debug.assert(env == work.global); work.deinit(); + return .ok; } pub export fn napi_queue_async_work(env: napi_env, work: *napi_async_work) napi_status { std.debug.assert(env == work.global); @@ -1103,9 +1147,10 @@ pub export fn napi_get_node_version(_: napi_env, version: **const napi_node_vers version.* = &napi_node_version.global; return .ok; } -pub export fn napi_get_uv_event_loop(_: napi_env, loop: *?*struct_uv_loop_s) napi_status { +pub export fn napi_get_uv_event_loop(_: napi_env, loop: **JSC.VirtualMachine.EventLoop) napi_status { // lol loop.* = JSC.VirtualMachine.vm.eventLoop(); + return .ok; } pub extern fn napi_fatal_exception(env: napi_env, err: napi_value) napi_status; @@ -1115,7 +1160,7 @@ pub export fn napi_add_env_cleanup_hook(env: napi_env, fun: ?fn (?*anyopaque) ca if (fun == null) return .ok; - JSC.VirtualMachine.vm.rareData().pushCleanupHook(env, arg, fun); + JSC.VirtualMachine.vm.rareData().pushCleanupHook(env, arg, fun.?); return .ok; } pub export fn napi_remove_env_cleanup_hook(env: napi_env, fun: ?fn (?*anyopaque) callconv(.C) void, arg: ?*anyopaque) napi_status { @@ -1165,10 +1210,9 @@ pub const ThreadSafeFunction = struct { /// prevent it from being destroyed. ref_for_process_exit: bool = false, - owning_threads: std.AutoArrayHashMapUnmanaged(u64) = .{}, + owning_threads: std.AutoArrayHashMapUnmanaged(u64, void) = .{}, owning_thread_lock: Lock = Lock.init(), event_loop: *JSC.VirtualMachine.EventLoop, - finalizer: ?*Finalizer = null, javascript_function: JSValue, finalizer_task: JSC.AnyTask = undefined, @@ -1182,22 +1226,22 @@ pub const ThreadSafeFunction = struct { const ThreadSafeFunctionTask = JSC.AnyTask.New(@This(), call); pub const Queue = union(enum) { sized: Channel(?*anyopaque, .Slice), - unsized: Channel(?*anyopaque, .Slice), + unsized: Channel(?*anyopaque, .Dynamic), pub fn isClosed(this: *const @This()) bool { return @atomicLoad( bool, - switch (this) { - .sized => &this.size.is_closed, + switch (this.*) { + .sized => &this.sized.is_closed, .unsized => &this.unsized.is_closed, }, .SeqCst, ); } - pub fn close(this: *@This()) bool { - switch (this) { - .sized => this.size.close(), + pub fn close(this: *@This()) void { + switch (this.*) { + .sized => this.sized.close(), .unsized => this.unsized.close(), } } @@ -1226,24 +1270,24 @@ pub const ThreadSafeFunction = struct { } pub fn readItem(this: *@This()) !?*anyopaque { - switch (this.*) { + return switch (this.*) { .sized => try this.sized.readItem(), .unsized => try this.unsized.readItem(), - } + }; } pub fn tryWriteItem(this: *@This(), value: ?*anyopaque) !bool { - switch (this.*) { + return switch (this.*) { .sized => try this.sized.tryWriteItem(value), .unsized => try this.unsized.tryWriteItem(value), - } + }; } pub fn tryReadItem(this: *@This()) !??*anyopaque { - switch (this.*) { + return switch (this.*) { .sized => try this.sized.tryReadItem(), .unsized => try this.unsized.tryReadItem(), - } + }; } }; @@ -1266,20 +1310,20 @@ pub const ThreadSafeFunction = struct { pub fn enqueue(this: *ThreadSafeFunction, ctx: ?*anyopaque, block: bool) !void { if (block) { - try this.channel.writeItem(JSC.AnyTask{ .ctx = ctx, .run = this.call }); + try this.channel.writeItem(ctx); } else { - if (!this.channel.tryWriteItem(JSC.AnyTask{ .ctx = ctx, .run = this.call })) { + if (!try this.channel.tryWriteItem(ctx)) { return error.WouldBlock; } } - this.event_loop.enqueueTaskConcurrent(ThreadSafeFunction.init(this)); + this.event_loop.enqueueTaskConcurrent(JSC.Task.init(this)); } pub fn finalize(opaq: *anyopaque) void { var this = bun.cast(*ThreadSafeFunction, opaq); if (this.finalizer.fun) |fun| { - fun(this.finalizer.ctx); + fun(this.event_loop.global, opaq, this.finalizer.ctx); } JSC.C.JSValueUnprotect(this.event_loop.global.ref(), this.javascript_function.asObjectRef()); @@ -1314,13 +1358,14 @@ pub const ThreadSafeFunction = struct { if (this.owning_threads.count() == 0) { this.finalizer_task = JSC.AnyTask{ .ctx = this, .callback = finalize }; - this.event_loop.enqueueTaskConcurrent(&this.finalizer_task); + this.event_loop.enqueueTaskConcurrent(JSC.Task.init(&this.finalizer_task)); return; } } }; -pub extern fn napi_open_callback_scope(env: napi_env, resource_object: napi_value, context: napi_async_context, result: [*c]napi_callback_scope) napi_status; -pub extern fn napi_close_callback_scope(env: napi_env, scope: napi_callback_scope) napi_status; + +// pub extern fn napi_open_callback_scope(env: napi_env, resource_object: napi_value, context: napi_async_context, result: [*c]napi_callback_scope) napi_status; +// pub extern fn napi_close_callback_scope(env: napi_env, scope: napi_callback_scope) napi_status; pub export fn napi_create_threadsafe_function( env: napi_env, func: napi_value, @@ -1343,7 +1388,7 @@ pub export fn napi_create_threadsafe_function( .javascript_function = func, .call_js = call_js_cb, .ctx = context, - .queue = ThreadSafeFunction.Queue.init(max_queue_size, bun.default_allocator), + .channel = ThreadSafeFunction.Queue.init(max_queue_size, bun.default_allocator), .owning_threads = .{}, }; function.owning_threads.ensureTotalCapacity(bun.default_allocator, initial_thread_count) catch return .generic_failure; @@ -1356,14 +1401,13 @@ pub export fn napi_get_threadsafe_function_context(func: napi_threadsafe_functio return .ok; } pub export fn napi_call_threadsafe_function(func: napi_threadsafe_function, data: ?*anyopaque, is_blocking: napi_threadsafe_function_call_mode) napi_status { - func.enqueue(data, is_blocking) catch |err| { + func.enqueue(data, is_blocking == napi_tsfn_blocking) catch |err| { switch (err) { error.WouldBlock => { return napi_status.queue_full; }, - error.Closing => { - return napi_status.closing; - }, + + else => return .closing, } }; return .ok; @@ -1403,3 +1447,210 @@ pub const NAPI_VERSION = @as(c_int, 8); pub const NAPI_AUTO_LENGTH = std.math.maxInt(usize); pub const SRC_NODE_API_TYPES_H_ = ""; pub const NAPI_MODULE_VERSION = @as(c_int, 1); + +pub fn fixDeadCodeElimination() void { + if (comptime JSC.is_bindgen) unreachable; + std.mem.doNotOptimizeAway(napi_get_undefined); + std.mem.doNotOptimizeAway(napi_get_null); + std.mem.doNotOptimizeAway(napi_get_boolean); + std.mem.doNotOptimizeAway(napi_create_object); + std.mem.doNotOptimizeAway(napi_create_array); + std.mem.doNotOptimizeAway(napi_create_array_with_length); + std.mem.doNotOptimizeAway(napi_create_double); + std.mem.doNotOptimizeAway(napi_create_int32); + std.mem.doNotOptimizeAway(napi_create_uint32); + std.mem.doNotOptimizeAway(napi_create_int64); + std.mem.doNotOptimizeAway(napi_create_string_latin1); + std.mem.doNotOptimizeAway(napi_create_string_utf8); + std.mem.doNotOptimizeAway(napi_create_string_utf16); + std.mem.doNotOptimizeAway(napi_create_symbol); + // std.mem.doNotOptimizeAway(napi_create_function); + std.mem.doNotOptimizeAway(napi_create_error); + std.mem.doNotOptimizeAway(napi_typeof); + std.mem.doNotOptimizeAway(napi_get_value_double); + std.mem.doNotOptimizeAway(napi_get_value_int32); + std.mem.doNotOptimizeAway(napi_get_value_uint32); + std.mem.doNotOptimizeAway(napi_get_value_int64); + std.mem.doNotOptimizeAway(napi_get_value_bool); + std.mem.doNotOptimizeAway(napi_get_value_string_latin1); + std.mem.doNotOptimizeAway(napi_get_value_string_utf8); + std.mem.doNotOptimizeAway(napi_get_value_string_utf16); + std.mem.doNotOptimizeAway(napi_coerce_to_bool); + std.mem.doNotOptimizeAway(napi_coerce_to_number); + std.mem.doNotOptimizeAway(napi_coerce_to_object); + // std.mem.doNotOptimizeAway(napi_coerce_to_string); + std.mem.doNotOptimizeAway(napi_get_prototype); + // std.mem.doNotOptimizeAway(napi_get_property_names); + std.mem.doNotOptimizeAway(napi_set_property); + std.mem.doNotOptimizeAway(napi_has_property); + std.mem.doNotOptimizeAway(napi_get_property); + std.mem.doNotOptimizeAway(napi_delete_property); + std.mem.doNotOptimizeAway(napi_has_own_property); + std.mem.doNotOptimizeAway(napi_set_named_property); + std.mem.doNotOptimizeAway(napi_has_named_property); + std.mem.doNotOptimizeAway(napi_get_named_property); + std.mem.doNotOptimizeAway(napi_set_element); + std.mem.doNotOptimizeAway(napi_has_element); + std.mem.doNotOptimizeAway(napi_get_element); + // std.mem.doNotOptimizeAway(napi_delete_element); + std.mem.doNotOptimizeAway(napi_is_array); + std.mem.doNotOptimizeAway(napi_get_array_length); + std.mem.doNotOptimizeAway(napi_strict_equals); + std.mem.doNotOptimizeAway(napi_call_function); + std.mem.doNotOptimizeAway(napi_new_instance); + std.mem.doNotOptimizeAway(napi_instanceof); + std.mem.doNotOptimizeAway(napi_open_handle_scope); + std.mem.doNotOptimizeAway(napi_close_handle_scope); + std.mem.doNotOptimizeAway(napi_is_error); + std.mem.doNotOptimizeAway(napi_is_arraybuffer); + std.mem.doNotOptimizeAway(napi_create_arraybuffer); + std.mem.doNotOptimizeAway(napi_create_external_arraybuffer); + std.mem.doNotOptimizeAway(napi_get_arraybuffer_info); + std.mem.doNotOptimizeAway(napi_is_typedarray); + std.mem.doNotOptimizeAway(napi_create_typedarray); + std.mem.doNotOptimizeAway(napi_get_typedarray_info); + std.mem.doNotOptimizeAway(napi_is_dataview); + std.mem.doNotOptimizeAway(napi_get_dataview_info); + std.mem.doNotOptimizeAway(napi_get_version); + std.mem.doNotOptimizeAway(napi_create_promise); + std.mem.doNotOptimizeAway(napi_resolve_deferred); + std.mem.doNotOptimizeAway(napi_reject_deferred); + std.mem.doNotOptimizeAway(napi_is_promise); + std.mem.doNotOptimizeAway(napi_run_script); + std.mem.doNotOptimizeAway(napi_create_date); + std.mem.doNotOptimizeAway(napi_is_date); + std.mem.doNotOptimizeAway(napi_get_date_value); + std.mem.doNotOptimizeAway(napi_create_bigint_int64); + std.mem.doNotOptimizeAway(napi_create_bigint_uint64); + std.mem.doNotOptimizeAway(napi_get_value_bigint_int64); + std.mem.doNotOptimizeAway(napi_get_value_bigint_uint64); + // std.mem.doNotOptimizeAway(napi_module_register); + std.mem.doNotOptimizeAway(napi_fatal_error); + // std.mem.doNotOptimizeAway(napi_make_callback); + std.mem.doNotOptimizeAway(napi_create_buffer); + std.mem.doNotOptimizeAway(napi_create_external_buffer); + std.mem.doNotOptimizeAway(napi_create_buffer_copy); + std.mem.doNotOptimizeAway(napi_is_buffer); + std.mem.doNotOptimizeAway(napi_get_buffer_info); + std.mem.doNotOptimizeAway(napi_create_async_work); + std.mem.doNotOptimizeAway(napi_delete_async_work); + std.mem.doNotOptimizeAway(napi_queue_async_work); + std.mem.doNotOptimizeAway(napi_cancel_async_work); + std.mem.doNotOptimizeAway(napi_get_node_version); + std.mem.doNotOptimizeAway(napi_get_uv_event_loop); + std.mem.doNotOptimizeAway(napi_add_env_cleanup_hook); + std.mem.doNotOptimizeAway(napi_remove_env_cleanup_hook); + std.mem.doNotOptimizeAway(napi_create_threadsafe_function); + std.mem.doNotOptimizeAway(napi_get_threadsafe_function_context); + std.mem.doNotOptimizeAway(napi_call_threadsafe_function); + std.mem.doNotOptimizeAway(napi_acquire_threadsafe_function); + std.mem.doNotOptimizeAway(napi_release_threadsafe_function); + std.mem.doNotOptimizeAway(napi_unref_threadsafe_function); + std.mem.doNotOptimizeAway(napi_ref_threadsafe_function); + std.mem.doNotOptimizeAway(napi_add_async_cleanup_hook); + std.mem.doNotOptimizeAway(napi_remove_async_cleanup_hook); +} + +comptime { + if (!JSC.is_bindgen) { + _ = napi_get_undefined; + _ = napi_get_null; + _ = napi_get_boolean; + _ = napi_create_object; + _ = napi_create_array; + _ = napi_create_array_with_length; + _ = napi_create_double; + _ = napi_create_int32; + _ = napi_create_uint32; + _ = napi_create_int64; + _ = napi_create_string_latin1; + _ = napi_create_string_utf8; + _ = napi_create_string_utf16; + _ = napi_create_symbol; + // _ = napi_create_function; + _ = napi_create_error; + _ = napi_typeof; + _ = napi_get_value_double; + _ = napi_get_value_int32; + _ = napi_get_value_uint32; + _ = napi_get_value_int64; + _ = napi_get_value_bool; + _ = napi_get_value_string_latin1; + _ = napi_get_value_string_utf8; + _ = napi_get_value_string_utf16; + _ = napi_coerce_to_bool; + _ = napi_coerce_to_number; + _ = napi_coerce_to_object; + // _ = napi_coerce_to_string; + _ = napi_get_prototype; + // _ = napi_get_property_names; + _ = napi_set_property; + _ = napi_has_property; + _ = napi_get_property; + _ = napi_delete_property; + _ = napi_has_own_property; + _ = napi_set_named_property; + _ = napi_has_named_property; + _ = napi_get_named_property; + _ = napi_set_element; + _ = napi_has_element; + _ = napi_get_element; + // _ = napi_delete_element; + _ = napi_is_array; + _ = napi_get_array_length; + _ = napi_strict_equals; + _ = napi_call_function; + _ = napi_new_instance; + _ = napi_instanceof; + _ = napi_open_handle_scope; + _ = napi_close_handle_scope; + _ = napi_is_error; + _ = napi_is_arraybuffer; + _ = napi_create_arraybuffer; + _ = napi_create_external_arraybuffer; + _ = napi_get_arraybuffer_info; + _ = napi_is_typedarray; + _ = napi_create_typedarray; + _ = napi_get_typedarray_info; + _ = napi_is_dataview; + _ = napi_get_dataview_info; + _ = napi_get_version; + _ = napi_create_promise; + _ = napi_resolve_deferred; + _ = napi_reject_deferred; + _ = napi_is_promise; + _ = napi_run_script; + _ = napi_create_date; + _ = napi_is_date; + _ = napi_get_date_value; + _ = napi_create_bigint_int64; + _ = napi_create_bigint_uint64; + _ = napi_get_value_bigint_int64; + _ = napi_get_value_bigint_uint64; + // _ = napi_module_register; + _ = napi_fatal_error; + // _ = napi_make_callback; + _ = napi_create_buffer; + _ = napi_create_external_buffer; + _ = napi_create_buffer_copy; + _ = napi_is_buffer; + _ = napi_get_buffer_info; + _ = napi_create_async_work; + _ = napi_delete_async_work; + _ = napi_queue_async_work; + _ = napi_cancel_async_work; + _ = napi_get_node_version; + _ = napi_get_uv_event_loop; + _ = napi_add_env_cleanup_hook; + _ = napi_remove_env_cleanup_hook; + _ = napi_create_threadsafe_function; + _ = napi_get_threadsafe_function_context; + _ = napi_call_threadsafe_function; + _ = napi_acquire_threadsafe_function; + _ = napi_release_threadsafe_function; + _ = napi_unref_threadsafe_function; + _ = napi_ref_threadsafe_function; + _ = napi_add_async_cleanup_hook; + _ = napi_remove_async_cleanup_hook; + } +} diff --git a/src/options.zig b/src/options.zig index 99a82c7cb..bb5af5a27 100644 --- a/src/options.zig +++ b/src/options.zig @@ -632,6 +632,8 @@ pub const Loader = enum(u4) { json, toml, wasm, + napi, + pub const Map = std.EnumArray(Loader, string); pub const stdin_name: Map = brk: { var map = Map.initFill(""); @@ -644,6 +646,7 @@ pub const Loader = enum(u4) { map.set(Loader.json, "input.json"); map.set(Loader.toml, "input.toml"); map.set(Loader.wasm, "input.wasm"); + map.set(Loader.napi, "input.node"); break :brk map; }; @@ -686,6 +689,7 @@ pub const Loader = enum(u4) { LoaderMatcher.case("json") => Loader.json, LoaderMatcher.case("toml") => Loader.toml, LoaderMatcher.case("wasm") => Loader.wasm, + LoaderMatcher.case("node") => Loader.napi, else => null, }; } @@ -707,6 +711,7 @@ pub const Loader = enum(u4) { .json => .json, .toml => .toml, .wasm => .wasm, + .napi => .napi, else => .file, }; } @@ -757,6 +762,7 @@ pub const defaultLoaders = ComptimeStringMap(Loader, .{ .{ ".toml", Loader.toml }, .{ ".wasm", Loader.wasm }, + .{ ".node", Loader.napi }, }); // https://webpack.js.org/guides/package-exports/#reference-syntax @@ -1032,23 +1038,43 @@ pub fn definesFromTransformOptions( ); } -pub fn loadersFromTransformOptions(allocator: std.mem.Allocator, _loaders: ?Api.LoaderMap) !std.StringHashMap(Loader) { +pub fn loadersFromTransformOptions(allocator: std.mem.Allocator, _loaders: ?Api.LoaderMap, platform: Platform) !std.StringHashMap(Loader) { var input_loaders = _loaders orelse std.mem.zeroes(Api.LoaderMap); var loader_values = try allocator.alloc(Loader, input_loaders.loaders.len); - for (loader_values) |_, i| { - const loader = switch (input_loaders.loaders[i]) { - .jsx => Loader.jsx, - .js => Loader.js, - .ts => Loader.ts, - .css => Loader.css, - .tsx => Loader.tsx, - .json => Loader.json, - .toml => Loader.toml, - .wasm => Loader.wasm, - else => unreachable, - }; - loader_values[i] = loader; + if (platform.isBun()) { + for (loader_values) |_, i| { + const loader = switch (input_loaders.loaders[i]) { + .jsx => Loader.jsx, + .js => Loader.js, + .ts => Loader.ts, + .css => Loader.css, + .tsx => Loader.tsx, + .json => Loader.json, + .toml => Loader.toml, + .wasm => Loader.wasm, + .napi => Loader.napi, + else => unreachable, + }; + + loader_values[i] = loader; + } + } else { + for (loader_values) |_, i| { + const loader = switch (input_loaders.loaders[i]) { + .jsx => Loader.jsx, + .js => Loader.js, + .ts => Loader.ts, + .css => Loader.css, + .tsx => Loader.tsx, + .json => Loader.json, + .toml => Loader.toml, + .wasm => Loader.wasm, + else => unreachable, + }; + + loader_values[i] = loader; + } } var loaders = try stringHashMapFromArrays( @@ -1069,12 +1095,22 @@ pub fn loadersFromTransformOptions(allocator: std.mem.Allocator, _loaders: ?Api. ".toml", ".wasm", }; + const default_loader_ext_bun = [_]string{".node"}; + inline for (default_loader_ext) |ext| { if (!loaders.contains(ext)) { try loaders.put(ext, defaultLoaders.get(ext).?); } } + if (platform.isBun()) { + inline for (default_loader_ext_bun) |ext| { + if (!loaders.contains(ext)) { + try loaders.put(ext, defaultLoaders.get(ext).?); + } + } + } + return loaders; } @@ -1258,7 +1294,7 @@ pub const BundleOptions = struct { .log = log, .resolve_mode = transform.resolve orelse .dev, .define = undefined, - .loaders = try loadersFromTransformOptions(allocator, transform.loaders), + .loaders = try loadersFromTransformOptions(allocator, transform.loaders, Platform.from(transform.platform)), .output_dir = transform.output_dir orelse "out", .platform = Platform.from(transform.platform), .write = transform.write orelse false, diff --git a/src/symbols.txt b/src/symbols.txt new file mode 100644 index 000000000..2ebc45f36 --- /dev/null +++ b/src/symbols.txt @@ -0,0 +1,105 @@ +_napi_acquire_threadsafe_function +_napi_add_async_cleanup_hook +_napi_add_env_cleanup_hook +_napi_call_function +_napi_call_threadsafe_function +_napi_cancel_async_work +_napi_close_handle_scope +_napi_coerce_to_bool +_napi_coerce_to_number +_napi_coerce_to_object +#_napi_coerce_to_string +_napi_create_array +_napi_create_array_with_length +_napi_create_arraybuffer +_napi_create_async_work +_napi_create_bigint_int64 +_napi_create_bigint_uint64 +_napi_create_buffer +_napi_create_buffer_copy +_napi_create_date +_napi_create_double +_napi_create_error +_napi_create_external_arraybuffer +_napi_create_external_buffer +_napi_create_function +_napi_create_function +_napi_create_int32 +_napi_create_int64 +_napi_create_object +_napi_create_promise +_napi_create_string_latin1 +_napi_create_string_utf16 +_napi_create_string_utf8 +_napi_create_symbol +_napi_create_threadsafe_function +_napi_create_typedarray +_napi_create_uint32 +_napi_delete_async_work +#_napi_delete_element +_napi_delete_property +_napi_fatal_error +_napi_get_array_length +_napi_get_arraybuffer_info +_napi_get_boolean +_napi_get_buffer_info +_napi_get_cb_info +_napi_get_dataview_info +_napi_get_date_value +_napi_get_element +_napi_get_named_property +_napi_get_node_version +_napi_get_null +_napi_get_property +#_napi_get_property_names +_napi_get_prototype +_napi_get_threadsafe_function_context +_napi_get_typedarray_info +_napi_get_undefined +_napi_get_uv_event_loop +_napi_get_value_bigint_int64 +_napi_get_value_bigint_uint64 +_napi_get_value_bool +_napi_get_value_double +_napi_get_value_int32 +_napi_get_value_int64 +_napi_get_value_string_latin1 +_napi_get_value_string_utf16 +_napi_get_value_string_utf8 +_napi_get_value_uint32 +_napi_get_version +_napi_has_element +_napi_has_named_property +_napi_has_own_property +_napi_has_property +_napi_instanceof +_napi_is_array +_napi_is_arraybuffer +_napi_is_buffer +_napi_is_dataview +_napi_is_date +_napi_is_error +_napi_is_promise +_napi_is_typedarray +#_napi_make_callback +_napi_module_register +_napi_module_register +_napi_new_instance +_napi_open_handle_scope +_napi_queue_async_work +_napi_ref_threadsafe_function +_napi_reject_deferred +_napi_release_threadsafe_function +_napi_remove_async_cleanup_hook +_napi_remove_env_cleanup_hook +_napi_resolve_deferred +_napi_run_script +_napi_set_element +_napi_set_named_property +_napi_set_property +_napi_strict_equals +_napi_throw_error +_napi_typeof +_napi_unref_threadsafe_function + +_napi_create_reference |