1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-27 16:10:57 -05:00

fix(cli): set napi object property properly (#26344)

<!--
Before submitting a PR, please read
https://docs.deno.com/runtime/manual/references/contributing

1. Give the PR a descriptive title.

  Examples of good title:
    - fix(std/http): Fix race condition in server
    - docs(console): Update docstrings
    - feat(doc): Handle nested reexports

  Examples of bad title:
    - fix #7123
    - update docs
    - fix bugs

2. Ensure there is a related issue and it is referenced in the PR text.
3. Ensure there are tests that cover the changes.
4. Ensure `cargo test` passes.
5. Ensure `./tools/format.js` passes without changing files.
6. Ensure `./tools/lint.js` passes.
7. Open as a draft PR if your work is still in progress. The CI won't
run
   all steps, but you can add '[ci]' to a commit message to force it to.
8. If you would like to run the benchmarks on the CI, add the 'ci-bench'
label.
-->
This commit is contained in:
LongYinan 2024-10-17 18:44:51 +08:00 committed by GitHub
parent a61ba3c699
commit 5689585888
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 69 additions and 14 deletions

View file

@ -264,6 +264,16 @@ fn napi_define_class<'s>(
Err(status) => return status, Err(status) => return status,
}; };
let mut accessor_property = v8::PropertyAttribute::NONE;
if p.attributes & napi_enumerable == 0 {
accessor_property = accessor_property | v8::PropertyAttribute::DONT_ENUM;
}
if p.attributes & napi_configurable == 0 {
accessor_property =
accessor_property | v8::PropertyAttribute::DONT_DELETE;
}
if p.getter.is_some() || p.setter.is_some() { if p.getter.is_some() || p.setter.is_some() {
let getter = p.getter.map(|g| { let getter = p.getter.map(|g| {
create_function_template(&mut env.scope(), env_ptr, None, g, p.data) create_function_template(&mut env.scope(), env_ptr, None, g, p.data)
@ -271,8 +281,6 @@ fn napi_define_class<'s>(
let setter = p.setter.map(|s| { let setter = p.setter.map(|s| {
create_function_template(&mut env.scope(), env_ptr, None, s, p.data) create_function_template(&mut env.scope(), env_ptr, None, s, p.data)
}); });
let mut accessor_property = v8::PropertyAttribute::NONE;
if getter.is_some() if getter.is_some()
&& setter.is_some() && setter.is_some()
&& (p.attributes & napi_writable) == 0 && (p.attributes & napi_writable) == 0
@ -280,15 +288,6 @@ fn napi_define_class<'s>(
accessor_property = accessor_property =
accessor_property | v8::PropertyAttribute::READ_ONLY; accessor_property | v8::PropertyAttribute::READ_ONLY;
} }
if p.attributes & napi_enumerable == 0 {
accessor_property =
accessor_property | v8::PropertyAttribute::DONT_ENUM;
}
if p.attributes & napi_configurable == 0 {
accessor_property =
accessor_property | v8::PropertyAttribute::DONT_DELETE;
}
let proto = tpl.prototype_template(&mut env.scope()); let proto = tpl.prototype_template(&mut env.scope());
proto.set_accessor_property(name, getter, setter, accessor_property); proto.set_accessor_property(name, getter, setter, accessor_property);
} else if let Some(method) = p.method { } else if let Some(method) = p.method {
@ -300,10 +299,14 @@ fn napi_define_class<'s>(
p.data, p.data,
); );
let proto = tpl.prototype_template(&mut env.scope()); let proto = tpl.prototype_template(&mut env.scope());
proto.set(name, function.into()); proto.set_with_attr(name, function.into(), accessor_property);
} else { } else {
let proto = tpl.prototype_template(&mut env.scope()); let proto = tpl.prototype_template(&mut env.scope());
proto.set(name, p.value.unwrap().into()); if (p.attributes & napi_writable) == 0 {
accessor_property =
accessor_property | v8::PropertyAttribute::READ_ONLY;
}
proto.set_with_attr(name, p.value.unwrap().into(), accessor_property);
} }
} }

View file

@ -1,6 +1,11 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assert, assertEquals, loadTestLibrary } from "./common.js"; import {
assert,
assertEquals,
assertThrows,
loadTestLibrary,
} from "./common.js";
const object = loadTestLibrary(); const object = loadTestLibrary();
@ -12,4 +17,22 @@ Deno.test("napi object", function () {
const r1 = object.test_object_get(r); const r1 = object.test_object_get(r);
assert(r === r1); assert(r === r1);
const r2 = object.test_object_attr_property(r);
assert(r === r2);
assertThrows(
() => {
r2.self = "2";
},
Error,
"Cannot assign to read only property 'self' of object '#<Object>'",
);
assertThrows(
() => {
r2.method = () => {};
},
Error,
"Cannot assign to read only property 'method' of object '#<Object>'",
);
}); });

View file

@ -40,10 +40,39 @@ extern "C" fn test_object_get(
obj obj
} }
extern "C" fn test_object_attr_property(
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];
let mut property = napi_new_property!(env, "self", test_object_new);
property.attributes = PropertyAttributes::enumerable;
property.method = None;
property.value = obj;
let mut method_property = napi_new_property!(env, "method", test_object_new);
method_property.attributes = PropertyAttributes::enumerable;
let properties = &[property, method_property];
assert_napi_ok!(napi_define_properties(
env,
obj,
properties.len(),
properties.as_ptr()
));
obj
}
pub fn init(env: napi_env, exports: napi_value) { pub fn init(env: napi_env, exports: napi_value) {
let properties = &[ let properties = &[
napi_new_property!(env, "test_object_new", test_object_new), napi_new_property!(env, "test_object_new", test_object_new),
napi_new_property!(env, "test_object_get", test_object_get), napi_new_property!(env, "test_object_get", test_object_get),
napi_new_property!(
env,
"test_object_attr_property",
test_object_attr_property
),
]; ];
assert_napi_ok!(napi_define_properties( assert_napi_ok!(napi_define_properties(