From 5b44ae322f0389b769df995d21887fbb544643b4 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 9 Sep 2021 18:57:18 +0800 Subject: [PATCH] fix(napi): drop_wrapped implementation --- napi/src/env.rs | 13 +++++-------- test_module/__test__/class.spec.ts | 10 ++++++++++ test_module/src/class.rs | 18 ++++++++++++++---- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/napi/src/env.rs b/napi/src/env.rs index 41736994..e68e3669 100644 --- a/napi/src/env.rs +++ b/napi/src/env.rs @@ -868,25 +868,22 @@ impl Env { } #[inline] - pub fn drop_wrapped(&self, js_object: JsObject) -> Result<()> { + pub fn drop_wrapped(&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::() { - let tagged_object = unknown_tagged_object as *mut TaggedObject; - (*tagged_object).object = None; + Box::from_raw(unknown_tagged_object as *mut TaggedObject); 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(), }) } } diff --git a/test_module/__test__/class.spec.ts b/test_module/__test__/class.spec.ts index 3c5b801e..304645bc 100644 --- a/test_module/__test__/class.spec.ts +++ b/test_module/__test__/class.spec.ts @@ -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) diff --git a/test_module/src/class.rs b/test_module/src/class.rs index 78832129..df34bde4 100644 --- a/test_module/src/class.rs +++ b/test_module/src/class.rs @@ -10,10 +10,12 @@ struct NativeClass { fn create_test_class(ctx: CallContext) -> Result { 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 { ctx.env.create_int32(native_class.value) } +#[js_function] +fn renew_wrapped(ctx: CallContext) -> Result { + let mut this: JsObject = ctx.this_unchecked(); + ctx.env.drop_wrapped::(&mut this)?; + ctx.env.wrap(&mut this, NativeClass { value: 42 })?; + ctx.env.get_undefined() +} + #[js_function(1)] fn new_test_class(ctx: CallContext) -> Result { let add_count_method = Property::new(ctx.env, "addCount")?.with_method(add_count);