fix(ext/node): napi_get_element and napi_set_element work with objects (#23713)

This change makes DuckDB example work:
https://github.com/denoland/deno/issues/23656.
This commit is contained in:
Bartek Iwańczuk 2024-05-06 20:22:50 +01:00 committed by GitHub
parent a635abbf21
commit f698bc70e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 76 additions and 4 deletions

View File

@ -1855,11 +1855,11 @@ fn napi_get_element(
check_env!(env);
let env = unsafe { &mut *env };
let object = napi_value_unchecked(object);
let Ok(array) = v8::Local::<v8::Array>::try_from(object) else {
let Ok(object) = v8::Local::<v8::Object>::try_from(object) else {
return napi_invalid_arg;
};
let value: v8::Local<v8::Value> =
array.get_index(&mut env.scope(), index).unwrap();
object.get_index(&mut env.scope(), index).unwrap();
*result = value.into();
napi_ok
}
@ -2521,11 +2521,11 @@ fn napi_set_element(
check_env!(env);
let env = unsafe { &mut *env };
let object = napi_value_unchecked(object);
let Ok(array) = v8::Local::<v8::Array>::try_from(object) else {
let Ok(object) = v8::Local::<v8::Object>::try_from(object) else {
return napi_invalid_arg;
};
let value = napi_value_unchecked(value);
array.set_index(&mut env.scope(), index, value).unwrap();
object.set_index(&mut env.scope(), index, value).unwrap();
napi_ok
}

15
tests/napi/object_test.js Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assert, assertEquals, loadTestLibrary } from "./common.js";
const object = loadTestLibrary();
Deno.test("napi object", function () {
const r = object.test_object_new(1, "hello");
assertEquals(typeof r, "object");
assertEquals(r[0], 1);
assertEquals(r[1], "hello");
const r1 = object.test_object_get(r);
assert(r === r1);
});

View File

@ -19,6 +19,7 @@ pub mod finalizer;
pub mod make_callback;
pub mod mem;
pub mod numbers;
pub mod object;
pub mod object_wrap;
pub mod primitives;
pub mod promise;
@ -164,6 +165,7 @@ unsafe extern "C" fn napi_register_module_v1(
bigint::init(env, exports);
symbol::init(env, exports);
make_callback::init(env, exports);
object::init(env, exports);
init_cleanup_hook(env, exports);

55
tests/napi/src/object.rs Normal file
View File

@ -0,0 +1,55 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::assert_napi_ok;
use crate::napi_get_callback_info;
use crate::napi_new_property;
use napi_sys::*;
use std::ptr;
extern "C" fn test_object_new(
env: napi_env,
info: napi_callback_info,
) -> napi_value {
let (args, argc, _) = napi_get_callback_info!(env, info, 2);
assert_eq!(argc, 2);
let mut value: napi_value = ptr::null_mut();
assert_napi_ok!(napi_create_object(env, &mut value));
assert_napi_ok!(napi_set_element(env, value, 0, args[0]));
assert_napi_ok!(napi_set_element(env, value, 1, args[1]));
value
}
extern "C" fn test_object_get(
env: napi_env,
info: napi_callback_info,
) -> napi_value {
let (args, argc, _) = napi_get_callback_info!(env, info, 1);
assert_eq!(argc, 1);
let obj = args[0];
assert_napi_ok!(napi_set_element(env, obj, 0, args[0]));
let mut value: napi_value = ptr::null_mut();
assert_napi_ok!(napi_get_element(env, obj, 0, &mut value));
let mut value: napi_value = ptr::null_mut();
assert_napi_ok!(napi_get_element(env, obj, 1, &mut value));
obj
}
pub fn init(env: napi_env, exports: napi_value) {
let properties = &[
napi_new_property!(env, "test_object_new", test_object_new),
napi_new_property!(env, "test_object_get", test_object_get),
];
assert_napi_ok!(napi_define_properties(
env,
exports,
properties.len(),
properties.as_ptr()
));
}