diff options
-rw-r--r-- | src/bun.js/bindings/napi.cpp | 88 | ||||
-rw-r--r-- | src/napi/napi.zig | 58 |
2 files changed, 79 insertions, 67 deletions
diff --git a/src/bun.js/bindings/napi.cpp b/src/bun.js/bindings/napi.cpp index c39dbd413..25e493554 100644 --- a/src/bun.js/bindings/napi.cpp +++ b/src/bun.js/bindings/napi.cpp @@ -685,11 +685,8 @@ extern "C" napi_status napi_get_cb_info( memcpy(argv, callFrame->addressOfArgumentsStart(), argsToCopy * sizeof(JSC::JSValue)); - // If the user didn't provide expected number of args, we need to fill the rest with undefined. - // TODO: can we use memset() here? - auto argv_ptr = argv[outputArgsCount]; for (size_t i = outputArgsCount; i < inputArgsCount; i++) { - argv[i] = reinterpret_cast<napi_value>(JSC::JSValue::encode(JSC::jsUndefined())); + argv[i] = toNapi(JSC::jsUndefined()); } } @@ -711,6 +708,8 @@ extern "C" napi_status napi_get_cb_info( *data = proto->napiRef ? proto->napiRef->data : nullptr; } else if (auto* proto = JSC::jsDynamicCast<NapiClass*>(thisValue)) { *data = proto->dataPtr; + } else if (auto* proto = JSC::jsDynamicCast<Bun::NapiExternal*>(thisValue)) { + *data = proto->value(); } else { *data = nullptr; } @@ -1455,6 +1454,78 @@ extern "C" napi_status napi_create_external(napi_env env, void* data, return napi_ok; } +extern "C" napi_status napi_typeof(napi_env env, napi_value val, + napi_valuetype* result) +{ + if (UNLIKELY(result == nullptr)) + return napi_invalid_arg; + + Zig::GlobalObject* globalObject = toJS(env); + JSC::VM& vm = globalObject->vm(); + + JSC::JSValue value = toJS(val); + + if (value.isEmpty()) { + return napi_invalid_arg; + } + + if (value.isCell()) { + JSC::JSCell* cell = value.asCell(); + + if (cell->isSymbol()) { + *result = napi_symbol; + return napi_ok; + } + + if (cell->isString()) { + *result = napi_string; + return napi_ok; + } + + if (value.isBigInt()) { + *result = napi_bigint; + return napi_ok; + } + + if (cell->isCallable() || cell->isConstructor()) { + *result = napi_function; + return napi_ok; + } + + if (JSC::jsDynamicCast<Bun::NapiExternal*>(value)) { + *result = napi_external; + return napi_ok; + } + + if (cell->isObject()) { + *result = napi_object; + return napi_ok; + } + } + + if (value.isNumber()) { + *result = napi_boolean; + return napi_ok; + } + + if (value.isUndefined()) { + *result = napi_undefined; + return napi_ok; + } + + if (value.isNull()) { + *result = napi_null; + return napi_ok; + } + + if (value.isBoolean()) { + *result = napi_boolean; + return napi_ok; + } + + return napi_generic_failure; +} + extern "C" napi_status napi_get_value_external(napi_env env, napi_value value, void** result) { @@ -1469,16 +1540,13 @@ extern "C" napi_status napi_get_value_external(napi_env env, napi_value value, JSC::JSValue jsValue = JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(value)); JSC::EnsureStillAliveScope ensureStillAlive(jsValue); - if (!jsValue || !jsValue.isObject()) { - return napi_invalid_arg; - } + auto* external = jsDynamicCast<Bun::NapiExternal*>(jsValue); - JSC::JSObject* object = jsValue.getObject(); - if (!object->inherits<Bun::NapiExternal>()) { + if (!external) { return napi_invalid_arg; } - *result = jsCast<Bun::NapiExternal*>(object)->value(); + *result = external->value(); return napi_ok; } diff --git a/src/napi/napi.zig b/src/napi/napi.zig index 8faecb040..09817f22c 100644 --- a/src/napi/napi.zig +++ b/src/napi/napi.zig @@ -287,63 +287,7 @@ pub export fn napi_create_error(env: napi_env, code: napi_value, msg: napi_value pub extern fn napi_create_type_error(env: napi_env, code: napi_value, msg: napi_value, result: *napi_value) napi_status; 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; - return .ok; - } - - if (value.isUndefined()) { - result.* = .undefined; - return .ok; - } - - if (value.isNull()) { - result.* = .null; - return .ok; - } - - if (value.isBoolean()) { - result.* = .boolean; - return .ok; - } - - if (value.isNumber()) { - result.* = .number; - return .ok; - } - - if (value.isString()) { - result.* = .string; - return .ok; - } - - if (value.isSymbol()) { - result.* = .symbol; - return .ok; - } - - if (value.isBigInt()) { - result.* = .bigint; - return .ok; - } - - if (value.isObject()) { - if (value.isCallable(env.vm())) { - result.* = .function; - return .ok; - } - result.* = .object; - return .ok; - } - - if (value.isCell() and value.isCallable(env.vm())) { - result.* = .function; - return .ok; - } - - return .invalid_arg; -} +pub extern fn napi_typeof(env: napi_env, value: napi_value, result: *napi_valuetype) napi_status; pub export fn napi_get_value_double(_: napi_env, value: napi_value, result: *f64) napi_status { result.* = value.asNumber(); return .ok; |