mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-12-01 16:51:32 -05:00
Fix BackingStore segfault (#294)
This commit is contained in:
parent
26cee7e327
commit
816b6ad537
4 changed files with 108 additions and 26 deletions
|
@ -64,6 +64,22 @@ extern "C" {
|
||||||
fn std__shared_ptr__v8__BackingStore__use_count(
|
fn std__shared_ptr__v8__BackingStore__use_count(
|
||||||
ptr: *const SharedRef<BackingStore>,
|
ptr: *const SharedRef<BackingStore>,
|
||||||
) -> long;
|
) -> long;
|
||||||
|
|
||||||
|
fn std__shared_ptr__v8__ArrayBuffer__Allocator__COPY(
|
||||||
|
ptr: *const SharedRef<Allocator>,
|
||||||
|
) -> SharedRef<Allocator>;
|
||||||
|
fn std__shared_ptr__v8__ArrayBuffer__Allocator__CONVERT__std__unique_ptr(
|
||||||
|
unique: UniqueRef<Allocator>,
|
||||||
|
) -> SharedRef<Allocator>;
|
||||||
|
fn std__shared_ptr__v8__ArrayBuffer__Allocator__get(
|
||||||
|
ptr: *const SharedRef<Allocator>,
|
||||||
|
) -> *mut Allocator;
|
||||||
|
fn std__shared_ptr__v8__ArrayBuffer__Allocator__reset(
|
||||||
|
ptr: *mut SharedRef<Allocator>,
|
||||||
|
);
|
||||||
|
fn std__shared_ptr__v8__ArrayBuffer__Allocator__use_count(
|
||||||
|
ptr: *const SharedRef<Allocator>,
|
||||||
|
) -> long;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A thread-safe allocator that V8 uses to allocate |ArrayBuffer|'s memory.
|
/// A thread-safe allocator that V8 uses to allocate |ArrayBuffer|'s memory.
|
||||||
|
@ -86,14 +102,34 @@ extern "C" {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Allocator(Opaque);
|
pub struct Allocator(Opaque);
|
||||||
|
|
||||||
|
impl Shared for Allocator {
|
||||||
|
fn clone(ptr: *const SharedRef<Self>) -> SharedRef<Self> {
|
||||||
|
unsafe { std__shared_ptr__v8__ArrayBuffer__Allocator__COPY(ptr) }
|
||||||
|
}
|
||||||
|
fn from_unique(unique: UniqueRef<Self>) -> SharedRef<Self> {
|
||||||
|
unsafe {
|
||||||
|
std__shared_ptr__v8__ArrayBuffer__Allocator__CONVERT__std__unique_ptr(
|
||||||
|
unique,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn deref(ptr: *const SharedRef<Self>) -> *mut Self {
|
||||||
|
unsafe { std__shared_ptr__v8__ArrayBuffer__Allocator__get(ptr) }
|
||||||
|
}
|
||||||
|
fn reset(ptr: *mut SharedRef<Self>) {
|
||||||
|
unsafe { std__shared_ptr__v8__ArrayBuffer__Allocator__reset(ptr) }
|
||||||
|
}
|
||||||
|
fn use_count(ptr: *const SharedRef<Self>) -> long {
|
||||||
|
unsafe { std__shared_ptr__v8__ArrayBuffer__Allocator__use_count(ptr) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// malloc/free based convenience allocator.
|
/// malloc/free based convenience allocator.
|
||||||
///
|
pub fn new_default_allocator() -> SharedRef<Allocator> {
|
||||||
/// Caller takes ownership, i.e. the returned object needs to be freed using
|
|
||||||
/// |delete allocator| once it is no longer in use.
|
|
||||||
pub fn new_default_allocator() -> UniqueRef<Allocator> {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
UniqueRef::from_raw(v8__ArrayBuffer__Allocator__NewDefaultAllocator())
|
UniqueRef::from_raw(v8__ArrayBuffer__Allocator__NewDefaultAllocator())
|
||||||
}
|
}
|
||||||
|
.make_shared()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -100,11 +100,7 @@ v8::Isolate* v8__Isolate__New(v8::Isolate::CreateParams& params) {
|
||||||
return isolate;
|
return isolate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void v8__Isolate__Dispose(v8::Isolate* isolate) {
|
void v8__Isolate__Dispose(v8::Isolate* isolate) { isolate->Dispose(); }
|
||||||
auto allocator = isolate->GetArrayBufferAllocator();
|
|
||||||
isolate->Dispose();
|
|
||||||
delete allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
void v8__Isolate__Enter(v8::Isolate* isolate) { isolate->Enter(); }
|
void v8__Isolate__Enter(v8::Isolate* isolate) { isolate->Enter(); }
|
||||||
|
|
||||||
|
@ -196,15 +192,16 @@ v8::Isolate::CreateParams* v8__Isolate__CreateParams__NEW() {
|
||||||
// This function is only called if the Isolate::CreateParams object is *not*
|
// This function is only called if the Isolate::CreateParams object is *not*
|
||||||
// consumed by Isolate::New().
|
// consumed by Isolate::New().
|
||||||
void v8__Isolate__CreateParams__DELETE(v8::Isolate::CreateParams& self) {
|
void v8__Isolate__CreateParams__DELETE(v8::Isolate::CreateParams& self) {
|
||||||
delete self.array_buffer_allocator;
|
assert(self.array_buffer_allocator ==
|
||||||
|
nullptr); // We only used the shared version.
|
||||||
delete &self;
|
delete &self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function takes ownership of the ArrayBuffer::Allocator.
|
// This function takes ownership of the ArrayBuffer::Allocator.
|
||||||
void v8__Isolate__CreateParams__SET__array_buffer_allocator(
|
void v8__Isolate__CreateParams__SET__array_buffer_allocator(
|
||||||
v8::Isolate::CreateParams& self, v8::ArrayBuffer::Allocator* value) {
|
v8::Isolate::CreateParams& self,
|
||||||
delete self.array_buffer_allocator;
|
std::shared_ptr<v8::ArrayBuffer::Allocator>& allocator) {
|
||||||
self.array_buffer_allocator = value;
|
self.array_buffer_allocator_shared = allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
// external_references should probably have static lifetime.
|
// external_references should probably have static lifetime.
|
||||||
|
@ -628,6 +625,33 @@ long std__shared_ptr__v8__BackingStore__use_count(
|
||||||
return ptr.use_count();
|
return ptr.use_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
two_pointers_t std__shared_ptr__v8__ArrayBuffer__Allocator__COPY(
|
||||||
|
const std::shared_ptr<v8::ArrayBuffer::Allocator>& ptr) {
|
||||||
|
return make_pod<two_pointers_t>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
two_pointers_t
|
||||||
|
std__shared_ptr__v8__ArrayBuffer__Allocator__CONVERT__std__unique_ptr(
|
||||||
|
v8::ArrayBuffer::Allocator* ptr) {
|
||||||
|
return make_pod<two_pointers_t>(
|
||||||
|
std::shared_ptr<v8::ArrayBuffer::Allocator>(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::ArrayBuffer::Allocator* std__shared_ptr__v8__ArrayBuffer__Allocator__get(
|
||||||
|
const std::shared_ptr<v8::ArrayBuffer::Allocator>& ptr) {
|
||||||
|
return ptr.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void std__shared_ptr__v8__ArrayBuffer__Allocator__reset(
|
||||||
|
std::shared_ptr<v8::ArrayBuffer::Allocator>& ptr) {
|
||||||
|
ptr.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
long std__shared_ptr__v8__ArrayBuffer__Allocator__use_count(
|
||||||
|
const std::shared_ptr<v8::ArrayBuffer::Allocator>& ptr) {
|
||||||
|
return ptr.use_count();
|
||||||
|
}
|
||||||
|
|
||||||
v8::String* v8__String__Empty(v8::Isolate* isolate) {
|
v8::String* v8__String__Empty(v8::Isolate* isolate) {
|
||||||
return local_to_ptr(v8::String::Empty(isolate));
|
return local_to_ptr(v8::String::Empty(isolate));
|
||||||
}
|
}
|
||||||
|
@ -742,9 +766,7 @@ v8::Array* v8__Array__New_with_elements(v8::Isolate* isolate,
|
||||||
return local_to_ptr(v8::Array::New(isolate, elements, length));
|
return local_to_ptr(v8::Array::New(isolate, elements, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t v8__Array__Length(const v8::Array& self) {
|
uint32_t v8__Array__Length(const v8::Array& self) { return self.Length(); }
|
||||||
return self.Length();
|
|
||||||
}
|
|
||||||
|
|
||||||
v8::Number* v8__Number__New(v8::Isolate* isolate, double value) {
|
v8::Number* v8__Number__New(v8::Isolate* isolate, double value) {
|
||||||
return *v8::Number::New(isolate, value);
|
return *v8::Number::New(isolate, value);
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::promise::PromiseRejectMessage;
|
||||||
use crate::support::intptr_t;
|
use crate::support::intptr_t;
|
||||||
use crate::support::Delete;
|
use crate::support::Delete;
|
||||||
use crate::support::Opaque;
|
use crate::support::Opaque;
|
||||||
|
use crate::support::SharedRef;
|
||||||
use crate::support::UniqueRef;
|
use crate::support::UniqueRef;
|
||||||
use crate::Context;
|
use crate::Context;
|
||||||
use crate::Function;
|
use crate::Function;
|
||||||
|
@ -121,7 +122,7 @@ extern "C" {
|
||||||
fn v8__Isolate__CreateParams__DELETE(this: &mut CreateParams);
|
fn v8__Isolate__CreateParams__DELETE(this: &mut CreateParams);
|
||||||
fn v8__Isolate__CreateParams__SET__array_buffer_allocator(
|
fn v8__Isolate__CreateParams__SET__array_buffer_allocator(
|
||||||
this: &mut CreateParams,
|
this: &mut CreateParams,
|
||||||
value: *mut Allocator,
|
allocator: &SharedRef<Allocator>,
|
||||||
);
|
);
|
||||||
fn v8__Isolate__CreateParams__SET__external_references(
|
fn v8__Isolate__CreateParams__SET__external_references(
|
||||||
this: &mut CreateParams,
|
this: &mut CreateParams,
|
||||||
|
@ -493,16 +494,12 @@ impl CreateParams {
|
||||||
/// The ArrayBuffer::Allocator to use for allocating and freeing the backing
|
/// The ArrayBuffer::Allocator to use for allocating and freeing the backing
|
||||||
/// store of ArrayBuffers.
|
/// store of ArrayBuffers.
|
||||||
///
|
///
|
||||||
/// If the shared_ptr version is used, the Isolate instance and every
|
/// The Isolate instance and every |BackingStore| allocated using this
|
||||||
/// |BackingStore| allocated using this allocator hold a std::shared_ptr
|
/// allocator hold a SharedRef to the allocator, in order to facilitate
|
||||||
/// to the allocator, in order to facilitate lifetime
|
/// lifetime management for the allocator instance.
|
||||||
/// management for the allocator instance.
|
pub fn set_array_buffer_allocator(&mut self, value: SharedRef<Allocator>) {
|
||||||
pub fn set_array_buffer_allocator(&mut self, value: UniqueRef<Allocator>) {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
v8__Isolate__CreateParams__SET__array_buffer_allocator(
|
v8__Isolate__CreateParams__SET__array_buffer_allocator(self, &value)
|
||||||
self,
|
|
||||||
value.into_raw(),
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -334,6 +334,33 @@ fn array_buffer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn backing_store_segfault() {
|
||||||
|
let _setup_guard = setup();
|
||||||
|
let array_buffer_allocator = v8::new_default_allocator();
|
||||||
|
let shared_bs = {
|
||||||
|
assert_eq!(1, v8::SharedRef::use_count(&array_buffer_allocator));
|
||||||
|
let mut params = v8::Isolate::create_params();
|
||||||
|
params.set_array_buffer_allocator(array_buffer_allocator.clone());
|
||||||
|
assert_eq!(2, v8::SharedRef::use_count(&array_buffer_allocator));
|
||||||
|
let mut isolate = v8::Isolate::new(params);
|
||||||
|
assert_eq!(2, v8::SharedRef::use_count(&array_buffer_allocator));
|
||||||
|
let mut hs = v8::HandleScope::new(&mut isolate);
|
||||||
|
let scope = hs.enter();
|
||||||
|
let context = v8::Context::new(scope);
|
||||||
|
let mut cs = v8::ContextScope::new(scope, context);
|
||||||
|
let scope = cs.enter();
|
||||||
|
let ab = v8::ArrayBuffer::new(scope, 10);
|
||||||
|
let shared_bs = ab.get_backing_store();
|
||||||
|
assert_eq!(3, v8::SharedRef::use_count(&array_buffer_allocator));
|
||||||
|
shared_bs
|
||||||
|
};
|
||||||
|
assert_eq!(1, v8::SharedRef::use_count(&shared_bs));
|
||||||
|
assert_eq!(2, v8::SharedRef::use_count(&array_buffer_allocator));
|
||||||
|
drop(array_buffer_allocator);
|
||||||
|
drop(shared_bs); // Error occurred here.
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn array_buffer_with_shared_backing_store() {
|
fn array_buffer_with_shared_backing_store() {
|
||||||
let _setup_guard = setup();
|
let _setup_guard = setup();
|
||||||
|
|
Loading…
Reference in a new issue