Implement node_api_create_external_string_latin1 and node_api_create_external_string_utf16 (#5675)

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
This commit is contained in:
Jarred Sumner
2023-09-18 17:31:26 -07:00
committed by GitHub
parent 333e217c32
commit 79dd196edd
5 changed files with 91 additions and 4 deletions

View File

@@ -3903,6 +3903,10 @@ pub const JSValue = enum(JSValueReprInt) {
return jsNumberFromInt32(@as(i32, @intCast(i)));
}
return jsNumberFromPtrSize(i);
}
pub fn jsNumberFromPtrSize(i: usize) JSValue {
return jsNumberFromDouble(@as(f64, @floatFromInt(@as(i52, @intCast(@as(u51, @truncate(i)))))));
}

View File

@@ -503,6 +503,81 @@ extern "C" napi_status napi_get_named_property(napi_env env, napi_value object,
return napi_ok;
}
#if !COMPILER(MSVC)
__attribute__((visibility("default")))
#endif
extern "C" napi_status
node_api_create_external_string_latin1(napi_env env,
char* str,
size_t length,
napi_finalize finalize_callback,
void* finalize_hint,
napi_value* result,
bool* copied)
{
// https://nodejs.org/api/n-api.html#node_api_create_external_string_latin1
if (UNLIKELY(!str || !result)) {
return napi_invalid_arg;
}
length = length == NAPI_AUTO_LENGTH ? strlen(str) : length;
WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create(reinterpret_cast<LChar*>(str), static_cast<unsigned int>(length), finalize_hint, [finalize_callback](void* hint, void* str, unsigned length) {
if (finalize_callback) {
finalize_callback(reinterpret_cast<napi_env>(Bun__getDefaultGlobal()), nullptr, hint);
}
});
JSGlobalObject* globalObject = toJS(env);
// globalObject is allowed to be null here
if (UNLIKELY(!globalObject)) {
globalObject = Bun__getDefaultGlobal();
}
JSString* out = JSC::jsString(globalObject->vm(), WTF::String(impl));
ensureStillAliveHere(out);
*result = toNapi(out);
ensureStillAliveHere(out);
return napi_ok;
}
#if !COMPILER(MSVC)
__attribute__((visibility("default")))
#endif
extern "C" napi_status
node_api_create_external_string_utf16(napi_env env,
char16_t* str,
size_t length,
napi_finalize finalize_callback,
void* finalize_hint,
napi_value* result,
bool* copied)
{
// https://nodejs.org/api/n-api.html#node_api_create_external_string_utf16
if (UNLIKELY(!str || !result)) {
return napi_invalid_arg;
}
length = length == NAPI_AUTO_LENGTH ? std::char_traits<char16_t>::length(str) : length;
WTF::ExternalStringImpl& impl = WTF::ExternalStringImpl::create(reinterpret_cast<UChar*>(str), static_cast<unsigned int>(length), finalize_hint, [finalize_callback](void* hint, void* str, unsigned length) {
if (finalize_callback) {
finalize_callback(reinterpret_cast<napi_env>(Bun__getDefaultGlobal()), nullptr, hint);
}
});
JSGlobalObject* globalObject = toJS(env);
// globalObject is allowed to be null here
if (UNLIKELY(!globalObject)) {
globalObject = Bun__getDefaultGlobal();
}
JSString* out = JSC::jsString(globalObject->vm(), WTF::String(impl));
ensureStillAliveHere(out);
*result = toNapi(out);
ensureStillAliveHere(out);
return napi_ok;
}
extern "C" void napi_module_register(napi_module* mod)
{
auto* globalObject = Bun__getDefaultGlobal();

View File

@@ -309,14 +309,14 @@ pub extern 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 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 {
pub export fn napi_get_value_double(globalObject: napi_env, value: napi_value, result: *f64) napi_status {
log("napi_get_value_double", .{});
result.* = value.asNumber();
result.* = value.coerce(f64, globalObject);
return .ok;
}
pub export fn napi_get_value_int32(_: napi_env, value: napi_value, result: *i32) napi_status {
pub export fn napi_get_value_int32(globalObject: napi_env, value: napi_value, result: *i32) napi_status {
log("napi_get_value_int32", .{});
result.* = value.to(i32);
result.* = value.coerce(i32, globalObject);
return .ok;
}
pub export fn napi_get_value_uint32(_: napi_env, value: napi_value, result: *u32) napi_status {
@@ -1097,6 +1097,8 @@ pub export fn napi_get_buffer_info(env: napi_env, value: napi_value, data: *[*]u
extern fn node_api_create_syntax_error(napi_env, napi_value, napi_value, *napi_value) napi_status;
extern fn node_api_symbol_for(napi_env, [*]const c_char, usize, *napi_value) napi_status;
extern fn node_api_throw_syntax_error(napi_env, [*]const c_char, [*]const c_char) napi_status;
extern fn node_api_create_external_string_latin1(napi_env, [*:0]u8, usize, napi_finalize, ?*anyopaque, *JSValue, *bool) napi_status;
extern fn node_api_create_external_string_utf16(napi_env, [*:0]u16, usize, napi_finalize, ?*anyopaque, *JSValue, *bool) napi_status;
pub export fn napi_create_async_work(
env: napi_env,
@@ -1617,5 +1619,7 @@ pub fn fixDeadCodeElimination() void {
std.mem.doNotOptimizeAway(&node_api_create_syntax_error);
std.mem.doNotOptimizeAway(&node_api_symbol_for);
std.mem.doNotOptimizeAway(&node_api_throw_syntax_error);
std.mem.doNotOptimizeAway(&node_api_create_external_string_latin1);
std.mem.doNotOptimizeAway(&node_api_create_external_string_utf16);
std.mem.doNotOptimizeAway(&@import("../bun.js/node/buffer.zig").BufferVectorized.fill);
}

View File

@@ -146,4 +146,6 @@
_node_api_create_syntax_error;
_node_api_symbol_for;
_node_api_throw_syntax_error;
_node_api_create_external_string_latin1;
_node_api_create_external_string_utf16;
};

View File

@@ -145,3 +145,5 @@ _napi_wrap
_node_api_create_syntax_error
_node_api_symbol_for
_node_api_throw_syntax_error
_node_api_create_external_string_latin1
_node_api_create_external_string_utf16