mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-24 15:19:31 -05:00
use Isolate for creating primitives (#1082)
This commit is contained in:
parent
8f8636b4f7
commit
5dd41e9dba
6 changed files with 114 additions and 37 deletions
|
@ -94,36 +94,74 @@ fn main() {
|
|||
global.set(scope, name.into(), value.into()).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
extern "C" fn callback(info: *const v8::FunctionCallbackInfo) {
|
||||
let scope = unsafe { &mut v8::CallbackScope::new(&*info) };
|
||||
let mut rv =
|
||||
unsafe { v8::ReturnValue::from_function_callback_info(info) };
|
||||
rv.set(v8::undefined(scope).into());
|
||||
}
|
||||
let func = v8::Function::new_raw(scope, callback).unwrap();
|
||||
let name = v8::String::new(scope, "undefined_from_scope").unwrap();
|
||||
global.set(scope, name.into(), func.into()).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
extern "C" fn callback(info: *const v8::FunctionCallbackInfo) {
|
||||
let mut rv =
|
||||
unsafe { v8::ReturnValue::from_function_callback_info(info) };
|
||||
let mut info = unsafe {
|
||||
v8::FunctionCallbackArguments::from_function_callback_info(info)
|
||||
};
|
||||
rv.set(v8::undefined(unsafe { info.get_isolate() }).into());
|
||||
}
|
||||
let func = v8::Function::new_raw(scope, callback).unwrap();
|
||||
let name = v8::String::new(scope, "undefined_from_isolate").unwrap();
|
||||
global.set(scope, name.into(), func.into()).unwrap();
|
||||
}
|
||||
|
||||
let runs = 100_000_000;
|
||||
|
||||
for x in [
|
||||
"new_",
|
||||
"new_raw",
|
||||
"new_set_uint32",
|
||||
"new_raw_set_uint32",
|
||||
"new_fast",
|
||||
for (group_name, benches) in [
|
||||
(
|
||||
"function_overhead",
|
||||
&[
|
||||
"new_",
|
||||
"new_raw",
|
||||
"new_set_uint32",
|
||||
"new_raw_set_uint32",
|
||||
"new_fast",
|
||||
][..],
|
||||
),
|
||||
(
|
||||
"primitives",
|
||||
&["undefined_from_scope", "undefined_from_isolate"][..],
|
||||
),
|
||||
] {
|
||||
let code = format!(
|
||||
"
|
||||
function bench() {{ return {}(); }};
|
||||
runs = {};
|
||||
start = Date.now();
|
||||
for (i = 0; i < runs; i++) bench();
|
||||
Date.now() - start;
|
||||
",
|
||||
x, runs
|
||||
);
|
||||
println!("Running {} ...", group_name);
|
||||
for x in benches {
|
||||
let code = format!(
|
||||
"
|
||||
function bench() {{ return {}(); }};
|
||||
runs = {};
|
||||
start = Date.now();
|
||||
for (i = 0; i < runs; i++) bench();
|
||||
Date.now() - start;
|
||||
",
|
||||
x, runs
|
||||
);
|
||||
|
||||
let r = eval(scope, &code).unwrap();
|
||||
let number = r.to_number(scope).unwrap();
|
||||
let total_ms = number.number_value(scope).unwrap();
|
||||
let total_ns = 1e6 * total_ms;
|
||||
let ns_per_run = total_ns / (runs as f64);
|
||||
let mops_per_sec = (runs as f64) / (total_ms / 1000.0) / 1e6;
|
||||
println!(
|
||||
"{:.1} ns per run {:.1} million ops/sec → {}",
|
||||
ns_per_run, mops_per_sec, x
|
||||
);
|
||||
let r = eval(scope, &code).unwrap();
|
||||
let number = r.to_number(scope).unwrap();
|
||||
let total_ms = number.number_value(scope).unwrap();
|
||||
let total_ns = 1e6 * total_ms;
|
||||
let ns_per_run = total_ns / (runs as f64);
|
||||
let mops_per_sec = (runs as f64) / (total_ms / 1000.0) / 1e6;
|
||||
println!(
|
||||
" {:.1} ns per run {:.1} million ops/sec → {}",
|
||||
ns_per_run, mops_per_sec, x
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ use crate::support::{int, Opaque};
|
|||
use crate::Context;
|
||||
use crate::Function;
|
||||
use crate::HandleScope;
|
||||
use crate::Isolate;
|
||||
use crate::Local;
|
||||
use crate::Name;
|
||||
use crate::Object;
|
||||
|
@ -69,6 +70,9 @@ extern "C" {
|
|||
fn v8__FunctionCallbackInfo__NewTarget(
|
||||
this: *const FunctionCallbackInfo,
|
||||
) -> *const Value;
|
||||
fn v8__FunctionCallbackInfo__GetIsolate(
|
||||
this: *const FunctionCallbackInfo,
|
||||
) -> *mut Isolate;
|
||||
|
||||
fn v8__PropertyCallbackInfo__GetReturnValue(
|
||||
this: *const PropertyCallbackInfo,
|
||||
|
@ -233,6 +237,11 @@ impl<'s> FunctionCallbackArguments<'s> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn get_isolate(&mut self) -> &mut Isolate {
|
||||
&mut *v8__FunctionCallbackInfo__GetIsolate(self.info)
|
||||
}
|
||||
|
||||
/// Returns the receiver. This corresponds to the "this" value.
|
||||
#[inline(always)]
|
||||
pub fn this(&self) -> Local<'s, Object> {
|
||||
|
|
|
@ -107,6 +107,11 @@ impl<'s, T> Local<'s, T> {
|
|||
NonNull::new(ptr as *mut _).map(|nn| Self::from_non_null(nn))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) unsafe fn from_raw_unchecked(ptr: *const T) -> Self {
|
||||
Self(NonNull::new_unchecked(ptr as *mut _), PhantomData)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) unsafe fn from_non_null(nn: NonNull<T>) -> Self {
|
||||
Self(nn, PhantomData)
|
||||
|
|
|
@ -1123,6 +1123,18 @@ impl DerefMut for OwnedIsolate {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsMut<Isolate> for OwnedIsolate {
|
||||
fn as_mut(&mut self) -> &mut Isolate {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl AsMut<Isolate> for Isolate {
|
||||
fn as_mut(&mut self) -> &mut Isolate {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl HeapStatistics {
|
||||
#[inline(always)]
|
||||
pub fn total_heap_size(&self) -> usize {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::isolate::Isolate;
|
||||
use crate::Boolean;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
use crate::Primitive;
|
||||
|
||||
|
@ -12,24 +11,29 @@ extern "C" {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn null<'s>(scope: &mut HandleScope<'s, ()>) -> Local<'s, Primitive> {
|
||||
unsafe { scope.cast_local(|sd| v8__Null(sd.get_isolate_ptr())) }.unwrap()
|
||||
pub fn null<'a, R>(scope: &mut R) -> Local<'a, Primitive>
|
||||
where
|
||||
R: AsMut<Isolate>,
|
||||
{
|
||||
unsafe { Local::from_raw_unchecked(v8__Null(scope.as_mut())) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn undefined<'s>(scope: &mut HandleScope<'s, ()>) -> Local<'s, Primitive> {
|
||||
unsafe { scope.cast_local(|sd| v8__Undefined(sd.get_isolate_ptr())) }.unwrap()
|
||||
pub fn undefined<'a, R>(scope: &mut R) -> Local<'a, Primitive>
|
||||
where
|
||||
R: AsMut<Isolate>,
|
||||
{
|
||||
unsafe { Local::from_raw_unchecked(v8__Undefined(scope.as_mut())) }
|
||||
}
|
||||
|
||||
impl Boolean {
|
||||
#[inline(always)]
|
||||
pub fn new<'s>(
|
||||
scope: &mut HandleScope<'s, ()>,
|
||||
value: bool,
|
||||
) -> Local<'s, Boolean> {
|
||||
pub fn new<'a, R>(scope: &mut R, value: bool) -> Local<'a, Boolean>
|
||||
where
|
||||
R: AsMut<Isolate>,
|
||||
{
|
||||
unsafe {
|
||||
scope.cast_local(|sd| v8__Boolean__New(sd.get_isolate_ptr(), value))
|
||||
Local::from_raw_unchecked(v8__Boolean__New(scope.as_mut(), value))
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -553,6 +553,15 @@ fn get_isolate_from_handle() {
|
|||
check_eval(scope, Some(false), "3.3 / 3.3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handles_from_isolate() {
|
||||
let _setup_guard = setup();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
let _ = v8::null(isolate);
|
||||
let _ = v8::undefined(isolate);
|
||||
let _ = v8::Boolean::new(isolate, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array_buffer() {
|
||||
let _setup_guard = setup();
|
||||
|
|
Loading…
Reference in a new issue