mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-27 16:11:06 -05:00
Rolling to V8 12.9.202.1 (#1579)
* Rolling to V8 12.9.202.1 * initial changes for 12.9 * CallbackScope for fast fns * disable broken thing by default * use windows 2022 runner --------- Co-authored-by: snek <the@snek.dev>
This commit is contained in:
parent
1f5ebd9c4e
commit
3d29396d72
17 changed files with 98 additions and 151 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -62,7 +62,7 @@ jobs:
|
||||||
variant: release
|
variant: release
|
||||||
cargo: cargo
|
cargo: cargo
|
||||||
|
|
||||||
- os: ${{ github.repository == 'denoland/rusty_v8' && 'windows-2019-xxl' || 'windows-2019' }}
|
- os: ${{ github.repository == 'denoland/rusty_v8' && 'windows-2022-xxl' || 'windows-2022' }}
|
||||||
target: x86_64-pc-windows-msvc
|
target: x86_64-pc-windows-msvc
|
||||||
variant: release # Note: we do not support windows debug builds.
|
variant: release # Note: we do not support windows debug builds.
|
||||||
cargo: cargo
|
cargo: cargo
|
||||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -19,9 +19,6 @@
|
||||||
[submodule "buildtools"]
|
[submodule "buildtools"]
|
||||||
path = buildtools
|
path = buildtools
|
||||||
url = https://chromium.googlesource.com/chromium/src/buildtools.git
|
url = https://chromium.googlesource.com/chromium/src/buildtools.git
|
||||||
[submodule "third_party/zlib"]
|
|
||||||
path = third_party/zlib
|
|
||||||
url = https://chromium.googlesource.com/chromium/src/third_party/zlib.git
|
|
||||||
[submodule "third_party/icu"]
|
[submodule "third_party/icu"]
|
||||||
path = third_party/icu
|
path = third_party/icu
|
||||||
url = https://github.com/denoland/icu.git
|
url = https://github.com/denoland/icu.git
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Rusty V8 Binding
|
# Rusty V8 Binding
|
||||||
|
|
||||||
V8 Version: 12.8.374.16
|
V8 Version: 12.9.202.1
|
||||||
|
|
||||||
[![ci](https://github.com/denoland/rusty_v8/workflows/ci/badge.svg?branch=main)](https://github.com/denoland/rusty_v8/actions)
|
[![ci](https://github.com/denoland/rusty_v8/workflows/ci/badge.svg?branch=main)](https://github.com/denoland/rusty_v8/actions)
|
||||||
[![crates](https://img.shields.io/crates/v/v8.svg)](https://crates.io/crates/v8)
|
[![crates](https://img.shields.io/crates/v/v8.svg)](https://crates.io/crates/v8)
|
||||||
|
|
2
build
2
build
|
@ -1 +1 @@
|
||||||
Subproject commit 8cc2df0e909d0365e20cc0869e565149a723d2ca
|
Subproject commit c6d44e625aa64fa89cbdc971dfd301353bee04f3
|
4
build.rs
4
build.rs
|
@ -47,7 +47,7 @@ fn main() {
|
||||||
"PYTHON",
|
"PYTHON",
|
||||||
"DISABLE_CLANG",
|
"DISABLE_CLANG",
|
||||||
"EXTRA_GN_ARGS",
|
"EXTRA_GN_ARGS",
|
||||||
"NO_PRINT_GN_ARGS",
|
"PRINT_GN_ARGS",
|
||||||
"CARGO_ENCODED_RUSTFLAGS",
|
"CARGO_ENCODED_RUSTFLAGS",
|
||||||
];
|
];
|
||||||
for env in envs {
|
for env in envs {
|
||||||
|
@ -313,7 +313,7 @@ fn build_v8(is_asan: bool) {
|
||||||
let gn_out = maybe_gen(gn_args);
|
let gn_out = maybe_gen(gn_args);
|
||||||
assert!(gn_out.exists());
|
assert!(gn_out.exists());
|
||||||
assert!(gn_out.join("args.gn").exists());
|
assert!(gn_out.join("args.gn").exists());
|
||||||
if env::var_os("NO_PRINT_GN_ARGS").is_none() {
|
if env_bool("PRINT_GN_ARGS") {
|
||||||
print_gn_args(&gn_out);
|
print_gn_args(&gn_out);
|
||||||
}
|
}
|
||||||
build("rusty_v8", None);
|
build("rusty_v8", None);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3ef44a2b92d5dd1faa5189a06f3a5febe6db2d58
|
Subproject commit 60a590902cf146c282f15242401bd8543256e2a2
|
|
@ -33,6 +33,9 @@ EACH_TYPED_ARRAY(TYPED_ARRAY_MAX_LENGTH)
|
||||||
|
|
||||||
using v8__CFunction = v8::CFunction;
|
using v8__CFunction = v8::CFunction;
|
||||||
using v8__CFunctionInfo = v8::CFunctionInfo;
|
using v8__CFunctionInfo = v8::CFunctionInfo;
|
||||||
|
using v8__FastApiArrayBufferView = v8::FastApiArrayBufferView;
|
||||||
|
using v8__FastOneByteString = v8::FastOneByteString;
|
||||||
|
using v8__FastApiTypedArray = v8::FastApiTypedArray<void>;
|
||||||
|
|
||||||
using v8__Isolate__UseCounterFeature = v8::Isolate::UseCounterFeature;
|
using v8__Isolate__UseCounterFeature = v8::Isolate::UseCounterFeature;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::ffi::c_void;
|
|
||||||
|
|
||||||
use crate::binding::*;
|
use crate::binding::*;
|
||||||
use crate::Isolate;
|
use crate::Isolate;
|
||||||
use crate::Local;
|
use crate::Local;
|
||||||
use crate::Value;
|
use crate::Value;
|
||||||
|
use std::ffi::c_void;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -140,42 +140,26 @@ bitflags::bitflags! {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct FastApiCallbackOptions<'a> {
|
pub struct FastApiCallbackOptions<'a> {
|
||||||
pub isolate: *mut Isolate,
|
pub isolate: *mut Isolate,
|
||||||
/// If the callback wants to signal an error condition or to perform an
|
|
||||||
/// allocation, it must set options.fallback to true and do an early return
|
|
||||||
/// from the fast method. Then V8 checks the value of options.fallback and if
|
|
||||||
/// it's true, falls back to executing the SlowCallback, which is capable of
|
|
||||||
/// reporting the error (either by throwing a JS exception or logging to the
|
|
||||||
/// console) or doing the allocation. It's the embedder's responsibility to
|
|
||||||
/// ensure that the fast callback is idempotent up to the point where error and
|
|
||||||
/// fallback conditions are checked, because otherwise executing the slow
|
|
||||||
/// callback might produce visible side-effects twice.
|
|
||||||
pub fallback: bool,
|
|
||||||
/// The `data` passed to the FunctionTemplate constructor, or `undefined`.
|
/// The `data` passed to the FunctionTemplate constructor, or `undefined`.
|
||||||
pub data: Local<'a, Value>,
|
pub data: Local<'a, Value>,
|
||||||
/// When called from WebAssembly, a view of the calling module's memory.
|
|
||||||
pub wasm_memory: *const FastApiTypedArray<u8>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://source.chromium.org/chromium/chromium/src/+/main:v8/include/v8-fast-api-calls.h;l=336
|
#[allow(unused)] // only constructed by V8
|
||||||
#[repr(C)]
|
#[repr(transparent)]
|
||||||
pub struct FastApiTypedArray<T: Default> {
|
pub struct FastApiTypedArray<T: Default>(v8__FastApiTypedArray, PhantomData<T>);
|
||||||
/// Returns the length in number of elements.
|
|
||||||
pub length: usize,
|
|
||||||
// This pointer should include the typed array offset applied.
|
|
||||||
// It's not guaranteed that it's aligned to sizeof(T), it's only
|
|
||||||
// guaranteed that it's 4-byte aligned, so for 8-byte types we need to
|
|
||||||
// provide a special implementation for reading from it, which hides
|
|
||||||
// the possibly unaligned read in the `get` method.
|
|
||||||
data: *mut T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Default> FastApiTypedArray<T> {
|
impl<T: Default> FastApiTypedArray<T> {
|
||||||
|
/// Returns the length in number of elements.
|
||||||
|
pub const fn length(&self) -> usize {
|
||||||
|
self.0._base.length_
|
||||||
|
}
|
||||||
|
|
||||||
/// Performs an unaligned-safe read of T from the underlying data.
|
/// Performs an unaligned-safe read of T from the underlying data.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn get(&self, index: usize) -> T {
|
pub const fn get(&self, index: usize) -> T {
|
||||||
debug_assert!(index < self.length);
|
debug_assert!(index < self.length());
|
||||||
// SAFETY: src is valid for reads, and is a valid value for T
|
// SAFETY: src is valid for reads, and is a valid value for T
|
||||||
unsafe { std::ptr::read_unaligned(self.data.add(index)) }
|
unsafe { std::ptr::read_unaligned((self.0.data_ as *const T).add(index)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a slice pointing to the underlying data if safe to do so.
|
/// Returns a slice pointing to the underlying data if safe to do so.
|
||||||
|
@ -183,14 +167,16 @@ impl<T: Default> FastApiTypedArray<T> {
|
||||||
pub fn get_storage_if_aligned(&self) -> Option<&mut [T]> {
|
pub fn get_storage_if_aligned(&self) -> Option<&mut [T]> {
|
||||||
// V8 may provide an invalid or null pointer when length is zero, so we just
|
// V8 may provide an invalid or null pointer when length is zero, so we just
|
||||||
// ignore that value completely and create an empty slice in this case.
|
// ignore that value completely and create an empty slice in this case.
|
||||||
if self.length == 0 {
|
if self.length() == 0 {
|
||||||
return Some(&mut []);
|
return Some(&mut []);
|
||||||
}
|
}
|
||||||
|
let data = self.0.data_ as *mut T;
|
||||||
// Ensure that we never return an unaligned or null buffer
|
// Ensure that we never return an unaligned or null buffer
|
||||||
if self.data.is_null() || (self.data as usize) % align_of::<T>() != 0 {
|
if data.is_null() || !data.is_aligned() {
|
||||||
return None;
|
None
|
||||||
|
} else {
|
||||||
|
Some(unsafe { std::slice::from_raw_parts_mut(data, self.length()) })
|
||||||
}
|
}
|
||||||
Some(unsafe { std::slice::from_raw_parts_mut(self.data, self.length) })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,19 +186,9 @@ impl<T: Default> FastApiTypedArray<T> {
|
||||||
/// own instance type. It could be supported if we specify that
|
/// own instance type. It could be supported if we specify that
|
||||||
/// TypedArray<T> always has precedence over the generic ArrayBufferView,
|
/// TypedArray<T> always has precedence over the generic ArrayBufferView,
|
||||||
/// but this complicates overload resolution.
|
/// but this complicates overload resolution.
|
||||||
#[repr(C)]
|
pub type FastApiArrayBufferView = v8__FastApiArrayBufferView;
|
||||||
pub struct FastApiArrayBufferView {
|
|
||||||
pub data: *mut c_void,
|
|
||||||
pub byte_length: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
// FastApiOneByteString is an alias for SeqOneByteString and the type is widely used in deno_core.
|
pub type FastApiOneByteString = v8__FastOneByteString;
|
||||||
#[allow(unused)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct FastApiOneByteString {
|
|
||||||
data: *const u8,
|
|
||||||
pub length: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FastApiOneByteString {
|
impl FastApiOneByteString {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -224,6 +200,6 @@ impl FastApiOneByteString {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: The data is guaranteed to be valid for the length of the string.
|
// SAFETY: The data is guaranteed to be valid for the length of the string.
|
||||||
unsafe { std::slice::from_raw_parts(self.data, self.length as usize) }
|
unsafe { std::slice::from_raw_parts(self.data as _, self.length as usize) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
63
src/scope.rs
63
src/scope.rs
|
@ -102,6 +102,7 @@ use std::ops::DerefMut;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
use crate::fast_api::FastApiCallbackOptions;
|
||||||
use crate::function::FunctionCallbackInfo;
|
use crate::function::FunctionCallbackInfo;
|
||||||
use crate::function::PropertyCallbackInfo;
|
use crate::function::PropertyCallbackInfo;
|
||||||
use crate::Context;
|
use crate::Context;
|
||||||
|
@ -628,6 +629,7 @@ where
|
||||||
/// - `&FunctionCallbackInfo`
|
/// - `&FunctionCallbackInfo`
|
||||||
/// - `&PropertyCallbackInfo`
|
/// - `&PropertyCallbackInfo`
|
||||||
/// - `&PromiseRejectMessage`
|
/// - `&PromiseRejectMessage`
|
||||||
|
/// - `&FastApiCallbackOptions`
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CallbackScope<'s, C = Context> {
|
pub struct CallbackScope<'s, C = Context> {
|
||||||
_data: NonNull<data::ScopeData>,
|
_data: NonNull<data::ScopeData>,
|
||||||
|
@ -637,10 +639,23 @@ pub struct CallbackScope<'s, C = Context> {
|
||||||
impl<'s> CallbackScope<'s> {
|
impl<'s> CallbackScope<'s> {
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
pub unsafe fn new<P: param::NewCallbackScope<'s>>(param: P) -> P::NewScope {
|
pub unsafe fn new<P: param::NewCallbackScope<'s>>(param: P) -> P::NewScope {
|
||||||
let (isolate, context) = param.get_isolate_mut_and_maybe_current_context();
|
let context = param.get_context();
|
||||||
data::ScopeData::get_current_mut(isolate)
|
let scope_data = data::ScopeData::get_current_mut(param.get_isolate_mut());
|
||||||
.new_callback_scope_data(context)
|
// A HandleScope is not implicitly created for
|
||||||
.as_scope()
|
// fast functions, so one must be opened here.
|
||||||
|
let scope_data = if P::NEEDS_SCOPE {
|
||||||
|
if let Some(context) = context {
|
||||||
|
scope_data.new_handle_scope_data_with_context(&context)
|
||||||
|
} else {
|
||||||
|
scope_data.new_handle_scope_data()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scope_data.new_callback_scope_data(context)
|
||||||
|
};
|
||||||
|
// This scope needs to exit when dropped, as it
|
||||||
|
// must not live beyond the callback activation.
|
||||||
|
scope_data.disable_zombie();
|
||||||
|
scope_data.as_scope()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1160,11 +1175,10 @@ mod param {
|
||||||
|
|
||||||
pub trait NewCallbackScope<'s>: Sized + getter::GetIsolate<'s> {
|
pub trait NewCallbackScope<'s>: Sized + getter::GetIsolate<'s> {
|
||||||
type NewScope: Scope;
|
type NewScope: Scope;
|
||||||
|
const NEEDS_SCOPE: bool = false;
|
||||||
|
|
||||||
unsafe fn get_isolate_mut_and_maybe_current_context(
|
fn get_context(&self) -> Option<Local<'s, Context>> {
|
||||||
self,
|
None
|
||||||
) -> (&'s mut Isolate, Option<Local<'s, Context>>) {
|
|
||||||
(self.get_isolate_mut(), None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,13 +1198,16 @@ mod param {
|
||||||
type NewScope = CallbackScope<'s>;
|
type NewScope = CallbackScope<'s>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'s> NewCallbackScope<'s> for &'s FastApiCallbackOptions<'s> {
|
||||||
|
type NewScope = CallbackScope<'s>;
|
||||||
|
const NEEDS_SCOPE: bool = true;
|
||||||
|
}
|
||||||
|
|
||||||
impl<'s> NewCallbackScope<'s> for Local<'s, Context> {
|
impl<'s> NewCallbackScope<'s> for Local<'s, Context> {
|
||||||
type NewScope = CallbackScope<'s>;
|
type NewScope = CallbackScope<'s>;
|
||||||
|
|
||||||
unsafe fn get_isolate_mut_and_maybe_current_context(
|
fn get_context(&self) -> Option<Local<'s, Context>> {
|
||||||
self,
|
Some(*self)
|
||||||
) -> (&'s mut Isolate, Option<Local<'s, Context>>) {
|
|
||||||
(getter::GetIsolate::get_isolate_mut(self), Some(self))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1241,6 +1258,12 @@ mod getter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'s> GetIsolate<'s> for &'s FastApiCallbackOptions<'s> {
|
||||||
|
unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
|
||||||
|
&mut *self.isolate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'s> GetIsolate<'s> for Local<'s, Context> {
|
impl<'s> GetIsolate<'s> for Local<'s, Context> {
|
||||||
unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
|
unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
|
||||||
&mut *raw::v8__Context__GetIsolate(&*self)
|
&mut *raw::v8__Context__GetIsolate(&*self)
|
||||||
|
@ -1405,6 +1428,7 @@ pub(crate) mod data {
|
||||||
let isolate = data.isolate;
|
let isolate = data.isolate;
|
||||||
data.scope_type_specific_data.init_with(|| {
|
data.scope_type_specific_data.init_with(|| {
|
||||||
ScopeTypeSpecificData::HandleScope {
|
ScopeTypeSpecificData::HandleScope {
|
||||||
|
allow_zombie: true,
|
||||||
raw_handle_scope: unsafe { raw::HandleScope::uninit() },
|
raw_handle_scope: unsafe { raw::HandleScope::uninit() },
|
||||||
raw_context_scope: None,
|
raw_context_scope: None,
|
||||||
}
|
}
|
||||||
|
@ -1413,6 +1437,7 @@ pub(crate) mod data {
|
||||||
ScopeTypeSpecificData::HandleScope {
|
ScopeTypeSpecificData::HandleScope {
|
||||||
raw_handle_scope,
|
raw_handle_scope,
|
||||||
raw_context_scope,
|
raw_context_scope,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
unsafe { raw_handle_scope.init(isolate) };
|
unsafe { raw_handle_scope.init(isolate) };
|
||||||
init_context_fn(isolate, &mut data.context, raw_context_scope);
|
init_context_fn(isolate, &mut data.context, raw_context_scope);
|
||||||
|
@ -1422,6 +1447,15 @@ pub(crate) mod data {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(super) fn disable_zombie(&mut self) {
|
||||||
|
if let ScopeTypeSpecificData::HandleScope { allow_zombie, .. } =
|
||||||
|
&mut self.scope_type_specific_data
|
||||||
|
{
|
||||||
|
*allow_zombie = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(super) fn new_handle_scope_data(&mut self) -> &mut Self {
|
pub(super) fn new_handle_scope_data(&mut self) -> &mut Self {
|
||||||
self.new_handle_scope_data_with(|_, _, raw_context_scope| {
|
self.new_handle_scope_data_with(|_, _, raw_context_scope| {
|
||||||
|
@ -1732,7 +1766,9 @@ pub(crate) mod data {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(super) fn notify_scope_dropped(&mut self) {
|
pub(super) fn notify_scope_dropped(&mut self) {
|
||||||
match &self.scope_type_specific_data {
|
match &self.scope_type_specific_data {
|
||||||
ScopeTypeSpecificData::HandleScope { .. }
|
ScopeTypeSpecificData::HandleScope {
|
||||||
|
allow_zombie: true, ..
|
||||||
|
}
|
||||||
| ScopeTypeSpecificData::EscapableHandleScope { .. } => {
|
| ScopeTypeSpecificData::EscapableHandleScope { .. } => {
|
||||||
// Defer scope exit until the parent scope is touched.
|
// Defer scope exit until the parent scope is touched.
|
||||||
self.status.set(match self.status.get() {
|
self.status.set(match self.status.get() {
|
||||||
|
@ -1864,6 +1900,7 @@ pub(crate) mod data {
|
||||||
_raw_context_scope: raw::ContextScope,
|
_raw_context_scope: raw::ContextScope,
|
||||||
},
|
},
|
||||||
HandleScope {
|
HandleScope {
|
||||||
|
allow_zombie: bool,
|
||||||
raw_handle_scope: raw::HandleScope,
|
raw_handle_scope: raw::HandleScope,
|
||||||
raw_context_scope: Option<raw::ContextScope>,
|
raw_context_scope: Option<raw::ContextScope>,
|
||||||
},
|
},
|
||||||
|
|
|
@ -10451,7 +10451,13 @@ fn host_create_shadow_realm_context_callback() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fast_calls() {
|
fn test_fast_calls() {
|
||||||
static mut WHO: &str = "none";
|
static mut WHO: &str = "none";
|
||||||
fn fast_fn(_recv: v8::Local<v8::Object>, a: u32, b: u32) -> u32 {
|
fn fast_fn(
|
||||||
|
_recv: v8::Local<v8::Object>,
|
||||||
|
a: u32,
|
||||||
|
b: u32,
|
||||||
|
options: &v8::fast_api::FastApiCallbackOptions,
|
||||||
|
) -> u32 {
|
||||||
|
let _scope = unsafe { v8::CallbackScope::new(options) };
|
||||||
unsafe { WHO = "fast" };
|
unsafe { WHO = "fast" };
|
||||||
a + b
|
a + b
|
||||||
}
|
}
|
||||||
|
@ -10464,6 +10470,7 @@ fn test_fast_calls() {
|
||||||
fast_api::Type::V8Value.scalar(),
|
fast_api::Type::V8Value.scalar(),
|
||||||
fast_api::Type::Uint32.scalar(),
|
fast_api::Type::Uint32.scalar(),
|
||||||
fast_api::Type::Uint32.scalar(),
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
fast_api::Type::CallbackOptions.scalar(),
|
||||||
],
|
],
|
||||||
fast_api::Int64Representation::Number,
|
fast_api::Int64Representation::Number,
|
||||||
),
|
),
|
||||||
|
@ -10887,7 +10894,7 @@ fn test_fast_calls_overload() {
|
||||||
) {
|
) {
|
||||||
unsafe { WHO = "fast_buf" };
|
unsafe { WHO = "fast_buf" };
|
||||||
let buf = unsafe { &*data };
|
let buf = unsafe { &*data };
|
||||||
assert_eq!(buf.length, 2);
|
assert_eq!(buf.length(), 2);
|
||||||
assert_eq!(buf.get(0), 6);
|
assert_eq!(buf.get(0), 6);
|
||||||
assert_eq!(buf.get(1), 9);
|
assert_eq!(buf.get(1), 9);
|
||||||
}
|
}
|
||||||
|
@ -10977,77 +10984,6 @@ fn test_fast_calls_overload() {
|
||||||
assert_eq!("fast_array", unsafe { WHO });
|
assert_eq!("fast_array", unsafe { WHO });
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fast_calls_callback_options_fallback() {
|
|
||||||
static mut WHO: &str = "none";
|
|
||||||
fn fast_fn(
|
|
||||||
_recv: v8::Local<v8::Object>,
|
|
||||||
options: *mut fast_api::FastApiCallbackOptions,
|
|
||||||
) {
|
|
||||||
if unsafe { WHO == "fast" } {
|
|
||||||
let options = unsafe { &mut *options };
|
|
||||||
options.fallback = true; // Go back to slow path.
|
|
||||||
} else {
|
|
||||||
unsafe { WHO = "fast" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
|
||||||
fast_fn as _,
|
|
||||||
&fast_api::CFunctionInfo::new(
|
|
||||||
fast_api::Type::Void.scalar(),
|
|
||||||
&[
|
|
||||||
fast_api::Type::V8Value.scalar(),
|
|
||||||
fast_api::Type::CallbackOptions.scalar(),
|
|
||||||
],
|
|
||||||
fast_api::Int64Representation::Number,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
fn slow_fn(
|
|
||||||
scope: &mut v8::HandleScope,
|
|
||||||
_: v8::FunctionCallbackArguments,
|
|
||||||
mut rv: v8::ReturnValue<v8::Value>,
|
|
||||||
) {
|
|
||||||
unsafe { WHO = "slow" };
|
|
||||||
rv.set(v8::Boolean::new(scope, false).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
let _setup_guard = setup::parallel_test();
|
|
||||||
let isolate = &mut v8::Isolate::new(Default::default());
|
|
||||||
let scope = &mut v8::HandleScope::new(isolate);
|
|
||||||
let context = v8::Context::new(scope, Default::default());
|
|
||||||
let scope = &mut v8::ContextScope::new(scope, context);
|
|
||||||
|
|
||||||
let global = context.global(scope);
|
|
||||||
|
|
||||||
let template =
|
|
||||||
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &[FAST_TEST]);
|
|
||||||
|
|
||||||
let name = v8::String::new(scope, "func").unwrap();
|
|
||||||
let value = template.get_function(scope).unwrap();
|
|
||||||
global.set(scope, name.into(), value.into()).unwrap();
|
|
||||||
let source = r#"
|
|
||||||
function f() { return func(); }
|
|
||||||
%PrepareFunctionForOptimization(f);
|
|
||||||
f();
|
|
||||||
"#;
|
|
||||||
eval(scope, source).unwrap();
|
|
||||||
assert_eq!("slow", unsafe { WHO });
|
|
||||||
|
|
||||||
let source = r#"
|
|
||||||
%OptimizeFunctionOnNextCall(f);
|
|
||||||
f();
|
|
||||||
"#;
|
|
||||||
eval(scope, source).unwrap();
|
|
||||||
assert_eq!("fast", unsafe { WHO });
|
|
||||||
let source = r#"
|
|
||||||
f(); // Second call fallbacks back to slow path.
|
|
||||||
"#;
|
|
||||||
eval(scope, source).unwrap();
|
|
||||||
assert_eq!("slow", unsafe { WHO });
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fast_calls_callback_options_data() {
|
fn test_fast_calls_callback_options_data() {
|
||||||
static mut DATA: bool = false;
|
static mut DATA: bool = false;
|
||||||
|
@ -11057,7 +10993,6 @@ fn test_fast_calls_callback_options_data() {
|
||||||
) {
|
) {
|
||||||
let options = &mut *options;
|
let options = &mut *options;
|
||||||
if !options.data.is_external() {
|
if !options.data.is_external() {
|
||||||
options.fallback = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11079,11 +11014,10 @@ fn test_fast_calls_callback_options_data() {
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
scope: &mut v8::HandleScope,
|
_: &mut v8::HandleScope,
|
||||||
_: v8::FunctionCallbackArguments,
|
_: v8::FunctionCallbackArguments,
|
||||||
mut rv: v8::ReturnValue<v8::Value>,
|
_: v8::ReturnValue<v8::Value>,
|
||||||
) {
|
) {
|
||||||
rv.set(v8::Boolean::new(scope, false).into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _setup_guard = setup::parallel_test();
|
let _setup_guard = setup::parallel_test();
|
||||||
|
|
2
third_party/abseil-cpp
vendored
2
third_party/abseil-cpp
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 9d1552f25c3d9e9114b7d7aed55790570a99bc4d
|
Subproject commit ed3733b91e472a1e7a641c1f0c1e6c0ea698e958
|
2
third_party/libc++/src
vendored
2
third_party/libc++/src
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 6bb75caa139ee1e686d2205910454cf6ea212e58
|
Subproject commit f801c947082a3e0a4b48780303526b73905f6ecd
|
2
third_party/libc++abi/src
vendored
2
third_party/libc++abi/src
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit a3c7d3e2f3e1e724b4651891b1a71257cbd88acc
|
Subproject commit eb6567388e89d9730c76dee71d68ac82e4a1abf6
|
2
third_party/libunwind/src
vendored
2
third_party/libunwind/src
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit d09db732ff68f40fd3581306c650b17ea1955b4e
|
Subproject commit 116c20dae60d84a77005697cf29f72783f81b0f9
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4dc76da47b1145e53e508a23c1bf2204cf5ee7ee
|
Subproject commit 63b7be17f8981d716ea9a0d65bb04654d79548a8
|
|
@ -7,7 +7,7 @@ with open('./v8/DEPS') as f:
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
def process(name, dep):
|
def process(name, dep):
|
||||||
if name == 'build':
|
if name == 'build' or name == 'third_party/icu':
|
||||||
# We have our own fork of this
|
# We have our own fork of this
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
2
v8
2
v8
|
@ -1 +1 @@
|
||||||
Subproject commit 8e78e913dfed43460b215473fe39db2fce46984e
|
Subproject commit bc49fb862240af6bfa37dbbae09db7eafd3719e8
|
Loading…
Reference in a new issue