mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-12-26 00:59:28 -05:00
First pass at BackingStore (#108)
This commit is contained in:
parent
153018b41b
commit
f36e74a648
4 changed files with 89 additions and 0 deletions
|
@ -14,6 +14,14 @@ extern "C" {
|
|||
byte_length: usize,
|
||||
) -> *mut ArrayBuffer;
|
||||
fn v8__ArrayBuffer__ByteLength(self_: *const ArrayBuffer) -> usize;
|
||||
|
||||
fn v8__ArrayBuffer__NewBackingStore(
|
||||
isolate: *mut Isolate,
|
||||
byte_length: usize,
|
||||
) -> *mut BackingStore;
|
||||
fn v8__BackingStore__ByteLength(self_: &BackingStore) -> usize;
|
||||
fn v8__BackingStore__IsShared(self_: &BackingStore) -> bool;
|
||||
fn v8__BackingStore__DELETE(self_: &mut BackingStore);
|
||||
}
|
||||
|
||||
/// A thread-safe allocator that V8 uses to allocate |ArrayBuffer|'s memory.
|
||||
|
@ -59,6 +67,46 @@ impl Delete for Allocator {
|
|||
}
|
||||
}
|
||||
|
||||
/// A wrapper around the backing store (i.e. the raw memory) of an array buffer.
|
||||
/// See a document linked in http://crbug.com/v8/9908 for more information.
|
||||
///
|
||||
/// The allocation and destruction of backing stores is generally managed by
|
||||
/// V8. Clients should always use standard C++ memory ownership types (i.e.
|
||||
/// std::unique_ptr and std::shared_ptr) to manage lifetimes of backing stores
|
||||
/// properly, since V8 internal objects may alias backing stores.
|
||||
///
|
||||
/// This object does not keep the underlying |ArrayBuffer::Allocator| alive by
|
||||
/// default. Use Isolate::CreateParams::array_buffer_allocator_shared when
|
||||
/// creating the Isolate to make it hold a reference to the allocator itself.
|
||||
#[repr(C)]
|
||||
pub struct BackingStore([usize; 6]);
|
||||
|
||||
impl BackingStore {
|
||||
/// Return a pointer to the beginning of the memory block for this backing
|
||||
/// store. The pointer is only valid as long as this backing store object
|
||||
/// lives.
|
||||
pub fn data(&self) -> std::ffi::c_void {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// The length (in bytes) of this backing store.
|
||||
pub fn byte_length(&self) -> usize {
|
||||
unsafe { v8__BackingStore__ByteLength(self) }
|
||||
}
|
||||
|
||||
/// Indicates whether the backing store was created for an ArrayBuffer or
|
||||
/// a SharedArrayBuffer.
|
||||
pub fn is_shared(&self) -> bool {
|
||||
unsafe { v8__BackingStore__IsShared(self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Delete for BackingStore {
|
||||
fn delete(&mut self) {
|
||||
unsafe { v8__BackingStore__DELETE(self) };
|
||||
}
|
||||
}
|
||||
|
||||
/// An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5).
|
||||
#[repr(C)]
|
||||
pub struct ArrayBuffer(Opaque);
|
||||
|
@ -82,4 +130,23 @@ impl ArrayBuffer {
|
|||
pub fn byte_length(&self) -> usize {
|
||||
unsafe { v8__ArrayBuffer__ByteLength(self) }
|
||||
}
|
||||
|
||||
/// Returns a new standalone BackingStore that is allocated using the array
|
||||
/// buffer allocator of the isolate. The result can be later passed to
|
||||
/// ArrayBuffer::New.
|
||||
///
|
||||
/// If the allocator returns nullptr, then the function may cause GCs in the
|
||||
/// given isolate and re-try the allocation. If GCs do not help, then the
|
||||
/// function will crash with an out-of-memory error.
|
||||
pub fn new_backing_store<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
byte_length: usize,
|
||||
) -> UniqueRef<BackingStore> {
|
||||
unsafe {
|
||||
UniqueRef::from_raw(v8__ArrayBuffer__NewBackingStore(
|
||||
scope.as_mut(),
|
||||
byte_length,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,6 +189,23 @@ v8::Primitive* v8__PrimitiveArray__Get(v8::PrimitiveArray& self,
|
|||
return local_to_ptr(self.Get(isolate, index));
|
||||
}
|
||||
|
||||
v8::BackingStore* v8__ArrayBuffer__NewBackingStore(v8::Isolate* isolate,
|
||||
size_t length) {
|
||||
std::unique_ptr<v8::BackingStore> u =
|
||||
v8::ArrayBuffer::NewBackingStore(isolate, length);
|
||||
return u.release();
|
||||
}
|
||||
|
||||
size_t v8__BackingStore__ByteLength(v8::BackingStore& self) {
|
||||
return self.ByteLength();
|
||||
}
|
||||
|
||||
bool v8__BackingStore__IsShared(v8::BackingStore& self) {
|
||||
return self.IsShared();
|
||||
}
|
||||
|
||||
void v8__BackingStore__DELETE(v8::BackingStore& self) { delete &self; }
|
||||
|
||||
v8::String* v8__String__NewFromUtf8(v8::Isolate* isolate, const char* data,
|
||||
v8::NewStringType type, int length) {
|
||||
return maybe_local_to_ptr(
|
||||
|
|
|
@ -42,6 +42,7 @@ pub mod V8;
|
|||
|
||||
pub use array_buffer::Allocator;
|
||||
pub use array_buffer::ArrayBuffer;
|
||||
pub use array_buffer::BackingStore;
|
||||
pub use context::Context;
|
||||
pub use exception::*;
|
||||
pub use function::{
|
||||
|
|
|
@ -107,6 +107,10 @@ fn array_buffer() {
|
|||
let ab = v8::ArrayBuffer::new(scope, 42);
|
||||
assert_eq!(42, ab.byte_length());
|
||||
|
||||
let bs = v8::ArrayBuffer::new_backing_store(scope, 84);
|
||||
assert_eq!(84, bs.byte_length());
|
||||
assert_eq!(false, bs.is_shared());
|
||||
|
||||
context.exit();
|
||||
});
|
||||
drop(locker);
|
||||
|
|
Loading…
Reference in a new issue