0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-11-21 15:04:33 -05:00

Create first isolate (#17)

This commit is contained in:
Bert Belder 2019-11-20 13:34:32 -08:00
parent dc6050011a
commit 0339c5f3b3
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
5 changed files with 145 additions and 17 deletions

View file

@ -1,6 +1,6 @@
use crate::support::Delete;
use crate::support::Opaque;
use crate::support::UniquePtr;
use crate::support::UniqueRef;
extern "C" {
fn v8__ArrayBuffer__Allocator__NewDefaultAllocator() -> *mut Allocator;
@ -12,9 +12,9 @@ extern "C" {
pub struct Allocator(Opaque);
impl Allocator {
pub fn new_default_allocator() -> UniquePtr<Allocator> {
pub fn new_default_allocator() -> UniqueRef<Allocator> {
unsafe {
UniquePtr::from_raw(v8__ArrayBuffer__Allocator__NewDefaultAllocator())
UniqueRef::from_raw(v8__ArrayBuffer__Allocator__NewDefaultAllocator())
}
}
}

View file

@ -3,12 +3,35 @@
using namespace v8;
extern "C" {
Isolate* v8__Isolate__New() {
Isolate::CreateParams params;
return Isolate::New(params);
// This function consumes the Isolate::CreateParams object. The Isolate takes
// ownership of the ArrayBuffer::Allocator referenced by the params object.
Isolate* v8__Isolate__New(Isolate::CreateParams& params) {
auto isolate = Isolate::New(params);
delete &params;
return isolate;
}
void v8__Isolate__Dispose(Isolate& isolate) {
auto allocator = isolate.GetArrayBufferAllocator();
isolate.Dispose();
delete allocator;
}
Isolate::CreateParams* v8__Isolate__CreateParams__NEW() {
return new Isolate::CreateParams();
}
// This function is only called if the Isolate::CreateParams object is *not*
// consumed by Isolate::New().
void v8__Isolate__CreateParams__DELETE(Isolate::CreateParams& self) {
delete self.array_buffer_allocator;
delete &self;
}
// This function takes ownership of the ArrayBuffer::Allocator.
void v8__Isolate__CreateParams__SET__array_buffer_allocator(
Isolate::CreateParams& self, ArrayBuffer::Allocator* value) {
delete self.array_buffer_allocator;
self.array_buffer_allocator = value;
}
}

View file

@ -1,10 +1,23 @@
use crate::support::Opaque;
use crate::v8::assert_initialized;
use std::ops::Deref;
use crate::array_buffer::Allocator;
use crate::support::Delete;
use crate::support::Opaque;
use crate::support::UniqueRef;
use crate::v8::assert_initialized;
extern "C" {
fn v8__Isolate__New() -> &'static mut UnlockedIsolate;
fn v8__Isolate__New(
params: *mut CreateParams,
) -> &'static mut UnlockedIsolate;
fn v8__Isolate__Dispose(this: &mut UnlockedIsolate) -> ();
fn v8__Isolate__CreateParams__NEW() -> *mut CreateParams;
fn v8__Isolate__CreateParams__DELETE(this: &mut CreateParams);
fn v8__Isolate__CreateParams__SET__array_buffer_allocator(
this: &mut CreateParams,
value: *mut Allocator,
);
}
#[repr(C)]
@ -16,10 +29,10 @@ pub struct LockedIsolate(Opaque);
pub struct Isolate(&'static mut UnlockedIsolate);
impl Isolate {
pub fn new() -> Self {
pub fn new(params: UniqueRef<CreateParams>) -> Self {
// TODO: support CreateParams.
assert_initialized();
Self(unsafe { v8__Isolate__New() })
Self(unsafe { v8__Isolate__New(params.into_raw()) })
}
}
@ -36,6 +49,30 @@ impl Deref for Isolate {
}
}
#[repr(C)]
pub struct CreateParams(Opaque);
impl CreateParams {
pub fn new() -> UniqueRef<CreateParams> {
unsafe { UniqueRef::from_raw(v8__Isolate__CreateParams__NEW()) }
}
pub fn set_array_buffer_allocator(&mut self, value: UniqueRef<Allocator>) {
unsafe {
v8__Isolate__CreateParams__SET__array_buffer_allocator(
self,
value.into_raw(),
)
};
}
}
impl Delete for CreateParams {
fn delete(&'static mut self) {
unsafe { v8__Isolate__CreateParams__DELETE(self) }
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -46,8 +83,8 @@ mod tests {
fn test_isolate() {
initialize_platform(new_default_platform());
initialize();
//let isolate = Isolate::new();
dispose();
shutdown_platform();
let mut params = CreateParams::new();
params.set_array_buffer_allocator(Allocator::new_default_allocator());
Isolate::new(params);
}
}

View file

@ -1,9 +1,11 @@
use std::marker::PhantomData;
use std::mem::replace;
use std::mem::size_of;
use std::mem::transmute;
use std::mem::MaybeUninit;
use std::ops::Deref;
use std::ops::DerefMut;
use std::ptr::NonNull;
pub use std::os::raw::c_int as int;
@ -16,7 +18,7 @@ where
fn delete(&'static mut self) -> ();
}
/// Pointer to object allocated on the C++ heap.
/// Pointer to object allocated on the C++ heap. The pointer may be null.
#[repr(transparent)]
#[derive(Debug)]
pub struct UniquePtr<T>(Option<&'static mut T>)
@ -42,6 +44,12 @@ where
pub fn into_raw(self) -> *mut T {
unsafe { transmute(self) }
}
pub fn unwrap(self) -> UniqueRef<T> {
let p = self.into_raw();
assert!(!p.is_null());
unsafe { UniqueRef::from_raw(p) }
}
}
impl<T> Deref for UniquePtr<T>
@ -74,6 +82,61 @@ where
}
}
/// Pointer to object allocated on the C++ heap. The pointer may not be null.
#[repr(transparent)]
#[derive(Debug)]
pub struct UniqueRef<T>(&'static mut T)
where
T: Delete;
impl<T> UniqueRef<T>
where
T: Delete,
{
pub fn new(r: &'static mut T) -> Self {
Self(r)
}
pub unsafe fn from_raw(p: *mut T) -> Self {
transmute(NonNull::new(p))
}
pub fn into_raw(self) -> *mut T {
unsafe { transmute(self) }
}
}
impl<T> Deref for UniqueRef<T>
where
T: Delete,
{
type Target = &'static mut T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for UniqueRef<T>
where
T: Delete,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> Drop for UniqueRef<T>
where
T: Delete,
{
fn drop(&mut self) {
let inner = replace(&mut self.0, unsafe {
transmute(NonNull::<&'static mut T>::dangling())
});
Delete::delete(inner)
}
}
#[derive(Copy, Clone, Debug)]
#[repr(transparent)]
pub struct CxxVTable(pub *const Opaque);

View file

@ -133,10 +133,15 @@ pub fn initialize() {
/// It should generally not be necessary to dispose v8 before exiting
/// a process, this should happen automatically. It is only necessary
/// to use if the process needs the resources taken up by v8.
pub fn dispose() -> bool {
///
/// # Safety
///
/// Calling this function before completely disposing all isolates will lead
/// to a crash.
pub unsafe fn dispose() -> bool {
let mut global_state_guard = GLOBAL_STATE.lock().unwrap();
assert_eq!(*global_state_guard, Initialized);
assert_eq!(unsafe { v8__V8__Dispose() }, true);
assert_eq!(v8__V8__Dispose(), true);
*global_state_guard = Disposed;
true
}