mirror of
https://github.com/denoland/deno.git
synced 2025-01-12 00:54:02 -05:00
fix(napi): handle static properties in classes (#17320)
Adds support for static properties when using "napi_define_class".
This commit is contained in:
parent
1c2db072b5
commit
aa79603674
4 changed files with 90 additions and 3 deletions
|
@ -296,7 +296,6 @@ fn napi_create_error(
|
||||||
let msg = transmute::<napi_value, v8::Local<v8::Value>>(msg);
|
let msg = transmute::<napi_value, v8::Local<v8::Value>>(msg);
|
||||||
|
|
||||||
let msg = msg.to_string(&mut env.scope()).unwrap();
|
let msg = msg.to_string(&mut env.scope()).unwrap();
|
||||||
|
|
||||||
let error = v8::Exception::error(&mut env.scope(), msg);
|
let error = v8::Exception::error(&mut env.scope(), msg);
|
||||||
*result = error.into();
|
*result = error.into();
|
||||||
|
|
||||||
|
@ -1134,8 +1133,15 @@ fn napi_define_class(
|
||||||
let scope = &mut env.scope();
|
let scope = &mut env.scope();
|
||||||
let napi_properties: &[napi_property_descriptor] =
|
let napi_properties: &[napi_property_descriptor] =
|
||||||
std::slice::from_raw_parts(properties, property_count);
|
std::slice::from_raw_parts(properties, property_count);
|
||||||
|
let mut static_property_count = 0;
|
||||||
|
|
||||||
for p in napi_properties {
|
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 = if !p.utf8name.is_null() {
|
||||||
let name_str = CStr::from_ptr(p.utf8name).to_str().unwrap();
|
let name_str = CStr::from_ptr(p.utf8name).to_str().unwrap();
|
||||||
v8::String::new(scope, name_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();
|
let value: v8::Local<v8::Value> = tpl.get_function(scope).unwrap().into();
|
||||||
*result = value.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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn napi_status_to_result(status: napi_status) -> Result {
|
||||||
|
if status == napi_ok {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(status.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[napi_sym::napi_sym]
|
#[napi_sym::napi_sym]
|
||||||
fn napi_define_properties(
|
fn napi_define_properties(
|
||||||
env_ptr: *mut Env,
|
env_ptr: *mut Env,
|
||||||
|
@ -1211,10 +1245,10 @@ fn napi_define_properties(
|
||||||
let scope = &mut env.scope();
|
let scope = &mut env.scope();
|
||||||
let object = transmute::<napi_value, v8::Local<v8::Object>>(obj);
|
let object = transmute::<napi_value, v8::Local<v8::Object>>(obj);
|
||||||
let properties = std::slice::from_raw_parts(properties, property_count);
|
let properties = std::slice::from_raw_parts(properties, property_count);
|
||||||
|
|
||||||
for property in properties {
|
for property in properties {
|
||||||
let name = if !property.utf8name.is_null() {
|
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()
|
v8::String::new(scope, name_str).unwrap()
|
||||||
} else {
|
} else {
|
||||||
transmute::<napi_value, v8::Local<v8::String>>(property.name)
|
transmute::<napi_value, v8::Local<v8::String>>(property.name)
|
||||||
|
|
|
@ -123,6 +123,38 @@ pub enum Error {
|
||||||
WouldDeadlock,
|
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>;
|
pub type Result = std::result::Result<(), Error>;
|
||||||
|
|
||||||
impl From<Error> for napi_status {
|
impl From<Error> for napi_status {
|
||||||
|
@ -603,6 +635,7 @@ where
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(serde_v8::Value {
|
Ok(serde_v8::Value {
|
||||||
v8_value: exports.into(),
|
v8_value: exports.into(),
|
||||||
})
|
})
|
||||||
|
|
|
@ -14,4 +14,5 @@ Deno.test("napi object wrap new", function () {
|
||||||
obj.increment();
|
obj.increment();
|
||||||
obj.set_value(10);
|
obj.set_value(10);
|
||||||
assertEquals(obj.get_value(), 10);
|
assertEquals(obj.get_value(), 10);
|
||||||
|
assertEquals(objectWrap.NapiObject.factory(), 64);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use napi_sys::PropertyAttributes;
|
||||||
use napi_sys::Status::napi_ok;
|
use napi_sys::Status::napi_ok;
|
||||||
use napi_sys::ValueType::napi_number;
|
use napi_sys::ValueType::napi_number;
|
||||||
use napi_sys::*;
|
use napi_sys::*;
|
||||||
|
@ -116,13 +117,31 @@ impl NapiObject {
|
||||||
|
|
||||||
ptr::null_mut()
|
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) {
|
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 = &[
|
let properties = &[
|
||||||
crate::new_property!(env, "set_value\0", NapiObject::set_value),
|
crate::new_property!(env, "set_value\0", NapiObject::set_value),
|
||||||
crate::new_property!(env, "get_value\0", NapiObject::get_value),
|
crate::new_property!(env, "get_value\0", NapiObject::get_value),
|
||||||
crate::new_property!(env, "increment\0", NapiObject::increment),
|
crate::new_property!(env, "increment\0", NapiObject::increment),
|
||||||
|
static_prop,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut cons: napi_value = ptr::null_mut();
|
let mut cons: napi_value = ptr::null_mut();
|
||||||
|
|
Loading…
Reference in a new issue