Skip to content

Commit

Permalink
fix(ext/node): napi_get_element and napi_set_element work with objects
Browse files Browse the repository at this point in the history
  • Loading branch information
bartlomieju committed May 6, 2024
1 parent 397be1a commit 40aff4e
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 4 deletions.
8 changes: 4 additions & 4 deletions cli/napi/js_native_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}

Expand Down
15 changes: 15 additions & 0 deletions tests/napi/object_test.js
Original file line number Diff line number Diff line change
@@ -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);
});
2 changes: 2 additions & 0 deletions tests/napi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
55 changes: 55 additions & 0 deletions tests/napi/src/object.rs
Original file line number Diff line number Diff line change
@@ -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()
));
}

0 comments on commit 40aff4e

Please sign in to comment.