mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
fix(cli/napi): handle all property variants in napi_define_properties (#17680)
Fixes https://github.com/denoland/deno/issues/17509 This fixes the bug that blocked loading `fsevents` in Deno.
This commit is contained in:
parent
1740e0fc36
commit
4baaa246a2
4 changed files with 110 additions and 38 deletions
|
@ -1423,27 +1423,68 @@ fn napi_define_properties(
|
||||||
properties: *const napi_property_descriptor,
|
properties: *const napi_property_descriptor,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
let env: &mut Env = env_ptr.as_mut().ok_or(Error::InvalidArg)?;
|
let env: &mut Env = env_ptr.as_mut().ok_or(Error::InvalidArg)?;
|
||||||
|
if property_count > 0 {
|
||||||
|
check_arg!(env, properties);
|
||||||
|
}
|
||||||
|
|
||||||
let scope = &mut env.scope();
|
let scope = &mut env.scope();
|
||||||
let object = transmute::<napi_value, v8::Local<v8::Object>>(obj);
|
|
||||||
|
let object: v8::Local<v8::Object> = napi_value_unchecked(obj)
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| Error::ObjectExpected)?;
|
||||||
|
|
||||||
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);
|
let name_str = CStr::from_ptr(property.utf8name).to_str().unwrap();
|
||||||
let name_str = name_str.to_str().unwrap();
|
v8::String::new(scope, name_str).ok_or(Error::GenericFailure)?
|
||||||
v8::String::new(scope, name_str).unwrap()
|
|
||||||
} else {
|
} else {
|
||||||
transmute::<napi_value, v8::Local<v8::String>>(property.name)
|
let property_value = napi_value_unchecked(property.name);
|
||||||
|
v8::Local::<v8::String>::try_from(property_value)
|
||||||
|
.map_err(|_| Error::NameExpected)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let method_ptr = property.method;
|
if property.getter.is_some() || property.setter.is_some() {
|
||||||
|
let local_getter: v8::Local<v8::Value> = if property.getter.is_some() {
|
||||||
|
create_function(env_ptr, None, property.getter, property.data).into()
|
||||||
|
} else {
|
||||||
|
v8::undefined(scope).into()
|
||||||
|
};
|
||||||
|
let local_setter: v8::Local<v8::Value> = if property.setter.is_some() {
|
||||||
|
create_function(env_ptr, None, property.setter, property.data).into()
|
||||||
|
} else {
|
||||||
|
v8::undefined(scope).into()
|
||||||
|
};
|
||||||
|
|
||||||
if method_ptr.is_some() {
|
let mut desc =
|
||||||
let function: v8::Local<v8::Value> = {
|
v8::PropertyDescriptor::new_from_get_set(local_getter, local_setter);
|
||||||
|
desc.set_enumerable(property.attributes & napi_enumerable != 0);
|
||||||
|
desc.set_configurable(property.attributes & napi_configurable != 0);
|
||||||
|
|
||||||
|
let define_maybe = object.define_property(scope, name.into(), &desc);
|
||||||
|
return_status_if_false!(
|
||||||
|
env_ptr,
|
||||||
|
!define_maybe.unwrap_or(false),
|
||||||
|
napi_invalid_arg
|
||||||
|
);
|
||||||
|
} else if property.method.is_some() {
|
||||||
|
let value: v8::Local<v8::Value> = {
|
||||||
let function =
|
let function =
|
||||||
create_function(env_ptr, None, property.method, property.data);
|
create_function(env_ptr, None, property.method, property.data);
|
||||||
function.into()
|
function.into()
|
||||||
};
|
};
|
||||||
object.set(scope, name.into(), function).unwrap();
|
return_status_if_false!(
|
||||||
|
env_ptr,
|
||||||
|
object.set(scope, name.into(), value).is_some(),
|
||||||
|
napi_invalid_arg
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let value = napi_value_unchecked(property.value);
|
||||||
|
return_status_if_false!(
|
||||||
|
env_ptr,
|
||||||
|
object.set(scope, name.into(), value).is_some(),
|
||||||
|
napi_invalid_arg
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,14 @@ import { assertEquals, loadTestLibrary } from "./common.js";
|
||||||
const properties = loadTestLibrary();
|
const properties = loadTestLibrary();
|
||||||
|
|
||||||
Deno.test("napi properties", () => {
|
Deno.test("napi properties", () => {
|
||||||
properties.test_property_rw = 1;
|
|
||||||
assertEquals(properties.test_property_rw, 1);
|
assertEquals(properties.test_property_rw, 1);
|
||||||
properties.test_property_rw = 2;
|
properties.test_property_rw = 2;
|
||||||
assertEquals(properties.test_property_rw, 2);
|
assertEquals(properties.test_property_rw, 2);
|
||||||
|
|
||||||
// assertEquals(properties.test_property_r, 2);
|
assertEquals(properties.test_property_r, 1);
|
||||||
// assertRejects(() => properties.test_property_r = 3);
|
|
||||||
|
// https://github.com/denoland/deno/issues/17509
|
||||||
|
assertEquals(properties.test_simple_property, {
|
||||||
|
nice: 69,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub mod typedarray;
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! cstr {
|
macro_rules! cstr {
|
||||||
($s: literal) => {{
|
($s: literal) => {{
|
||||||
std::ffi::CString::new($s).unwrap().as_ptr()
|
std::ffi::CString::new($s).unwrap().into_raw()
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,28 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use crate::assert_napi_ok;
|
use crate::assert_napi_ok;
|
||||||
|
use crate::cstr;
|
||||||
use napi_sys::PropertyAttributes::*;
|
use napi_sys::PropertyAttributes::*;
|
||||||
use napi_sys::*;
|
use napi_sys::*;
|
||||||
use std::os::raw::c_char;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
static NICE: i64 = 69;
|
||||||
|
|
||||||
|
fn init_constants(env: napi_env) -> napi_value {
|
||||||
|
let mut constants: napi_value = ptr::null_mut();
|
||||||
|
let mut value: napi_value = ptr::null_mut();
|
||||||
|
|
||||||
|
assert_napi_ok!(napi_create_object(env, &mut constants));
|
||||||
|
assert_napi_ok!(napi_create_int64(env, NICE, &mut value));
|
||||||
|
assert_napi_ok!(napi_set_named_property(
|
||||||
|
env,
|
||||||
|
constants,
|
||||||
|
cstr!("nice"),
|
||||||
|
value
|
||||||
|
));
|
||||||
|
constants
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init(env: napi_env, exports: napi_value) {
|
pub fn init(env: napi_env, exports: napi_value) {
|
||||||
let mut number: napi_value = ptr::null_mut();
|
let mut number: napi_value = ptr::null_mut();
|
||||||
assert_napi_ok!(napi_create_double(env, 1.0, &mut number));
|
assert_napi_ok!(napi_create_double(env, 1.0, &mut number));
|
||||||
|
@ -14,7 +31,7 @@ pub fn init(env: napi_env, exports: napi_value) {
|
||||||
let mut name_value: napi_value = ptr::null_mut();
|
let mut name_value: napi_value = ptr::null_mut();
|
||||||
assert_napi_ok!(napi_create_string_utf8(
|
assert_napi_ok!(napi_create_string_utf8(
|
||||||
env,
|
env,
|
||||||
"key_v8_string".as_ptr() as *const c_char,
|
cstr!("key_v8_string"),
|
||||||
usize::MAX,
|
usize::MAX,
|
||||||
&mut name_value,
|
&mut name_value,
|
||||||
));
|
));
|
||||||
|
@ -24,7 +41,7 @@ pub fn init(env: napi_env, exports: napi_value) {
|
||||||
let mut name_symbol: napi_value = ptr::null_mut();
|
let mut name_symbol: napi_value = ptr::null_mut();
|
||||||
assert_napi_ok!(napi_create_string_utf8(
|
assert_napi_ok!(napi_create_string_utf8(
|
||||||
env,
|
env,
|
||||||
"key_v8_symbol".as_ptr() as *const c_char,
|
cstr!("key_v8_symbol"),
|
||||||
usize::MAX,
|
usize::MAX,
|
||||||
&mut symbol_description,
|
&mut symbol_description,
|
||||||
));
|
));
|
||||||
|
@ -36,7 +53,17 @@ pub fn init(env: napi_env, exports: napi_value) {
|
||||||
|
|
||||||
let properties = &[
|
let properties = &[
|
||||||
napi_property_descriptor {
|
napi_property_descriptor {
|
||||||
utf8name: "test_property_rw\0".as_ptr() as *const c_char,
|
utf8name: cstr!("test_simple_property"),
|
||||||
|
name: ptr::null_mut(),
|
||||||
|
method: None,
|
||||||
|
getter: None,
|
||||||
|
setter: None,
|
||||||
|
data: ptr::null_mut(),
|
||||||
|
attributes: enumerable | writable,
|
||||||
|
value: init_constants(env),
|
||||||
|
},
|
||||||
|
napi_property_descriptor {
|
||||||
|
utf8name: cstr!("test_property_rw"),
|
||||||
name: ptr::null_mut(),
|
name: ptr::null_mut(),
|
||||||
method: None,
|
method: None,
|
||||||
getter: None,
|
getter: None,
|
||||||
|
@ -46,7 +73,7 @@ pub fn init(env: napi_env, exports: napi_value) {
|
||||||
value: number,
|
value: number,
|
||||||
},
|
},
|
||||||
napi_property_descriptor {
|
napi_property_descriptor {
|
||||||
utf8name: "test_property_r\0".as_ptr() as *const c_char,
|
utf8name: cstr!("test_property_r"),
|
||||||
name: ptr::null_mut(),
|
name: ptr::null_mut(),
|
||||||
method: None,
|
method: None,
|
||||||
getter: None,
|
getter: None,
|
||||||
|
@ -55,26 +82,27 @@ pub fn init(env: napi_env, exports: napi_value) {
|
||||||
attributes: enumerable,
|
attributes: enumerable,
|
||||||
value: number,
|
value: number,
|
||||||
},
|
},
|
||||||
napi_property_descriptor {
|
// TODO(@littledivy): Fix this.
|
||||||
utf8name: ptr::null(),
|
// napi_property_descriptor {
|
||||||
name: name_value,
|
// utf8name: ptr::null(),
|
||||||
method: None,
|
// name: name_value,
|
||||||
getter: None,
|
// method: None,
|
||||||
setter: None,
|
// getter: None,
|
||||||
data: ptr::null_mut(),
|
// setter: None,
|
||||||
attributes: enumerable,
|
// data: ptr::null_mut(),
|
||||||
value: number,
|
// attributes: enumerable,
|
||||||
},
|
// value: number,
|
||||||
napi_property_descriptor {
|
// },
|
||||||
utf8name: ptr::null(),
|
// napi_property_descriptor {
|
||||||
name: name_symbol,
|
// utf8name: ptr::null(),
|
||||||
method: None,
|
// name: name_symbol,
|
||||||
getter: None,
|
// method: None,
|
||||||
setter: None,
|
// getter: None,
|
||||||
data: ptr::null_mut(),
|
// setter: None,
|
||||||
attributes: enumerable,
|
// data: ptr::null_mut(),
|
||||||
value: number,
|
// attributes: enumerable,
|
||||||
},
|
// value: number,
|
||||||
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
assert_napi_ok!(napi_define_properties(
|
assert_napi_ok!(napi_define_properties(
|
||||||
|
|
Loading…
Add table
Reference in a new issue