mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-12-25 08:39:15 -05:00
Create first isolate (#17)
This commit is contained in:
parent
dc6050011a
commit
0339c5f3b3
5 changed files with 145 additions and 17 deletions
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ¶ms;
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue