Merge pull request #734 from napi-rs/drop-wrapped

fix(napi): drop_wrapped implementation
This commit is contained in:
LongYinan 2021-09-09 23:24:57 +08:00 committed by GitHub
commit 5fe8003f9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 12 deletions

View file

@ -868,25 +868,22 @@ impl Env {
}
#[inline]
pub fn drop_wrapped<T: 'static>(&self, js_object: JsObject) -> Result<()> {
pub fn drop_wrapped<T: 'static>(&self, js_object: &mut JsObject) -> Result<()> {
unsafe {
let mut unknown_tagged_object: *mut c_void = ptr::null_mut();
check_status!(sys::napi_unwrap(
let mut unknown_tagged_object = ptr::null_mut();
check_status!(sys::napi_remove_wrap(
self.0,
js_object.0.value,
&mut unknown_tagged_object,
))?;
let type_id = unknown_tagged_object as *const TypeId;
if *type_id == TypeId::of::<T>() {
let tagged_object = unknown_tagged_object as *mut TaggedObject<T>;
(*tagged_object).object = None;
Box::from_raw(unknown_tagged_object as *mut TaggedObject<T>);
Ok(())
} else {
Err(Error {
status: Status::InvalidArg,
reason: "Invalid argument, T on drop_wrapped is not the type of wrapped object"
.to_owned(),
reason: "Invalid argument, T on unrwap is not the type of wrapped object".to_owned(),
})
}
}

View file

@ -20,6 +20,16 @@ test('should be able to manipulate wrapped native value', (t) => {
t.is(testClass.addNativeCount(add), fixture + add + 100)
})
test('should be able to re-create wrapped native value', (t) => {
const TestClass = bindings.createTestClass()
const fixture = 20
const testClass = new TestClass(fixture)
const add = 101
t.is(testClass.addNativeCount(add), fixture + add + 100)
testClass.renewWrapped()
t.is(testClass.addNativeCount(0), 42)
})
test('should be able to new class instance in native side', (t) => {
const instance = bindings.newTestClass()
t.is(instance.count, 42)

View file

@ -10,10 +10,12 @@ struct NativeClass {
fn create_test_class(ctx: CallContext) -> Result<JsFunction> {
let add_count_method = Property::new(ctx.env, "addCount")?.with_method(add_count);
let add_native_count = Property::new(ctx.env, "addNativeCount")?.with_method(add_native_count);
let properties = vec![add_count_method, add_native_count];
ctx
.env
.define_class("TestClass", test_class_constructor, properties.as_slice())
let renew_wrapped = Property::new(ctx.env, "renewWrapped")?.with_method(renew_wrapped);
ctx.env.define_class(
"TestClass",
test_class_constructor,
&[add_count_method, add_native_count, renew_wrapped],
)
}
#[js_function(1)]
@ -45,6 +47,14 @@ fn add_native_count(ctx: CallContext) -> Result<JsNumber> {
ctx.env.create_int32(native_class.value)
}
#[js_function]
fn renew_wrapped(ctx: CallContext) -> Result<JsUndefined> {
let mut this: JsObject = ctx.this_unchecked();
ctx.env.drop_wrapped::<NativeClass>(&mut this)?;
ctx.env.wrap(&mut this, NativeClass { value: 42 })?;
ctx.env.get_undefined()
}
#[js_function(1)]
fn new_test_class(ctx: CallContext) -> Result<JsObject> {
let add_count_method = Property::new(ctx.env, "addCount")?.with_method(add_count);