summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/napi/js_native_api.rs40
-rw-r--r--ext/napi/lib.rs33
-rw-r--r--test_napi/object_wrap_test.js1
-rw-r--r--test_napi/src/object_wrap.rs19
4 files changed, 90 insertions, 3 deletions
diff --git a/cli/napi/js_native_api.rs b/cli/napi/js_native_api.rs
index 0c8bc31d7..c72da9b02 100644
--- a/cli/napi/js_native_api.rs
+++ b/cli/napi/js_native_api.rs
@@ -296,7 +296,6 @@ fn napi_create_error(
let msg = transmute::<napi_value, v8::Local<v8::Value>>(msg);
let msg = msg.to_string(&mut env.scope()).unwrap();
-
let error = v8::Exception::error(&mut env.scope(), msg);
*result = error.into();
@@ -1134,8 +1133,15 @@ fn napi_define_class(
let scope = &mut env.scope();
let napi_properties: &[napi_property_descriptor] =
std::slice::from_raw_parts(properties, property_count);
+ let mut static_property_count = 0;
for p in napi_properties {
+ if p.attributes & napi_static != 0 {
+ // Will be handled below
+ static_property_count += 1;
+ continue;
+ }
+
let name = if !p.utf8name.is_null() {
let name_str = CStr::from_ptr(p.utf8name).to_str().unwrap();
v8::String::new(scope, name_str).unwrap()
@@ -1197,9 +1203,37 @@ fn napi_define_class(
let value: v8::Local<v8::Value> = tpl.get_function(scope).unwrap().into();
*result = value.into();
+
+ if static_property_count > 0 {
+ let mut static_descriptors = Vec::with_capacity(static_property_count);
+
+ for p in napi_properties {
+ if p.attributes & napi_static != 0 {
+ static_descriptors.push(*p);
+ }
+ }
+
+ let res = napi_define_properties(
+ env_ptr,
+ *result,
+ static_descriptors.len(),
+ static_descriptors.as_ptr() as *const napi_property_descriptor,
+ );
+
+ napi_status_to_result(res)?;
+ }
+
Ok(())
}
+fn napi_status_to_result(status: napi_status) -> Result {
+ if status == napi_ok {
+ Ok(())
+ } else {
+ Err(status.into())
+ }
+}
+
#[napi_sym::napi_sym]
fn napi_define_properties(
env_ptr: *mut Env,
@@ -1211,10 +1245,10 @@ fn napi_define_properties(
let scope = &mut env.scope();
let object = transmute::<napi_value, v8::Local<v8::Object>>(obj);
let properties = std::slice::from_raw_parts(properties, property_count);
-
for property in properties {
let name = if !property.utf8name.is_null() {
- let name_str = CStr::from_ptr(property.utf8name).to_str().unwrap();
+ let name_str = CStr::from_ptr(property.utf8name);
+ let name_str = name_str.to_str().unwrap();
v8::String::new(scope, name_str).unwrap()
} else {
transmute::<napi_value, v8::Local<v8::String>>(property.name)
diff --git a/ext/napi/lib.rs b/ext/napi/lib.rs
index e76a08ed9..577545774 100644
--- a/ext/napi/lib.rs
+++ b/ext/napi/lib.rs
@@ -123,6 +123,38 @@ pub enum Error {
WouldDeadlock,
}
+#[allow(clippy::from_over_into)]
+impl Into<Error> for napi_status {
+ fn into(self) -> Error {
+ match self {
+ napi_invalid_arg => Error::InvalidArg,
+ napi_object_expected => Error::ObjectExpected,
+ napi_string_expected => Error::StringExpected,
+ napi_name_expected => Error::NameExpected,
+ napi_function_expected => Error::FunctionExpected,
+ napi_number_expected => Error::NumberExpected,
+ napi_boolean_expected => Error::BooleanExpected,
+ napi_array_expected => Error::ArrayExpected,
+ napi_generic_failure => Error::GenericFailure,
+ napi_pending_exception => Error::PendingException,
+ napi_cancelled => Error::Cancelled,
+ napi_escape_called_twice => Error::EscapeCalledTwice,
+ napi_handle_scope_mismatch => Error::HandleScopeMismatch,
+ napi_callback_scope_mismatch => Error::CallbackScopeMismatch,
+ napi_queue_full => Error::QueueFull,
+ napi_closing => Error::Closing,
+ napi_bigint_expected => Error::BigIntExpected,
+ napi_date_expected => Error::DateExpected,
+ napi_arraybuffer_expected => Error::ArrayBufferExpected,
+ napi_detachable_arraybuffer_expected => {
+ Error::DetachableArraybufferExpected
+ }
+ napi_would_deadlock => Error::WouldDeadlock,
+ _ => unreachable!(),
+ }
+ }
+}
+
pub type Result = std::result::Result<(), Error>;
impl From<Error> for napi_status {
@@ -603,6 +635,7 @@ where
),
)
};
+
Ok(serde_v8::Value {
v8_value: exports.into(),
})
diff --git a/test_napi/object_wrap_test.js b/test_napi/object_wrap_test.js
index 2522a8e6c..ae64821ea 100644
--- a/test_napi/object_wrap_test.js
+++ b/test_napi/object_wrap_test.js
@@ -14,4 +14,5 @@ Deno.test("napi object wrap new", function () {
obj.increment();
obj.set_value(10);
assertEquals(obj.get_value(), 10);
+ assertEquals(objectWrap.NapiObject.factory(), 64);
});
diff --git a/test_napi/src/object_wrap.rs b/test_napi/src/object_wrap.rs
index bedb6d852..5b15a16d7 100644
--- a/test_napi/src/object_wrap.rs
+++ b/test_napi/src/object_wrap.rs
@@ -1,5 +1,6 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use napi_sys::PropertyAttributes;
use napi_sys::Status::napi_ok;
use napi_sys::ValueType::napi_number;
use napi_sys::*;
@@ -116,13 +117,31 @@ impl NapiObject {
ptr::null_mut()
}
+
+ pub extern "C" fn factory(
+ env: napi_env,
+ info: napi_callback_info,
+ ) -> napi_value {
+ let (_args, argc, _this) = crate::get_callback_info!(env, info, 0);
+ assert_eq!(argc, 0);
+
+ let int64 = 64;
+ let mut value: napi_value = ptr::null_mut();
+ assert!(unsafe { napi_create_int64(env, int64, &mut value) } == napi_ok);
+ value
+ }
}
pub fn init(env: napi_env, exports: napi_value) {
+ let mut static_prop =
+ crate::new_property!(env, "factory\0", NapiObject::factory);
+ static_prop.attributes = PropertyAttributes::static_;
+
let properties = &[
crate::new_property!(env, "set_value\0", NapiObject::set_value),
crate::new_property!(env, "get_value\0", NapiObject::get_value),
crate::new_property!(env, "increment\0", NapiObject::increment),
+ static_prop,
];
let mut cons: napi_value = ptr::null_mut();