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:
parent
0e02971a35
commit
b4674c62b8
13 changed files with 185 additions and 77 deletions
1
BUILD.gn
1
BUILD.gn
|
@ -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",
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
20
src/local.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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
27
src/value.cc
Normal 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
73
src/value.rs
Normal 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) }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue