diff options
author | 2023-06-02 21:56:16 -0300 | |
---|---|---|
committer | 2023-06-02 17:56:16 -0700 | |
commit | 51846d0277aa58a69557668cb930448bd62de0bf (patch) | |
tree | 04c1647955fde3f89bdc548d73651605f81f6d9f | |
parent | c4f237572d87fea2de1a3cc307e4df176c48a769 (diff) | |
download | bun-51846d0277aa58a69557668cb930448bd62de0bf.tar.gz bun-51846d0277aa58a69557668cb930448bd62de0bf.tar.zst bun-51846d0277aa58a69557668cb930448bd62de0bf.zip |
[napi] some fixes for prisma (#3176)
* patch create object, so it can be used on wrap
* cleanup
* cleanup
* dont override napiRef
* make wrap strong ref
* workaround tests
* remove work around
-rw-r--r-- | src/bun.js/bindings/napi.cpp | 41 | ||||
-rw-r--r-- | src/napi/js_native_api.h | 2 | ||||
-rw-r--r-- | src/napi/napi.zig | 20 |
3 files changed, 46 insertions, 17 deletions
diff --git a/src/bun.js/bindings/napi.cpp b/src/bun.js/bindings/napi.cpp index 97f3222c9..a859e3ac5 100644 --- a/src/bun.js/bindings/napi.cpp +++ b/src/bun.js/bindings/napi.cpp @@ -554,6 +554,8 @@ extern "C" napi_status napi_wrap(napi_env env, auto* globalObject = toJS(env); auto& vm = globalObject->vm(); + + auto* val = jsDynamicCast<NapiPrototype*>(value); if (!val) { @@ -569,8 +571,8 @@ extern "C" napi_status napi_wrap(napi_env env, auto clientData = WebCore::clientData(vm); - auto* ref = new NapiRef(globalObject, 0); - ref->weakValueRef.setObject(val, weakValueHandleOwner(), ref); + auto* ref = new NapiRef(globalObject, 1); + ref->strongRef.set(globalObject->vm(), value.getObject()); if (finalize_cb) { ref->finalizer.finalize_cb = finalize_cb; @@ -584,7 +586,7 @@ extern "C" napi_status napi_wrap(napi_env env, val->napiRef = ref; if (result) { - *result = reinterpret_cast<napi_ref>(ref); + *result = toNapi(ref); } return napi_ok; @@ -623,12 +625,14 @@ extern "C" napi_status napi_remove_wrap(napi_env env, napi_value js_object, extern "C" napi_status napi_unwrap(napi_env env, napi_value js_object, void** result) { - if (!toJS(js_object).isObject()) { + JSValue value = toJS(js_object); + + if (!value.isObject()) { return NAPI_OBJECT_EXPECTED; } auto* globalObject = toJS(env); auto& vm = globalObject->vm(); - auto* object = JSC::jsDynamicCast<NapiPrototype*>(toJS(js_object)); + auto* object = JSC::jsDynamicCast<NapiPrototype*>(value); auto clientData = WebCore::clientData(vm); if (object) { @@ -793,10 +797,13 @@ extern "C" napi_status napi_create_reference(napi_env env, napi_value value, Zig::GlobalObject* globalObject = toJS(env); JSC::VM& vm = globalObject->vm(); - auto* ref = new NapiRef(toJS(env), initial_refcount); - + NapiPrototype* object = jsDynamicCast<NapiPrototype*>(val); + if (object && object->napiRef) { + *result = toNapi(object->napiRef); + return napi_ok; + } auto clientData = WebCore::clientData(vm); - + auto* ref = new NapiRef(globalObject, initial_refcount); if (initial_refcount > 0) { ref->strongRef.set(globalObject->vm(), val); } else { @@ -809,7 +816,7 @@ extern "C" napi_status napi_create_reference(napi_env env, napi_value value, } } - if (NapiPrototype* object = jsDynamicCast<NapiPrototype*>(val)) { + if(object) { object->napiRef = ref; } @@ -1467,6 +1474,22 @@ extern "C" napi_status napi_get_property_names(napi_env env, napi_value object, return napi_ok; } +extern "C" napi_status napi_create_object(napi_env env, napi_value* result){ + + if (UNLIKELY(result == nullptr)) { + return napi_invalid_arg; + } + + Zig::GlobalObject* globalObject = toJS(env); + JSC::VM& vm = globalObject->vm(); + + JSValue value = JSValue(NapiPrototype::create(vm, globalObject)); + + *result = toNapi(value); + JSC::EnsureStillAliveScope ensureStillAlive(value); + + return napi_ok; +} extern "C" napi_status napi_create_external(napi_env env, void* data, napi_finalize finalize_cb, void* finalize_hint, diff --git a/src/napi/js_native_api.h b/src/napi/js_native_api.h index 40db9dec2..e84f5444c 100644 --- a/src/napi/js_native_api.h +++ b/src/napi/js_native_api.h @@ -238,6 +238,8 @@ NAPI_EXTERN napi_status napi_unwrap(napi_env env, napi_value js_object, void **result); NAPI_EXTERN napi_status napi_remove_wrap(napi_env env, napi_value js_object, void **result); +NAPI_EXTERN napi_status napi_create_object(napi_env env, + napi_value *result); NAPI_EXTERN napi_status napi_create_external(napi_env env, void *data, napi_finalize finalize_cb, void *finalize_hint, diff --git a/src/napi/napi.zig b/src/napi/napi.zig index 227a80d05..5f94dac90 100644 --- a/src/napi/napi.zig +++ b/src/napi/napi.zig @@ -219,11 +219,6 @@ pub export fn napi_get_boolean(_: napi_env, value: bool, result: *napi_value) na result.* = JSValue.jsBoolean(value); return .ok; } -pub export fn napi_create_object(env: napi_env, result: *napi_value) napi_status { - log("napi_create_object", .{}); - result.* = JSValue.createEmptyObject(env, 0); - return .ok; -} pub export fn napi_create_array(env: napi_env, result: *napi_value) napi_status { log("napi_create_array", .{}); result.* = JSValue.c(JSC.C.JSObjectMakeArray(env.ref(), 0, null, null)); @@ -408,6 +403,7 @@ pub export fn napi_get_value_string_latin1(env: napi_env, value: napi_value, buf /// The result argument is optional unless buf is NULL. pub export fn napi_get_value_string_utf8(env: napi_env, value: napi_value, buf_ptr: [*c]u8, bufsize: usize, result_ptr: ?*usize) napi_status { defer value.ensureStillAlive(); + if (!value.isString()) { return .string_expected; } @@ -653,6 +649,7 @@ pub extern fn napi_define_class( pub extern fn napi_wrap(env: napi_env, js_object: napi_value, native_object: ?*anyopaque, finalize_cb: napi_finalize, finalize_hint: ?*anyopaque, result: [*]*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; +pub extern fn napi_create_object(env: napi_env, result: *napi_value) napi_status; pub extern fn napi_create_external(env: napi_env, data: ?*anyopaque, finalize_cb: napi_finalize, finalize_hint: ?*anyopaque, result: *napi_value) napi_status; pub extern fn napi_get_value_external(env: napi_env, value: napi_value, result: [*]*anyopaque) napi_status; pub extern fn napi_create_reference(env: napi_env, value: napi_value, initial_refcount: u32, result: **Ref) napi_status; @@ -1403,6 +1400,9 @@ pub const ThreadSafeFunction = struct { var task = this.channel.tryReadItem() catch null orelse return; switch (this.callback) { .js => |js_function| { + if (js_function.isEmptyOrUndefinedOrNull()) { + return; + } const err = js_function.call(this.env, &.{}); if (err.isAnyError()) { this.env.bunVM().onUnhandledError(this.env, err); @@ -1433,9 +1433,13 @@ pub const ThreadSafeFunction = struct { } if (this.callback == .js) { - this.callback.js.unprotect(); + if (!this.callback.js.isEmptyOrUndefinedOrNull()) { + this.callback.js.unprotect(); + } } else if (this.callback == .c) { - this.callback.c.js.unprotect(); + if (!this.callback.c.js.isEmptyOrUndefinedOrNull()) { + this.callback.c.js.unprotect(); + } } bun.default_allocator.destroy(this); } @@ -1506,7 +1510,7 @@ pub export fn napi_create_threadsafe_function( .js = if (func == .zero) JSC.JSValue.jsUndefined() else func, }, } else .{ - .js = func, + .js = if (func == .zero) JSC.JSValue.jsUndefined() else func, }, .ctx = context, .channel = ThreadSafeFunction.Queue.init(max_queue_size, bun.default_allocator), |