From f698bc70e2f1d4cd58d17544258cf1b19726b66a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 6 May 2024 20:22:50 +0100 Subject: [PATCH] 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. --- cli/napi/js_native_api.rs | 8 +++--- tests/napi/object_test.js | 15 +++++++++++ tests/napi/src/lib.rs | 2 ++ tests/napi/src/object.rs | 55 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 tests/napi/object_test.js create mode 100644 tests/napi/src/object.rs diff --git a/cli/napi/js_native_api.rs b/cli/napi/js_native_api.rs index 126f2109cb..428c4a04a0 100644 --- a/cli/napi/js_native_api.rs +++ b/cli/napi/js_native_api.rs @@ -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::::try_from(object) else { + let Ok(object) = v8::Local::::try_from(object) else { return napi_invalid_arg; }; let value: v8::Local = - 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::::try_from(object) else { + let Ok(object) = v8::Local::::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 } diff --git a/tests/napi/object_test.js b/tests/napi/object_test.js new file mode 100644 index 0000000000..4bc5c3c9c4 --- /dev/null +++ b/tests/napi/object_test.js @@ -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); +}); diff --git a/tests/napi/src/lib.rs b/tests/napi/src/lib.rs index b9f93fbd69..1b92464835 100644 --- a/tests/napi/src/lib.rs +++ b/tests/napi/src/lib.rs @@ -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); diff --git a/tests/napi/src/object.rs b/tests/napi/src/object.rs new file mode 100644 index 0000000000..aa34133dcf --- /dev/null +++ b/tests/napi/src/object.rs @@ -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() + )); +}