diff --git a/src/array_buffer.rs b/src/array_buffer.rs index d6919e49..9c3671d9 100644 --- a/src/array_buffer.rs +++ b/src/array_buffer.rs @@ -49,6 +49,9 @@ extern "C" { fn v8__BackingStore__IsShared(this: *const BackingStore) -> bool; fn v8__BackingStore__DELETE(this: &mut BackingStore); + fn std__shared_ptr__v8__BackingStore__COPY( + ptr: *const SharedRef, + ) -> SharedRef; fn std__shared_ptr__v8__BackingStore__CONVERT__std__unique_ptr( unique: UniqueRef, ) -> SharedRef; @@ -180,6 +183,9 @@ impl Delete for BackingStore { } impl Shared for BackingStore { + fn clone(ptr: *const SharedRef) -> SharedRef { + unsafe { std__shared_ptr__v8__BackingStore__COPY(ptr) } + } fn from_unique(unique: UniqueRef) -> SharedRef { unsafe { std__shared_ptr__v8__BackingStore__CONVERT__std__unique_ptr(unique) diff --git a/src/binding.cc b/src/binding.cc index 992a058f..fee9962c 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -592,6 +592,11 @@ bool v8__BackingStore__IsShared(const v8::BackingStore& self) { void v8__BackingStore__DELETE(v8::BackingStore& self) { delete &self; } +two_pointers_t std__shared_ptr__v8__BackingStore__COPY( + const std::shared_ptr& ptr) { + return make_pod(ptr); +} + two_pointers_t std__shared_ptr__v8__BackingStore__CONVERT__std__unique_ptr( v8::BackingStore* ptr) { return make_pod(std::shared_ptr(ptr)); diff --git a/src/support.rs b/src/support.rs index 7650f852..a02db0a3 100644 --- a/src/support.rs +++ b/src/support.rs @@ -161,6 +161,7 @@ pub trait Shared where Self: Delete + 'static, { + fn clone(shared_ptr: *const SharedRef) -> SharedRef; fn from_unique(unique: UniqueRef) -> SharedRef; fn deref(shared_ptr: *const SharedRef) -> *mut Self; fn reset(shared_ptr: *mut SharedRef); @@ -185,6 +186,15 @@ where } } +impl Clone for SharedRef +where + T: Shared, +{ + fn clone(&self) -> Self { + ::clone(self) + } +} + impl From> for SharedRef where T: Delete + Shared, diff --git a/tests/test_api.rs b/tests/test_api.rs index c2adf2f4..0665af2b 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -342,11 +342,20 @@ fn array_buffer_with_shared_backing_store() { let bs4 = ab2.get_backing_store(); assert_eq!(ab2.byte_length(), bs4.byte_length()); - assert_eq!(4, v8::SharedRef::use_count(&bs4)); assert_eq!(4, v8::SharedRef::use_count(&bs3)); + assert_eq!(4, v8::SharedRef::use_count(&bs4)); + + let bs5 = bs4.clone(); + assert_eq!(5, v8::SharedRef::use_count(&bs3)); + assert_eq!(5, v8::SharedRef::use_count(&bs4)); + assert_eq!(5, v8::SharedRef::use_count(&bs5)); drop(bs3); - assert_eq!(3, v8::SharedRef::use_count(&bs4)); + assert_eq!(4, v8::SharedRef::use_count(&bs4)); + assert_eq!(4, v8::SharedRef::use_count(&bs4)); + + drop(bs4); + assert_eq!(3, v8::SharedRef::use_count(&bs5)); } }