0
0
Fork 0
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:
Ry Dahl 2019-12-21 11:05:51 -05:00 committed by GitHub
parent 153018b41b
commit f36e74a648
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 0 deletions

View file

@ -14,6 +14,14 @@ extern "C" {
byte_length: usize, byte_length: usize,
) -> *mut ArrayBuffer; ) -> *mut ArrayBuffer;
fn v8__ArrayBuffer__ByteLength(self_: *const ArrayBuffer) -> usize; 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. /// 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). /// An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5).
#[repr(C)] #[repr(C)]
pub struct ArrayBuffer(Opaque); pub struct ArrayBuffer(Opaque);
@ -82,4 +130,23 @@ impl ArrayBuffer {
pub fn byte_length(&self) -> usize { pub fn byte_length(&self) -> usize {
unsafe { v8__ArrayBuffer__ByteLength(self) } 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,
))
}
}
} }

View file

@ -189,6 +189,23 @@ v8::Primitive* v8__PrimitiveArray__Get(v8::PrimitiveArray& self,
return local_to_ptr(self.Get(isolate, index)); 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::String* v8__String__NewFromUtf8(v8::Isolate* isolate, const char* data,
v8::NewStringType type, int length) { v8::NewStringType type, int length) {
return maybe_local_to_ptr( return maybe_local_to_ptr(

View file

@ -42,6 +42,7 @@ pub mod V8;
pub use array_buffer::Allocator; pub use array_buffer::Allocator;
pub use array_buffer::ArrayBuffer; pub use array_buffer::ArrayBuffer;
pub use array_buffer::BackingStore;
pub use context::Context; pub use context::Context;
pub use exception::*; pub use exception::*;
pub use function::{ pub use function::{

View file

@ -107,6 +107,10 @@ fn array_buffer() {
let ab = v8::ArrayBuffer::new(scope, 42); let ab = v8::ArrayBuffer::new(scope, 42);
assert_eq!(42, ab.byte_length()); 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(); context.exit();
}); });
drop(locker); drop(locker);