0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-12-25 00:29:14 -05:00

Basic support for Local<Number> and Local<Integer> (#23)

This commit is contained in:
Bert Belder 2019-11-30 16:31:51 +01:00
parent 0e02971a35
commit b4674c62b8
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
13 changed files with 185 additions and 77 deletions

View file

@ -13,6 +13,7 @@ v8_static_library("rusty_v8") {
"src/platform/mod.cc", "src/platform/mod.cc",
"src/platform/task.cc", "src/platform/task.cc",
"src/string_buffer.cc", "src/string_buffer.cc",
"src/value.cc",
] ]
deps = [ deps = [
":v8", ":v8",

View file

@ -18,4 +18,8 @@ void v8__HandleScope__CONSTRUCT(uninit_t<HandleScope>& buf, Isolate* isolate) {
void v8__HandleScope__DESTRUCT(HandleScope& self) { void v8__HandleScope__DESTRUCT(HandleScope& self) {
self.~HandleScope(); self.~HandleScope();
} }
Isolate* v8__HandleScope__GetIsolate(const HandleScope& self) {
return self.GetIsolate();
}
} }

View file

@ -1,63 +1,40 @@
use std::mem::drop; use std::marker::PhantomData;
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
use crate::isolate::CxxIsolate; use crate::isolate::CxxIsolate;
use crate::isolate::LockedIsolate; use crate::isolate::LockedIsolate;
use crate::support::Scope;
extern "C" { extern "C" {
fn v8__HandleScope__CONSTRUCT( fn v8__HandleScope__CONSTRUCT(
buf: &mut MaybeUninit<CxxHandleScope>, buf: &mut MaybeUninit<HandleScope>,
isolate: &mut CxxIsolate, isolate: &mut CxxIsolate,
); );
fn v8__HandleScope__DESTRUCT(this: &mut CxxHandleScope); fn v8__HandleScope__DESTRUCT(this: &mut HandleScope);
fn v8__HandleScope__GetIsolate<'sc>(
this: &'sc HandleScope,
) -> &'sc mut CxxIsolate;
} }
#[repr(C)] #[repr(C)]
pub struct CxxHandleScope([usize; 3]); pub struct HandleScope<'sc>([usize; 3], PhantomData<&'sc mut ()>);
pub struct HandleScope<'a, P> { impl<'sc> HandleScope<'sc> {
parent: &'a mut P, pub fn enter<P>(parent: &mut P, mut f: impl FnMut(&mut HandleScope<'_>) -> ())
cxx_handle_scope: MaybeUninit<CxxHandleScope>,
}
impl<'a, 'b, P> LockedIsolate for Scope<'a, HandleScope<'b, P>>
where where
P: LockedIsolate, P: LockedIsolate,
{ {
fn cxx_isolate(&mut self) -> &mut CxxIsolate { let mut scope: MaybeUninit<Self> = MaybeUninit::uninit();
self.0.parent.cxx_isolate() unsafe { v8__HandleScope__CONSTRUCT(&mut scope, parent.cxx_isolate()) };
} let mut scope = unsafe { &mut *(&mut scope as *mut _ as *mut HandleScope) };
}
impl<'a, P> HandleScope<'a, P>
where
P: LockedIsolate,
{
pub fn new(parent: &'a mut P) -> Self {
Self {
parent,
cxx_handle_scope: MaybeUninit::uninit(),
}
}
pub fn enter(&mut self, mut f: impl FnMut(&mut Scope<Self>) -> ()) {
unsafe {
v8__HandleScope__CONSTRUCT(
&mut self.cxx_handle_scope,
self.parent.cxx_isolate(),
)
};
let mut scope = Scope::new(self);
f(&mut scope); f(&mut scope);
drop(scope);
unsafe { unsafe { v8__HandleScope__DESTRUCT(&mut scope) };
v8__HandleScope__DESTRUCT( }
&mut *(&mut self.cxx_handle_scope as *mut _ as *mut CxxHandleScope), }
)
}; impl<'sc> LockedIsolate for HandleScope<'sc> {
fn cxx_isolate(&mut self) -> &mut CxxIsolate {
unsafe { v8__HandleScope__GetIsolate(self) }
} }
} }
@ -66,17 +43,29 @@ mod tests {
use super::*; use super::*;
use crate::array_buffer::Allocator; use crate::array_buffer::Allocator;
use crate::isolate::*; use crate::isolate::*;
use crate::Integer;
use crate::Locker; use crate::Locker;
use crate::Number;
#[test] #[test]
#[allow(clippy::float_cmp)]
fn test_handle_scope() { fn test_handle_scope() {
let g = crate::test_util::setup(); let g = crate::test_util::setup();
let mut params = CreateParams::new(); let mut params = CreateParams::new();
params.set_array_buffer_allocator(Allocator::new_default_allocator()); params.set_array_buffer_allocator(Allocator::new_default_allocator());
let isolate = Isolate::new(params); let mut isolate = Isolate::new(params);
let mut locker = Locker::new(&isolate); let mut locker = Locker::new(&mut isolate);
HandleScope::new(&mut locker).enter(|scope| { HandleScope::enter(&mut locker, |scope| {
HandleScope::new(scope).enter(|_scope| {}); let l1 = Integer::new(scope, -123);
let l2 = Integer::new_from_unsigned(scope, 456);
HandleScope::enter(scope, |scope2| {
let l3 = Number::new(scope2, 78.9);
assert_eq!(l1.value(), -123);
assert_eq!(l2.value(), 456);
assert_eq!(l3.value(), 78.9);
assert_eq!(Number::value(&l1), -123f64);
assert_eq!(Number::value(&l2), 456f64);
});
}); });
drop(g); drop(g);
} }

View file

@ -1,4 +1,5 @@
use std::ops::Deref; use std::ops::Deref;
use std::ops::DerefMut;
use crate::array_buffer::Allocator; use crate::array_buffer::Allocator;
use crate::support::Delete; use crate::support::Delete;
@ -43,11 +44,17 @@ impl Drop for Isolate {
impl Deref for Isolate { impl Deref for Isolate {
type Target = CxxIsolate; type Target = CxxIsolate;
fn deref(&self) -> &CxxIsolate { fn deref(&self) -> &Self::Target {
self.0 self.0
} }
} }
impl DerefMut for Isolate {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[repr(C)] #[repr(C)]
pub struct CreateParams(Opaque); pub struct CreateParams(Opaque);

View file

@ -13,6 +13,7 @@ pub mod array_buffer;
pub mod handle_scope; pub mod handle_scope;
pub mod inspector; pub mod inspector;
pub mod isolate; pub mod isolate;
pub mod local;
pub mod locker; pub mod locker;
pub mod platform; pub mod platform;
pub mod string_buffer; pub mod string_buffer;
@ -25,8 +26,12 @@ mod test_util;
// C++ namespace "v8::V8". // C++ namespace "v8::V8".
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub mod V8; pub mod V8;
pub mod value;
pub use handle_scope::HandleScope;
pub use isolate::Isolate; pub use isolate::Isolate;
pub use local::Local;
pub use locker::Locker; pub use locker::Locker;
pub use string_buffer::StringBuffer; pub use string_buffer::StringBuffer;
pub use string_view::StringView; pub use string_view::StringView;
pub use value::{Integer, Number};

20
src/local.rs Normal file
View file

@ -0,0 +1,20 @@
use std::ops::Deref;
pub struct Local<'sc, T>(&'sc T);
impl<'sc, T> Local<'sc, T> {
pub unsafe fn from_raw(ptr: *const T) -> Option<Self> {
if ptr.is_null() {
None
} else {
Some(Self(&*ptr))
}
}
}
impl<'sc, T> Deref for Local<'sc, T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}

View file

@ -14,7 +14,10 @@ use crate::isolate::LockedIsolate;
// } // }
extern "C" { extern "C" {
fn v8__Locker__CONSTRUCT(buf: &mut MaybeUninit<Locker>, isolate: &CxxIsolate); fn v8__Locker__CONSTRUCT(
buf: &mut MaybeUninit<Locker>,
isolate: &mut CxxIsolate,
);
fn v8__Locker__DESTRUCT(this: &mut Locker); fn v8__Locker__DESTRUCT(this: &mut Locker);
} }
@ -27,7 +30,7 @@ pub struct Locker<'a> {
} }
impl<'a> Locker<'a> { impl<'a> Locker<'a> {
pub fn new(isolate: &CxxIsolate) -> Self { pub fn new(isolate: &mut CxxIsolate) -> Self {
let mut buf = MaybeUninit::<Self>::uninit(); let mut buf = MaybeUninit::<Self>::uninit();
unsafe { unsafe {
v8__Locker__CONSTRUCT(&mut buf, isolate); v8__Locker__CONSTRUCT(&mut buf, isolate);

View file

@ -178,24 +178,3 @@ impl<F> FieldOffset<F> {
.unwrap() .unwrap()
} }
} }
pub struct Scope<'a, T>(pub(crate) &'a mut T);
impl<'a, T> Scope<'a, T> {
pub(crate) fn new(inner: &'a mut T) -> Self {
Self(inner)
}
}
impl<'a, T> Deref for Scope<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a, T> DerefMut for Scope<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

27
src/value.cc Normal file
View file

@ -0,0 +1,27 @@
#include <cstdint>
#include "v8/include/v8.h"
using namespace v8;
extern "C" {
Number* v8__Number__New(Isolate* isolate, double value) {
return *Number::New(isolate, value);
}
double v8__Number__Value(const Number& self) {
return self.Value();
}
Integer* v8__Integer__New(Isolate* isolate, int32_t value) {
return *Integer::New(isolate, value);
}
Integer* v8__Integer__NewFromUnsigned(Isolate* isolate, uint32_t value) {
return *Integer::NewFromUnsigned(isolate, value);
}
int64_t v8__Integer__Value(const Integer& self) {
return self.Value();
}
}

73
src/value.rs Normal file
View file

@ -0,0 +1,73 @@
use std::ops::Deref;
use crate::isolate::CxxIsolate;
use crate::isolate::LockedIsolate;
use crate::support::Opaque;
use crate::HandleScope;
use crate::Local;
extern "C" {
fn v8__Number__New(isolate: &mut CxxIsolate, value: f64) -> *const Number;
fn v8__Number__Value(this: &Number) -> f64;
fn v8__Integer__New(isolate: &mut CxxIsolate, value: i32) -> *const Integer;
fn v8__Integer__NewFromUnsigned(
isolate: &mut CxxIsolate,
value: u32,
) -> *const Integer;
fn v8__Integer__Value(this: &Integer) -> i64;
}
#[repr(C)]
pub struct Number(Opaque);
impl Number {
pub fn new<'sc>(
scope: &mut HandleScope<'sc>,
value: f64,
) -> Local<'sc, Number> {
unsafe {
let local = v8__Number__New(scope.cxx_isolate(), value);
Local::from_raw(local).unwrap()
}
}
pub fn value(&self) -> f64 {
unsafe { v8__Number__Value(self) }
}
}
#[repr(C)]
pub struct Integer(Opaque);
impl Integer {
pub fn new<'sc>(
scope: &mut HandleScope<'sc>,
value: i32,
) -> Local<'sc, Integer> {
unsafe {
let local = v8__Integer__New(scope.cxx_isolate(), value);
Local::from_raw(local).unwrap()
}
}
pub fn new_from_unsigned<'sc>(
scope: &mut HandleScope<'sc>,
value: u32,
) -> Local<'sc, Integer> {
unsafe {
let local = v8__Integer__NewFromUnsigned(scope.cxx_isolate(), value);
Local::from_raw(local).unwrap()
}
}
pub fn value(&self) -> i64 {
unsafe { v8__Integer__Value(self) }
}
}
impl Deref for Integer {
type Target = Number;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const _ as *const Number) }
}
}