From 6cc61a26b2130c48b2267148102f9ea5e45667a6 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Fri, 2 Jun 2023 20:28:14 +0300 Subject: [PATCH 01/70] feat(fastcall): Int64Representation (#1238) * feat(fastcall): Int64Representation * Add tests, new_with_bigint API * Fix build, actually --- src/binding.cc | 5 ++- src/fast_api.rs | 33 +++++++++++++- src/template.rs | 14 +++++- tests/test_api.rs | 107 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 6 deletions(-) diff --git a/src/binding.cc b/src/binding.cc index 2ae30fcf59..2ba9f30031 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -1979,9 +1979,10 @@ v8::CTypeInfo* v8__CTypeInfo__New__From__Slice(unsigned int len, v8::CFunctionInfo* v8__CFunctionInfo__New(const v8::CTypeInfo& return_info, unsigned int args_len, - v8::CTypeInfo* args_info) { + v8::CTypeInfo* args_info, + v8::CFunctionInfo::Int64Representation repr) { std::unique_ptr info = std::make_unique( - v8::CFunctionInfo(return_info, args_len, args_info)); + v8::CFunctionInfo(return_info, args_len, args_info, repr)); return info.release(); } diff --git a/src/fast_api.rs b/src/fast_api.rs index 3611c360d6..6cf479612b 100644 --- a/src/fast_api.rs +++ b/src/fast_api.rs @@ -17,6 +17,7 @@ extern "C" { return_info: *const CTypeInfo, args_len: usize, args_info: *const CTypeInfo, + repr: Int64Representation, ) -> *mut CFunctionInfo; } @@ -34,8 +35,14 @@ impl CFunctionInfo { args: *const CTypeInfo, args_len: usize, return_type: *const CTypeInfo, + repr: Int64Representation, ) -> NonNull { - NonNull::new_unchecked(v8__CFunctionInfo__New(return_type, args_len, args)) + NonNull::new_unchecked(v8__CFunctionInfo__New( + return_type, + args_len, + args, + repr, + )) } } @@ -246,8 +253,9 @@ impl FastApiTypedArray { pub struct FastFunction { pub args: &'static [Type], - pub return_type: CType, pub function: *const c_void, + pub repr: Int64Representation, + pub return_type: CType, } impl FastFunction { @@ -259,8 +267,29 @@ impl FastFunction { ) -> Self { Self { args, + function, + repr: Int64Representation::Number, return_type, + } + } + + pub const fn new_with_bigint( + args: &'static [Type], + return_type: CType, + function: *const c_void, + ) -> Self { + Self { + args, function, + repr: Int64Representation::BigInt, + return_type, } } } + +#[derive(Copy, Clone, Debug)] +#[repr(u8)] +pub enum Int64Representation { + Number = 0, + BigInt = 1, +} diff --git a/src/template.rs b/src/template.rs index 82a5be8518..2bffb9958a 100644 --- a/src/template.rs +++ b/src/template.rs @@ -578,7 +578,12 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> { let args = CTypeInfo::new_from_slice(overload1.args); let ret = CTypeInfo::new(overload1.return_type); let fn_info = unsafe { - CFunctionInfo::new(args.as_ptr(), overload1.args.len(), ret.as_ptr()) + CFunctionInfo::new( + args.as_ptr(), + overload1.args.len(), + ret.as_ptr(), + overload1.repr, + ) }; fn_info.as_ptr() }; @@ -590,7 +595,12 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> { let args = CTypeInfo::new_from_slice(overload2.args); let ret = CTypeInfo::new(overload2.return_type); let fn_info = unsafe { - CFunctionInfo::new(args.as_ptr(), overload2.args.len(), ret.as_ptr()) + CFunctionInfo::new( + args.as_ptr(), + overload2.args.len(), + ret.as_ptr(), + overload2.repr, + ) }; fn_info.as_ptr() } diff --git a/tests/test_api.rs b/tests/test_api.rs index 7a437a1e47..52e4dbdda8 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -9873,6 +9873,113 @@ fn test_fast_calls_onebytestring() { assert_eq!("fast", unsafe { WHO }); } +#[test] +fn test_fast_calls_i64representation() { + static mut FAST_CALL_COUNT: u32 = 0; + static mut SLOW_CALL_COUNT: u32 = 0; + fn fast_fn(_recv: v8::Local, a: u64, b: u64) -> u64 { + unsafe { FAST_CALL_COUNT += 1 }; + assert_eq!(9007199254740991, a); + assert_eq!(646, b); + a * b + } + + const FAST_TEST_NUMBER: fast_api::FastFunction = fast_api::FastFunction::new( + &[V8Value, Uint64, Uint64], + CType::Uint64, + fast_fn as _, + ); + + const FAST_TEST_BIGINT: fast_api::FastFunction = + fast_api::FastFunction::new_with_bigint( + &[V8Value, Uint64, Uint64], + CType::Uint64, + fast_fn as _, + ); + + fn slow_fn( + _: &mut v8::HandleScope, + _: v8::FunctionCallbackArguments, + _: v8::ReturnValue, + ) { + unsafe { SLOW_CALL_COUNT += 1 }; + } + + 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); + let scope = &mut v8::ContextScope::new(scope, context); + + let global = context.global(scope); + + let template_number = v8::FunctionTemplate::builder(slow_fn).build_fast( + scope, + &FAST_TEST_NUMBER, + None, + None, + None, + ); + let template_bigint = v8::FunctionTemplate::builder(slow_fn).build_fast( + scope, + &FAST_TEST_BIGINT, + None, + None, + None, + ); + + let name_number = v8::String::new(scope, "func_number").unwrap(); + let name_bigint = v8::String::new(scope, "func_bigint").unwrap(); + let value_number = template_number.get_function(scope).unwrap(); + let value_bigint = template_bigint.get_function(scope).unwrap(); + global + .set(scope, name_number.into(), value_number.into()) + .unwrap(); + global + .set(scope, name_bigint.into(), value_bigint.into()) + .unwrap(); + let source = r#" + function f(a, b) { return func_number(a, b); } + %PrepareFunctionForOptimization(f); + f(1, 2); +"#; + eval(scope, source).unwrap(); + assert_eq!(1, unsafe { SLOW_CALL_COUNT }); + + let source = r#" + %OptimizeFunctionOnNextCall(f); + { + const result = f(Number.MAX_SAFE_INTEGER, 646); + // Correct answer is 5818650718562680186: data is lost. + if (result != 5818650718562680000) { + throw new Error(`wrong number result: ${result}`); + } + } + "#; + eval(scope, source).unwrap(); + assert_eq!(1, unsafe { FAST_CALL_COUNT }); + + let source = r#" + function g(a, b) { return func_bigint(a, b); } + %PrepareFunctionForOptimization(g); + g(1n, 2n); +"#; + eval(scope, source).unwrap(); + assert_eq!(2, unsafe { SLOW_CALL_COUNT }); + + let source = r#" + %OptimizeFunctionOnNextCall(g); + { + const result = g(BigInt(Number.MAX_SAFE_INTEGER), 646n); + if (result != 5818650718562680186n) { + throw new Error(`wrong bigint result: ${result}`); + } + } + "#; + eval(scope, source).unwrap(); + assert_eq!(2, unsafe { FAST_CALL_COUNT }); +} + #[test] fn gc_callbacks() { let _setup_guard = setup::parallel_test(); From 5a15d85f2fbce79c4823462374b20124fd87d3b0 Mon Sep 17 00:00:00 2001 From: Francesco Ceccon Date: Mon, 5 Jun 2023 18:28:56 +0100 Subject: [PATCH 02/70] Don't preserve V8 archive mode and ownership on build (#1244) By default, copying a file will preserve its mode and ownership attributes. This is an issue when copying the V8 archive from a read-only filesystem since the archive file also becomes read-only, so subsequent builds will fail. We now create a new destination file and copy the content of the archive to it, this ensures the destination file has the default attributes. --- build.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/build.rs b/build.rs index 5c1698a1e8..94e89504d6 100644 --- a/build.rs +++ b/build.rs @@ -3,6 +3,7 @@ use fslock::LockFile; use std::collections::HashSet; use std::env; use std::fs; +use std::io; use std::path::Path; use std::path::PathBuf; use std::process::exit; @@ -383,7 +384,7 @@ fn build_dir() -> PathBuf { fn download_file(url: String, filename: PathBuf) { if !url.starts_with("http:") && !url.starts_with("https:") { - fs::copy(&url, filename).unwrap(); + copy_archive(&url, &filename); return; } @@ -455,6 +456,19 @@ fn download_static_lib_binaries() { download_file(url, static_lib_path()); } +/// Copy the V8 archive at `url` to `filename`. +/// +/// This function doesn't use `std::fs::copy` because that would +/// preveserve the file attributes such as ownership and mode flags. +/// Instead, it copies the file contents to a new file. +/// This is necessary because the V8 archive could live inside a read-only +/// filesystem, and subsequent builds would fail to overwrite it. +fn copy_archive(url: &str, filename: &Path) { + let mut src = fs::File::open(url).unwrap(); + let mut dst = fs::File::create(filename).unwrap(); + io::copy(&mut src, &mut dst).unwrap(); +} + fn print_link_flags() { println!("cargo:rustc-link-lib=static=rusty_v8"); From 270f46aa5f2f9df0d1732a50de6a2945c0746024 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Thu, 15 Jun 2023 19:00:42 +0200 Subject: [PATCH 03/70] chore: support 128-bit TypeId (#1249) --- src/isolate.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/isolate.rs b/src/isolate.rs index b0657cd39a..b9b3019996 100644 --- a/src/isolate.rs +++ b/src/isolate.rs @@ -1686,6 +1686,8 @@ impl Hasher for TypeIdHasher { #[inline] fn write_u64(&mut self, value: u64) { + // The internal hash function of TypeId only takes the bottom 64-bits, even on versions + // of Rust that use a 128-bit TypeId. let prev_state = self.state.replace(value); debug_assert_eq!(prev_state, None); } @@ -1712,8 +1714,14 @@ impl BuildHasher for BuildTypeIdHasher { } const _: () = { - assert!(size_of::() == size_of::()); - assert!(align_of::() == align_of::()); + assert!( + size_of::() == size_of::() + || size_of::() == size_of::() + ); + assert!( + align_of::() == align_of::() + || align_of::() == align_of::() + ); }; pub(crate) struct RawSlot { From 8fc39ebdc83ad217e70a6b26a2cacde752861b97 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Sun, 18 Jun 2023 02:36:04 +0200 Subject: [PATCH 04/70] Rolling to V8 11.5.150.10 (#1243) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f24287870a..631570d3e2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.5.150.2 +V8 Version: 11.5.150.10 [![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) diff --git a/v8 b/v8 index 3e797a2aac..297c562b9f 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 3e797a2aacc68a76b40f3992ce926cda9c576d98 +Subproject commit 297c562b9f33dd0eb9c6be73900c28fbc7b25387 From b97dd1b1d8c0f105f1b7f716be3ce007e4bc67ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sun, 25 Jun 2023 09:26:36 +0200 Subject: [PATCH 05/70] Track v8 11.6 (#1252) --- tools/auto_update_v8.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/auto_update_v8.ts b/tools/auto_update_v8.ts index d7ffbd0b07..d541a38b60 100644 --- a/tools/auto_update_v8.ts +++ b/tools/auto_update_v8.ts @@ -1,4 +1,4 @@ -const V8_TRACKING_BRANCH = "11.5-lkgr-denoland"; +const V8_TRACKING_BRANCH = "11.6-lkgr-denoland"; const AUTOROLL_BRANCH = "autoroll"; function extractVersion() { From 672254e1131d9f671c5b304850379448ea32e5eb Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Mon, 26 Jun 2023 09:30:16 -0600 Subject: [PATCH 06/70] feat: Fix is_onebyte and add an uninit write for onebyte (#1255) Some fixes around one-byte strings: - `is_onebyte` was calling the wrong v8 API. - We didn't have a way to write one-byte strings with uninitialized buffers - (bonus) The test_string method was quite slow making testing a bit of a pain --- src/string.rs | 33 +++++++++++++++++++++++++----- tests/test_api.rs | 52 +++++++++++++++++++++++++++++++---------------- 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/string.rs b/src/string.rs index 222ba6909b..55a5d92bc4 100644 --- a/src/string.rs +++ b/src/string.rs @@ -258,6 +258,28 @@ impl String { } } + /// Writes the contents of the string to an external [`MaybeUninit`] buffer, as one-byte + /// (Latin-1) characters. + #[inline(always)] + pub fn write_one_byte_uninit( + &self, + scope: &mut Isolate, + buffer: &mut [MaybeUninit], + start: usize, + options: WriteOptions, + ) -> usize { + unsafe { + v8__String__WriteOneByte( + self, + scope, + buffer.as_mut_ptr() as *mut u8, + start.try_into().unwrap_or(int::max_value()), + buffer.len().try_into().unwrap_or(int::max_value()), + options, + ) as usize + } + } + /// Writes the contents of the string to an external buffer, as UTF-8. #[inline(always)] pub fn write_utf8( @@ -281,7 +303,7 @@ impl String { } } - /// Writes the contents of the string to an external buffer, as UTF-8. + /// Writes the contents of the string to an external [`MaybeUninit`] buffer, as UTF-8. pub fn write_utf8_uninit( &self, scope: &mut Isolate, @@ -378,16 +400,17 @@ impl String { unsafe { v8__String__IsExternalTwoByte(self) } } - /// True if string is known to contain only one-byte data. - /// Doesn't read the string so can return false positives. + /// Will return true if and only if string is known for certain to contain only one-byte data, + /// ie: Latin-1, a.k.a. ISO-8859-1 code points. Doesn't read the string so can return false + /// negatives, and a return value of false does not mean this string is not one-byte data. /// - /// For a method that will not return false positives at the cost of + /// For a method that will not return false negatives at the cost of /// potentially reading the entire string, use [`contains_only_onebyte()`]. /// /// [`contains_only_onebyte()`]: String::contains_only_onebyte #[inline(always)] pub fn is_onebyte(&self) -> bool { - unsafe { v8__String__IsExternalOneByte(self) } + unsafe { v8__String__IsOneByte(self) } } /// True if the string contains only one-byte data. diff --git a/tests/test_api.rs b/tests/test_api.rs index 52e4dbdda8..9679751f59 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -305,27 +305,35 @@ fn test_string() { } { let scope = &mut v8::HandleScope::new(isolate); - let buffer = (0..v8::String::max_length() / 4) - .map(|_| '\u{10348}') // UTF8: 0xF0 0x90 0x8D 0x88 - .collect::(); - let local = v8::String::new_from_utf8( - scope, - buffer.as_bytes(), - v8::NewStringType::Normal, - ) - .unwrap(); + let mut buffer = Vec::with_capacity(v8::String::max_length()); + for _ in 0..buffer.capacity() / 4 { + // U+10348 in UTF-8 + buffer.push(0xF0_u8); + buffer.push(0x90_u8); + buffer.push(0x8D_u8); + buffer.push(0x88_u8); + } + let local = + v8::String::new_from_utf8(scope, &buffer, v8::NewStringType::Normal) + .unwrap(); // U+10348 is 2 UTF-16 code units, which is the unit of v8::String.length(). assert_eq!(v8::String::max_length() / 2, local.length()); - assert_eq!(buffer, local.to_rust_string_lossy(scope)); - - let too_long = (0..(v8::String::max_length() / 4) + 1) - .map(|_| '\u{10348}') // UTF8: 0xF0 0x90 0x8D 0x88 - .collect::(); - let none = v8::String::new_from_utf8( - scope, - too_long.as_bytes(), - v8::NewStringType::Normal, + assert_eq!( + buffer.as_slice(), + local.to_rust_string_lossy(scope).as_bytes() ); + + let mut too_long = Vec::with_capacity(v8::String::max_length() + 4); + for _ in 0..too_long.capacity() / 4 { + // U+10348 in UTF-8 + too_long.push(0xF0_u8); + too_long.push(0x90_u8); + too_long.push(0x8D_u8); + too_long.push(0x88_u8); + } + + let none = + v8::String::new_from_utf8(scope, &too_long, v8::NewStringType::Normal); assert!(none.is_none()); } { @@ -8316,6 +8324,14 @@ fn external_strings() { assert!(!gradients.is_external_twobyte()); assert!(!gradients.is_onebyte()); assert!(!gradients.contains_only_onebyte()); + + // one-byte "internal" test + let latin1 = v8::String::new(scope, "latin-1").unwrap(); + assert!(!latin1.is_external()); + assert!(!latin1.is_external_onebyte()); + assert!(!latin1.is_external_twobyte()); + assert!(latin1.is_onebyte()); + assert!(latin1.contains_only_onebyte()); } #[test] From 63df1735fd4ed60c4605cb8e04f032f35577ef56 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:50:31 +0200 Subject: [PATCH 07/70] Rolling to V8 11.6.189.6 (#1253) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartek Iwańczuk --- .gn | 5 +++++ README.md | 2 +- src/isolate.rs | 2 +- v8 | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.gn b/.gn index d81db0323c..0ba2aeb930 100644 --- a/.gn +++ b/.gn @@ -56,4 +56,9 @@ default_args = { # makes sure that the EPT is not used. # https://bugs.chromium.org/p/v8/issues/detail?id=13640&q=garbage%20collection&can=2 v8_enable_pointer_compression = false + + # V8 11.6 hardcoded an assumption in `mksnapshot` that shared RO heap + # is enabled. In our case it's disabled so without this flag we can't + # compile. + v8_enable_verify_heap = false } diff --git a/README.md b/README.md index 631570d3e2..078b22b2a7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.5.150.10 +V8 Version: 11.6.189.6 [![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) diff --git a/src/isolate.rs b/src/isolate.rs index b9b3019996..b71f8c5e4e 100644 --- a/src/isolate.rs +++ b/src/isolate.rs @@ -543,7 +543,7 @@ impl Isolate { // Byte offset inside `Isolate` where the isolate data slots are stored. This // should be the same as the value of `kIsolateEmbedderDataOffset` which is // defined in `v8-internal.h`. - const EMBEDDER_DATA_OFFSET: usize = size_of::<[*const (); 61]>(); + const EMBEDDER_DATA_OFFSET: usize = size_of::<[*const (); 62]>(); // Isolate data slots used internally by rusty_v8. const ANNEX_SLOT: u32 = 0; diff --git a/v8 b/v8 index 297c562b9f..ef71f5a180 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 297c562b9f33dd0eb9c6be73900c28fbc7b25387 +Subproject commit ef71f5a1808784aeb7b86d7aa13a7daa4e57f341 From 7419b38aaca4dd9c8ffe06ba4a2c150a3e126858 Mon Sep 17 00:00:00 2001 From: Rakeeb Hossain Date: Tue, 27 Jun 2023 23:09:07 -0700 Subject: [PATCH 08/70] Add `Function::{ScriptId, GetScriptOrigin}, ScriptOrigin::Get{ScriptId, ResourceName, SourceMapUrl}` bindings (#1250) --- src/binding.cc | 24 +++++++++++++++ src/function.rs | 20 +++++++++++- src/script.rs | 28 +++++++++++++++++ tests/test_api.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 1 deletion(-) diff --git a/src/binding.cc b/src/binding.cc index 2ba9f30031..1de8e8536f 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -1952,6 +1952,16 @@ int v8__Function__GetScriptLineNumber(const v8::Function& self) { return ptr_to_local(&self)->GetScriptLineNumber(); } +int v8__Function__ScriptId(const v8::Function& self) { + return ptr_to_local(&self)->ScriptId(); +} + +const v8::ScriptOrigin* v8__Function__GetScriptOrigin(const v8::Function& self) { + std::unique_ptr u = + std::make_unique(ptr_to_local(&self)->GetScriptOrigin()); + return u.release(); +} + const v8::Signature* v8__Signature__New(v8::Isolate* isolate, const v8::FunctionTemplate* templ) { return local_to_ptr(v8::Signature::New(isolate, ptr_to_local(templ))); @@ -2280,6 +2290,20 @@ void v8__ScriptOrigin__CONSTRUCT( ptr_to_local(&source_map_url), resource_is_opaque, is_wasm, is_module); } +int v8__ScriptOrigin__ScriptId(const v8::ScriptOrigin& self) { + return ptr_to_local(&self)->ScriptId(); +} + +const v8::Value* v8__ScriptOrigin__ResourceName( + const v8::ScriptOrigin& self) { + return local_to_ptr(ptr_to_local(&self)->ResourceName()); +} + +const v8::Value* v8__ScriptOrigin__SourceMapUrl( + const v8::ScriptOrigin& self) { + return local_to_ptr(ptr_to_local(&self)->SourceMapUrl()); +} + const v8::Value* v8__ScriptOrModule__GetResourceName( const v8::ScriptOrModule& self) { return local_to_ptr(ptr_to_local(&self)->GetResourceName()); diff --git a/src/function.rs b/src/function.rs index b5fc8483fc..188b61e04e 100644 --- a/src/function.rs +++ b/src/function.rs @@ -10,7 +10,6 @@ use crate::support::MapFnTo; use crate::support::ToCFn; use crate::support::UnitType; use crate::support::{int, Opaque}; -use crate::undefined; use crate::Context; use crate::Function; use crate::HandleScope; @@ -23,6 +22,7 @@ use crate::Signature; use crate::String; use crate::UniqueRef; use crate::Value; +use crate::{undefined, ScriptOrigin}; extern "C" { fn v8__Function__New( @@ -50,6 +50,10 @@ extern "C" { fn v8__Function__SetName(this: *const Function, name: *const String); fn v8__Function__GetScriptColumnNumber(this: *const Function) -> int; fn v8__Function__GetScriptLineNumber(this: *const Function) -> int; + fn v8__Function__ScriptId(this: *const Function) -> int; + fn v8__Function__GetScriptOrigin( + this: *const Function, + ) -> *const ScriptOrigin<'static>; fn v8__Function__CreateCodeCache( script: *const Function, @@ -903,6 +907,20 @@ impl Function { (ret >= 0).then_some(ret as u32) } + #[inline(always)] + pub fn get_script_origin(&self) -> &ScriptOrigin { + unsafe { + let ptr = v8__Function__GetScriptOrigin(self); + &*ptr + } + } + + /// Returns scriptId. + #[inline(always)] + pub fn script_id(&self) -> i32 { + unsafe { v8__Function__ScriptId(self) } + } + /// Creates and returns code cache for the specified unbound_script. /// This will return nullptr if the script cannot be serialized. The /// CachedData returned by this function should be owned by the caller. diff --git a/src/script.rs b/src/script.rs index bdb5e1c56a..c1244f1fee 100644 --- a/src/script.rs +++ b/src/script.rs @@ -43,6 +43,13 @@ extern "C" { is_wasm: bool, is_module: bool, ); + fn v8__ScriptOrigin__ScriptId(origin: *const ScriptOrigin) -> i32; + fn v8__ScriptOrigin__ResourceName( + origin: *const ScriptOrigin, + ) -> *const Value; + fn v8__ScriptOrigin__SourceMapUrl( + origin: *const ScriptOrigin, + ) -> *const Value; } impl Script { @@ -125,4 +132,25 @@ impl<'s> ScriptOrigin<'s> { buf.assume_init() } } + + #[inline(always)] + pub fn script_id(&self) -> i32 { + unsafe { v8__ScriptOrigin__ScriptId(self as *const _) } + } + + #[inline(always)] + pub fn resource_name(&self) -> Option> { + unsafe { + let ptr = v8__ScriptOrigin__ResourceName(self); + Local::from_raw(ptr) + } + } + + #[inline(always)] + pub fn source_map_url(&self) -> Option> { + unsafe { + let ptr = v8__ScriptOrigin__SourceMapUrl(self); + Local::from_raw(ptr) + } + } } diff --git a/tests/test_api.rs b/tests/test_api.rs index 9679751f59..2ebb340337 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -3828,6 +3828,83 @@ export function anotherFunctionG(a, b) { } } +#[test] +fn function_script_origin_and_id() { + 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); + let scope = &mut v8::ContextScope::new(scope, context); + + let mut num_cases = 10; + let mut prev_id = None; + while num_cases > 0 { + let resource_name = format!("google.com/{}", num_cases); + let source = mock_source( + scope, + resource_name.as_str(), // make sure each source has a different resource name + r#"export function f(a, b) { + return a; + } + + export function anotherFunctionG(a, b) { + return b; + }"#, + ); + let module = v8::script_compiler::compile_module(scope, source).unwrap(); + let result = + module.instantiate_module(scope, unexpected_module_resolve_callback); + assert!(result.is_some()); + module.evaluate(scope).unwrap(); + assert_eq!(v8::ModuleStatus::Evaluated, module.get_status()); + + let namespace = module.get_module_namespace(); + assert!(namespace.is_module_namespace_object()); + let namespace_obj = namespace.to_object(scope).unwrap(); + + let f_str = v8::String::new(scope, "f").unwrap(); + let f_function_obj: v8::Local = namespace_obj + .get(scope, f_str.into()) + .unwrap() + .try_into() + .unwrap(); + + // Modules with different resource names will have incrementing script IDs + // but the script ID of the first module is a V8 internal, so should not + // be depended on. + // See https://groups.google.com/g/v8-users/c/iEfceRohiy8 for more discussion. + let script_id = f_function_obj.script_id(); + assert!(f_function_obj.script_id() > 0); + + if let Some(id) = prev_id { + assert_eq!(script_id, id + 1); + assert_eq!(script_id, f_function_obj.get_script_origin().script_id(),); + } + prev_id = Some(script_id); + + // Verify source map URL matches + assert_eq!( + "source_map_url", + f_function_obj + .get_script_origin() + .source_map_url() + .unwrap() + .to_rust_string_lossy(scope) + ); + + // Verify resource name matches in script origin + let resource_name_val = f_function_obj.get_script_origin().resource_name(); + assert!(resource_name_val.is_some()); + assert_eq!( + resource_name_val.unwrap().to_rust_string_lossy(scope), + resource_name + ); + + num_cases -= 1; + } +} + #[test] fn constructor() { let _setup_guard = setup::parallel_test(); From 517f4d70324ecef0070a1b1be2a53e4515299b94 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Wed, 28 Jun 2023 07:46:25 -0600 Subject: [PATCH 09/70] chore: Add copy, clone and debug to some fast API types (#1257) chore: Add copy, clone and debug to some types --- src/fast_api.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fast_api.rs b/src/fast_api.rs index 6cf479612b..05db2a8ac6 100644 --- a/src/fast_api.rs +++ b/src/fast_api.rs @@ -84,7 +84,7 @@ pub enum SequenceType { IsArrayBuffer, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] #[repr(u8)] #[non_exhaustive] pub enum CType { @@ -107,7 +107,7 @@ pub enum CType { CallbackOptions = 255, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] #[non_exhaustive] pub enum Type { Void, @@ -251,6 +251,7 @@ impl FastApiTypedArray { } } +#[derive(Copy, Clone)] pub struct FastFunction { pub args: &'static [Type], pub function: *const c_void, From ad0a65d0a571c5d9c783ac28d94fbbc2c7d59000 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Wed, 28 Jun 2023 07:46:50 -0600 Subject: [PATCH 10/70] feat: Use MaybeUninit for to_rust_string_lossy and add to_rust_cow_lossy (#1256) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartek Iwańczuk --- src/string.rs | 163 ++++++++++++++++++++++++++++++++++++++++++---- tests/test_api.rs | 40 ++++++++++++ 2 files changed, 192 insertions(+), 11 deletions(-) diff --git a/src/string.rs b/src/string.rs index 55a5d92bc4..8c6efbf050 100644 --- a/src/string.rs +++ b/src/string.rs @@ -1,6 +1,6 @@ +use std::borrow::Cow; use std::convert::TryInto; use std::default::Default; -use std::mem::forget; use std::mem::MaybeUninit; use std::slice; @@ -420,22 +420,163 @@ impl String { unsafe { v8__String__ContainsOnlyOneByte(self) } } + /// Creates a copy of a [`crate::String`] in a [`std::string::String`]. /// Convenience function not present in the original V8 API. #[inline(always)] pub fn to_rust_string_lossy( &self, scope: &mut Isolate, ) -> std::string::String { + if self.is_onebyte() { + let len_utf16 = self.length(); + unsafe { + // Create an uninitialized buffer of `capacity` bytes. We need to be careful here to avoid + // accidentally creating a slice of u8 which would be invalid. + let layout = std::alloc::Layout::from_size_align(len_utf16, 1).unwrap(); + let data = std::alloc::alloc(layout) as *mut MaybeUninit; + let buffer = std::ptr::slice_from_raw_parts_mut(data, len_utf16); + + // Write to this MaybeUninit buffer, assuming we're going to fill this entire buffer + let length = self.write_one_byte_uninit( + scope, + &mut *buffer, + 0, + WriteOptions::NO_NULL_TERMINATION + | WriteOptions::REPLACE_INVALID_UTF8, + ); + debug_assert!(length == len_utf16); + + // Return an owned string from this guaranteed now-initialized data + let buffer = data as *mut u8; + return std::string::String::from_raw_parts(buffer, length, len_utf16); + } + } + let capacity = self.utf8_length(scope); - let mut string = std::string::String::with_capacity(capacity); - let data = string.as_mut_ptr(); - forget(string); - let length = self.write_utf8( - scope, - unsafe { slice::from_raw_parts_mut(data, capacity) }, - None, - WriteOptions::NO_NULL_TERMINATION | WriteOptions::REPLACE_INVALID_UTF8, - ); - unsafe { std::string::String::from_raw_parts(data, length, capacity) } + // SAFETY: This allocates a buffer manually using the default allocator using the string's capacity. + // We have a large number of invariants to uphold, so please check changes to this code carefully + unsafe { + // Create an uninitialized buffer of `capacity` bytes. We need to be careful here to avoid + // accidentally creating a slice of u8 which would be invalid. + let layout = std::alloc::Layout::from_size_align(capacity, 1).unwrap(); + let data = std::alloc::alloc(layout) as *mut MaybeUninit; + let buffer = std::ptr::slice_from_raw_parts_mut(data, capacity); + + // Write to this MaybeUninit buffer, assuming we're going to fill this entire buffer + let length = self.write_utf8_uninit( + scope, + &mut *buffer, + None, + WriteOptions::NO_NULL_TERMINATION | WriteOptions::REPLACE_INVALID_UTF8, + ); + debug_assert!(length == capacity); + + // Return an owned string from this guaranteed now-initialized data + let buffer = data as *mut u8; + std::string::String::from_raw_parts(buffer, length, capacity) + } + } + + /// Converts a [`crate::String`] to either an owned [`std::string::String`], or a borrowed [`str`], depending on whether it fits into the + /// provided buffer. + #[inline(always)] + pub fn to_rust_cow_lossy<'a, const N: usize>( + &self, + scope: &mut Isolate, + buffer: &'a mut [MaybeUninit; N], + ) -> Cow<'a, str> { + // TODO(mmastrac): Ideally we should be able to access the string's internal representation + + let len_utf16 = self.length(); + if self.is_onebyte() { + if len_utf16 <= N { + let length = self.write_one_byte_uninit( + scope, + buffer, + 0, + WriteOptions::NO_NULL_TERMINATION, + ); + debug_assert!(length == len_utf16); + unsafe { + // Get a slice of &[u8] of what we know is initialized now + let buffer = &mut buffer[..length]; + let buffer = &mut *(buffer as *mut [_] as *mut [u8]); + + // We know it's valid UTF-8, so make a string + return Cow::Borrowed(std::str::from_utf8_unchecked(buffer)); + } + } + + unsafe { + // Create an uninitialized buffer of `capacity` bytes. We need to be careful here to avoid + // accidentally creating a slice of u8 which would be invalid. + let layout = std::alloc::Layout::from_size_align(len_utf16, 1).unwrap(); + let data = std::alloc::alloc(layout) as *mut MaybeUninit; + let buffer = std::ptr::slice_from_raw_parts_mut(data, len_utf16); + + // Write to this MaybeUninit buffer, assuming we're going to fill this entire buffer + let length = self.write_one_byte_uninit( + scope, + &mut *buffer, + 0, + WriteOptions::NO_NULL_TERMINATION + | WriteOptions::REPLACE_INVALID_UTF8, + ); + debug_assert!(length == len_utf16); + + // Return an owned string from this guaranteed now-initialized data + let buffer = data as *mut u8; + return Cow::Owned(std::string::String::from_raw_parts( + buffer, length, len_utf16, + )); + } + } + + let capacity = self.utf8_length(scope); + if capacity <= N { + // No malloc path + let length = self.write_utf8_uninit( + scope, + buffer, + None, + WriteOptions::NO_NULL_TERMINATION | WriteOptions::REPLACE_INVALID_UTF8, + ); + debug_assert!(length == capacity); + + // SAFETY: We know that we wrote `length` UTF-8 bytes. See `slice_assume_init_mut` for additional guarantee information. + unsafe { + // Get a slice of &[u8] of what we know is initialized now + let buffer = &mut buffer[..length]; + let buffer = &mut *(buffer as *mut [_] as *mut [u8]); + + // We know it's valid UTF-8, so make a string + return Cow::Borrowed(std::str::from_utf8_unchecked(buffer)); + } + } + + // SAFETY: This allocates a buffer manually using the default allocator using the string's capacity. + // We have a large number of invariants to uphold, so please check changes to this code carefully + unsafe { + // Create an uninitialized buffer of `capacity` bytes. We need to be careful here to avoid + // accidentally creating a slice of u8 which would be invalid. + let layout = std::alloc::Layout::from_size_align(capacity, 1).unwrap(); + let data = std::alloc::alloc(layout) as *mut MaybeUninit; + let buffer = std::ptr::slice_from_raw_parts_mut(data, capacity); + + // Write to this MaybeUninit buffer, assuming we're going to fill this entire buffer + let length = self.write_utf8_uninit( + scope, + &mut *buffer, + None, + WriteOptions::NO_NULL_TERMINATION | WriteOptions::REPLACE_INVALID_UTF8, + ); + debug_assert!(length == capacity); + + // Return an owned string from this guaranteed now-initialized data + let buffer = data as *mut u8; + Cow::Owned(std::string::String::from_raw_parts( + buffer, length, capacity, + )) + } } } diff --git a/tests/test_api.rs b/tests/test_api.rs index 2ebb340337..d6ed851149 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -1,6 +1,7 @@ // Copyright 2019-2021 the Deno authors. All rights reserved. MIT license. use once_cell::sync::Lazy; use std::any::type_name; +use std::borrow::Cow; use std::cell::RefCell; use std::collections::hash_map::DefaultHasher; use std::collections::HashMap; @@ -410,6 +411,45 @@ fn test_string() { let invalid_4_octet_sequence = valid_6_octet_sequence.unwrap(); assert_eq!(invalid_4_octet_sequence.length(), 6); } + { + let scope = &mut v8::HandleScope::new(isolate); + let s = "Lorem ipsum dolor sit amet. Qui inventore debitis et voluptas cupiditate qui recusandae molestias et ullam possimus"; + let one_byte = v8::String::new_from_one_byte( + scope, + s.as_bytes(), + v8::NewStringType::Normal, + ) + .unwrap(); + + // Does not fit + let mut buffer = [MaybeUninit::uninit(); 10]; + let cow = one_byte.to_rust_cow_lossy(scope, &mut buffer); + assert!(matches!(cow, Cow::Owned(_))); + assert_eq!(s, cow); + + // Fits + let mut buffer = [MaybeUninit::uninit(); 1000]; + let cow = one_byte.to_rust_cow_lossy(scope, &mut buffer); + assert!(matches!(cow, Cow::Borrowed(_))); + assert_eq!(s, cow); + + let s = "🦕 Lorem ipsum dolor sit amet. Qui inventore debitis et voluptas cupiditate qui recusandae molestias et ullam possimus"; + let two_bytes = + v8::String::new_from_utf8(scope, s.as_bytes(), v8::NewStringType::Normal) + .unwrap(); + + // Does not fit + let mut buffer = [MaybeUninit::uninit(); 10]; + let cow = two_bytes.to_rust_cow_lossy(scope, &mut buffer); + assert!(matches!(cow, Cow::Owned(_))); + assert_eq!(s, cow); + + // Fits + let mut buffer = [MaybeUninit::uninit(); 1000]; + let cow = two_bytes.to_rust_cow_lossy(scope, &mut buffer); + assert!(matches!(cow, Cow::Borrowed(_))); + assert_eq!(s, cow); + } } #[test] From 3f785f0429a36dfb5f45066f041792af9cfe74ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 29 Jun 2023 18:03:17 +0200 Subject: [PATCH 11/70] v0.74.0 (#1258) --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 26f98c6d7a..c9f4614d35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1183,7 +1183,7 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "v8" -version = "0.73.0" +version = "0.74.0" dependencies = [ "align-data", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index 674e77e030..35927239e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.73.0" +version = "0.74.0" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From c4033caf233459499c9707aea0c11dca84911fe2 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Fri, 30 Jun 2023 14:38:20 +0200 Subject: [PATCH 12/70] Rolling to V8 11.6.189.7 (#1260) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 078b22b2a7..5c529e81d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.6.189.6 +V8 Version: 11.6.189.7 [![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) diff --git a/v8 b/v8 index ef71f5a180..544e4ba971 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit ef71f5a1808784aeb7b86d7aa13a7daa4e57f341 +Subproject commit 544e4ba97144b1d641d800a6d5b988a0dcfaf28f From d706291c5db10884ce7a309eee41e07637cd0cf3 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Fri, 30 Jun 2023 09:46:29 -0600 Subject: [PATCH 13/70] fix: Ensure that one-byte strings that are not ASCII go through write_utf8_uninit (#1261) --- src/string.rs | 39 +++++++++++++++++++++------------------ tests/test_api.rs | 15 +++++++++++++++ 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/string.rs b/src/string.rs index 8c6efbf050..772062eb7c 100644 --- a/src/string.rs +++ b/src/string.rs @@ -422,13 +422,16 @@ impl String { /// Creates a copy of a [`crate::String`] in a [`std::string::String`]. /// Convenience function not present in the original V8 API. - #[inline(always)] pub fn to_rust_string_lossy( &self, scope: &mut Isolate, ) -> std::string::String { - if self.is_onebyte() { - let len_utf16 = self.length(); + let len_utf8 = self.utf8_length(scope); + let len_utf16 = self.length(); + + // If len_utf8 == len_utf16 and the string is one-byte, we can take the fast memcpy path. This is true iff the + // string is 100% 7-bit ASCII. + if self.is_onebyte() && len_utf8 == len_utf16 { unsafe { // Create an uninitialized buffer of `capacity` bytes. We need to be careful here to avoid // accidentally creating a slice of u8 which would be invalid. @@ -452,15 +455,14 @@ impl String { } } - let capacity = self.utf8_length(scope); // SAFETY: This allocates a buffer manually using the default allocator using the string's capacity. // We have a large number of invariants to uphold, so please check changes to this code carefully unsafe { // Create an uninitialized buffer of `capacity` bytes. We need to be careful here to avoid // accidentally creating a slice of u8 which would be invalid. - let layout = std::alloc::Layout::from_size_align(capacity, 1).unwrap(); + let layout = std::alloc::Layout::from_size_align(len_utf8, 1).unwrap(); let data = std::alloc::alloc(layout) as *mut MaybeUninit; - let buffer = std::ptr::slice_from_raw_parts_mut(data, capacity); + let buffer = std::ptr::slice_from_raw_parts_mut(data, len_utf8); // Write to this MaybeUninit buffer, assuming we're going to fill this entire buffer let length = self.write_utf8_uninit( @@ -469,26 +471,28 @@ impl String { None, WriteOptions::NO_NULL_TERMINATION | WriteOptions::REPLACE_INVALID_UTF8, ); - debug_assert!(length == capacity); + debug_assert!(length == len_utf8); // Return an owned string from this guaranteed now-initialized data let buffer = data as *mut u8; - std::string::String::from_raw_parts(buffer, length, capacity) + std::string::String::from_raw_parts(buffer, length, len_utf8) } } /// Converts a [`crate::String`] to either an owned [`std::string::String`], or a borrowed [`str`], depending on whether it fits into the /// provided buffer. - #[inline(always)] pub fn to_rust_cow_lossy<'a, const N: usize>( &self, scope: &mut Isolate, buffer: &'a mut [MaybeUninit; N], ) -> Cow<'a, str> { // TODO(mmastrac): Ideally we should be able to access the string's internal representation - + let len_utf8 = self.utf8_length(scope); let len_utf16 = self.length(); - if self.is_onebyte() { + + // If len_utf8 == len_utf16 and the string is one-byte, we can take the fast memcpy path. This is true iff the + // string is 100% 7-bit ASCII. + if self.is_onebyte() && len_utf8 == len_utf16 { if len_utf16 <= N { let length = self.write_one_byte_uninit( scope, @@ -532,8 +536,7 @@ impl String { } } - let capacity = self.utf8_length(scope); - if capacity <= N { + if len_utf8 <= N { // No malloc path let length = self.write_utf8_uninit( scope, @@ -541,7 +544,7 @@ impl String { None, WriteOptions::NO_NULL_TERMINATION | WriteOptions::REPLACE_INVALID_UTF8, ); - debug_assert!(length == capacity); + debug_assert!(length == len_utf8); // SAFETY: We know that we wrote `length` UTF-8 bytes. See `slice_assume_init_mut` for additional guarantee information. unsafe { @@ -559,9 +562,9 @@ impl String { unsafe { // Create an uninitialized buffer of `capacity` bytes. We need to be careful here to avoid // accidentally creating a slice of u8 which would be invalid. - let layout = std::alloc::Layout::from_size_align(capacity, 1).unwrap(); + let layout = std::alloc::Layout::from_size_align(len_utf8, 1).unwrap(); let data = std::alloc::alloc(layout) as *mut MaybeUninit; - let buffer = std::ptr::slice_from_raw_parts_mut(data, capacity); + let buffer = std::ptr::slice_from_raw_parts_mut(data, len_utf8); // Write to this MaybeUninit buffer, assuming we're going to fill this entire buffer let length = self.write_utf8_uninit( @@ -570,12 +573,12 @@ impl String { None, WriteOptions::NO_NULL_TERMINATION | WriteOptions::REPLACE_INVALID_UTF8, ); - debug_assert!(length == capacity); + debug_assert!(length == len_utf8); // Return an owned string from this guaranteed now-initialized data let buffer = data as *mut u8; Cow::Owned(std::string::String::from_raw_parts( - buffer, length, capacity, + buffer, length, len_utf8, )) } } diff --git a/tests/test_api.rs b/tests/test_api.rs index d6ed851149..d654b7fb28 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -241,6 +241,21 @@ fn global_handle_drop() { fn test_string() { let _setup_guard = setup::parallel_test(); let isolate = &mut v8::Isolate::new(Default::default()); + { + // Ensure that a Latin-1 string correctly round-trips + let scope = &mut v8::HandleScope::new(isolate); + let reference = "\u{00a0}"; + assert_eq!(2, reference.len()); + let local = v8::String::new(scope, reference).unwrap(); + assert_eq!(1, local.length()); + assert_eq!(2, local.utf8_length(scope)); + // Should round-trip to UTF-8 + assert_eq!(2, local.to_rust_string_lossy(scope).len()); + let mut buf = [MaybeUninit::uninit(); 0]; + assert_eq!(2, local.to_rust_cow_lossy(scope, &mut buf).len()); + let mut buf = [MaybeUninit::uninit(); 10]; + assert_eq!(2, local.to_rust_cow_lossy(scope, &mut buf).len()); + } { let scope = &mut v8::HandleScope::new(isolate); let reference = "Hello 🦕 world!"; From 1990a6dff56891fdeb1d6440fd6938a03b42fa53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sat, 1 Jul 2023 18:43:52 +0200 Subject: [PATCH 14/70] v0.74.1 (#1262) --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9f4614d35..b0664276f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1183,7 +1183,7 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "v8" -version = "0.74.0" +version = "0.74.1" dependencies = [ "align-data", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index 35927239e0..13af90fec8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.74.0" +version = "0.74.1" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From ca83ce53bad172cd1b5f1fcfbe18cb936cbb3b7f Mon Sep 17 00:00:00 2001 From: cions Date: Sun, 2 Jul 2023 02:21:12 +0900 Subject: [PATCH 15/70] Fix build for android (#1246) --- build.rs | 73 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/build.rs b/build.rs index 94e89504d6..ce173e2475 100644 --- a/build.rs +++ b/build.rs @@ -23,6 +23,7 @@ fn main() { let envs = vec![ "CCACHE", "CLANG_BASE_PATH", + "CXXSTDLIB", "DENO_TRYBUILD", "DOCS_RS", "GN", @@ -261,25 +262,23 @@ fn maybe_install_sysroot(arch: &str) { } fn platform() -> String { - #[cfg(target_os = "linux")] - let os = "linux"; - #[cfg(target_os = "macos")] - let os = "mac"; - #[cfg(target_os = "windows")] - let os = "windows"; - #[cfg(not(any( - target_os = "linux", - target_os = "macos", - target_os = "windows" - )))] - let arch = "unknown"; - - #[cfg(target_arch = "x86_64")] - let arch = "amd64"; - #[cfg(target_arch = "aarch64")] - let arch = "arm64"; - #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] - let arch = "unknown"; + let os = if cfg!(target_os = "linux") { + "linux" + } else if cfg!(target_os = "macos") { + "mac" + } else if cfg!(target_os = "windows") { + "windows" + } else { + "unknown" + }; + + let arch = if cfg!(target_arch = "x86_64") { + "amd64" + } else if cfg!(target_arch = "aarch64") { + "arm64" + } else { + "unknown" + }; format!("{os}-{arch}") } @@ -481,16 +480,24 @@ fn print_link_flags() { if should_dyn_link_libcxx { // Based on https://github.com/alexcrichton/cc-rs/blob/fba7feded71ee4f63cfe885673ead6d7b4f2f454/src/lib.rs#L2462 - let target = env::var("TARGET").unwrap(); - if target.contains("apple") - || target.contains("freebsd") - || target.contains("openbsd") - { - println!("cargo:rustc-link-lib=dylib=c++"); - } else if target.contains("linux") { - println!("cargo:rustc-link-lib=dylib=stdc++"); - } else if target.contains("android") { - println!("cargo:rustc-link-lib=dylib=c++_shared"); + if let Ok(stdlib) = env::var("CXXSTDLIB") { + if !stdlib.is_empty() { + println!("cargo:rustc-link-lib=dylib={}", stdlib); + } + } else { + let target = env::var("TARGET").unwrap(); + if target.contains("msvc") { + // nothing to link to + } else if target.contains("apple") + || target.contains("freebsd") + || target.contains("openbsd") + { + println!("cargo:rustc-link-lib=dylib=c++"); + } else if target.contains("android") { + println!("cargo:rustc-link-lib=dylib=c++_shared"); + } else { + println!("cargo:rustc-link-lib=dylib=stdc++"); + } } } @@ -544,10 +551,6 @@ fn is_compatible_clang_version(clang_path: &Path) -> bool { } fn find_compatible_system_clang() -> Option { - if cfg!(target_os = "android") { - return None; - } - if let Ok(p) = env::var("CLANG_BASE_PATH") { let base_path = Path::new(&p); let clang_path = base_path.join("bin").join("clang"); @@ -686,6 +689,10 @@ fn ninja(gn_out_dir: &Path, maybe_env: Option) -> Command { let mut cmd = Command::new(cmd_string); cmd.arg("-C"); cmd.arg(gn_out_dir); + if let Ok(jobs) = env::var("NUM_JOBS") { + cmd.arg("-j"); + cmd.arg(jobs); + } if let Some(env) = maybe_env { for item in env { cmd.env(item.0, item.1); From e2c6541ea3845d1f6d47e60bd99c368d672e25ed Mon Sep 17 00:00:00 2001 From: Graham Abbott Date: Sat, 8 Jul 2023 07:45:50 -0700 Subject: [PATCH 16/70] silence warning for unused 'must use' (#1269) this warning only occurs when using the library as a dependency. warning: unused return value of `Box::::from_raw` that must be used --> /rusty_v8/src/scope.rs:1092:16 | 1092 | unsafe { Box::from_raw(root) }; | ^^^^^^^^^^^^^^^^^^^ | = note: call `drop(Box::from_raw(ptr))` if you intend to drop the `Box` = note: `#[warn(unused_must_use)]` on by default --- src/scope.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/scope.rs b/src/scope.rs index 04542db47f..8ccfadc68d 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -1089,7 +1089,9 @@ pub(crate) mod data { /// This function should be called only when an Isolate is being disposed. pub(crate) fn drop_root(isolate: &mut Isolate) { let root = Self::get_root_mut(isolate); - unsafe { Box::from_raw(root) }; + unsafe { + let _ = Box::from_raw(root); + }; isolate.set_current_scope_data(None); } From 73dcb46674dc0da1c3f42ee3aa11763fe9636851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sun, 9 Jul 2023 22:40:15 +0200 Subject: [PATCH 17/70] Add v8::NamedPropertyHandlerConfiguration::*_raw methods (#1273) --- src/template.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++ tests/test_api.rs | 29 ++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/src/template.rs b/src/template.rs index 2bffb9958a..98efbbe292 100644 --- a/src/template.rs +++ b/src/template.rs @@ -336,6 +336,14 @@ impl<'s> NamedPropertyHandlerConfiguration<'s> { self } + pub fn getter_raw( + mut self, + getter: GenericNamedPropertyGetterCallback<'s>, + ) -> Self { + self.getter = Some(getter); + self + } + pub fn setter( mut self, setter: impl MapFnTo>, @@ -344,6 +352,14 @@ impl<'s> NamedPropertyHandlerConfiguration<'s> { self } + pub fn setter_raw( + mut self, + setter: GenericNamedPropertySetterCallback<'s>, + ) -> Self { + self.setter = Some(setter); + self + } + pub fn query( mut self, query: impl MapFnTo>, @@ -352,6 +368,14 @@ impl<'s> NamedPropertyHandlerConfiguration<'s> { self } + pub fn query_raw( + mut self, + query: GenericNamedPropertyQueryCallback<'s>, + ) -> Self { + self.query = Some(query); + self + } + pub fn deleter( mut self, deleter: impl MapFnTo>, @@ -360,6 +384,14 @@ impl<'s> NamedPropertyHandlerConfiguration<'s> { self } + pub fn deleter_raw( + mut self, + deleter: GenericNamedPropertyDeleterCallback<'s>, + ) -> Self { + self.deleter = Some(deleter); + self + } + pub fn enumerator( mut self, enumerator: impl MapFnTo>, @@ -368,6 +400,14 @@ impl<'s> NamedPropertyHandlerConfiguration<'s> { self } + pub fn enumerator_raw( + mut self, + enumerator: GenericNamedPropertyEnumeratorCallback<'s>, + ) -> Self { + self.enumerator = Some(enumerator); + self + } + pub fn definer( mut self, definer: impl MapFnTo>, @@ -376,6 +416,14 @@ impl<'s> NamedPropertyHandlerConfiguration<'s> { self } + pub fn definer_raw( + mut self, + definer: GenericNamedPropertyDefinerCallback<'s>, + ) -> Self { + self.definer = Some(definer); + self + } + pub fn descriptor( mut self, descriptor: impl MapFnTo>, @@ -384,6 +432,14 @@ impl<'s> NamedPropertyHandlerConfiguration<'s> { self } + pub fn descriptor_raw( + mut self, + descriptor: GenericNamedPropertyDescriptorCallback<'s>, + ) -> Self { + self.descriptor = Some(descriptor); + self + } + /// Set the associated data. The default is no associated data. pub fn data(mut self, data: Local<'s, Value>) -> Self { self.data = Some(data); diff --git a/tests/test_api.rs b/tests/test_api.rs index d654b7fb28..7281efc184 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -2437,6 +2437,35 @@ fn object_template_set_named_property_handler() { .unwrap() .boolean_value(scope)); assert!(eval(scope, "obj.panicOnGet").unwrap().is_string()); + + // Test `v8::NamedPropertyHandlerConfiguration::*_raw()` methods + { + let templ = v8::ObjectTemplate::new(scope); + templ.set_internal_field_count(1); + templ.set_named_property_handler( + v8::NamedPropertyHandlerConfiguration::new() + .getter_raw(getter.map_fn_to()) + .setter_raw(setter.map_fn_to()) + .query_raw(query.map_fn_to()) + .flags(v8::PropertyHandlerFlags::NON_MASKING), + ); + + let obj = templ.new_instance(scope).unwrap(); + obj.set_internal_field(0, int.into()); + scope.get_current_context().global(scope).set( + scope, + name.into(), + obj.into(), + ); + assert!(!eval(scope, "'panicOnGet' in obj") + .unwrap() + .boolean_value(scope)); + eval(scope, "obj.panicOnGet = 'x'").unwrap(); + assert!(eval(scope, "'panicOnGet' in obj") + .unwrap() + .boolean_value(scope)); + assert!(eval(scope, "obj.panicOnGet").unwrap().is_string()); + } } } From 70239dc4ceda0f76ea13bb2570d0d40e37e7c12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sun, 9 Jul 2023 23:02:29 +0200 Subject: [PATCH 18/70] v0.74.2 (#1274) --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0664276f6..895e336a06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1183,7 +1183,7 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "v8" -version = "0.74.1" +version = "0.74.2" dependencies = [ "align-data", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index 13af90fec8..8ed2dd29dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.74.1" +version = "0.74.2" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From c6fe9e70d0c5b31402bf1a6188c0f908fcffe8f0 Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Mon, 10 Jul 2023 19:30:11 +0200 Subject: [PATCH 19/70] feat: v8::Object::PreviewEntries (#1276) --- src/binding.cc | 20 +++++++----- src/object.rs | 27 ++++++++++++++++ tests/test_api.rs | 79 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 7 deletions(-) diff --git a/src/binding.cc b/src/binding.cc index 1de8e8536f..4725239355 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -463,8 +463,8 @@ uint32_t v8__ScriptCompiler__CachedDataVersionTag() { return v8::ScriptCompiler::CachedDataVersionTag(); } -size_t v8__TypedArray__Length(const v8::TypedArray* self) { - return ptr_to_local(self)->Length(); +size_t v8__TypedArray__Length(const v8::TypedArray* self) { + return ptr_to_local(self)->Length(); } size_t v8__TypedArray__kMaxLength() { return v8::TypedArray::kMaxLength; } @@ -1134,7 +1134,7 @@ void v8__ObjectTemplate__SetAccessor( const v8::ObjectTemplate& self, const v8::Name& key, v8::AccessorNameGetterCallback getter, v8::AccessorNameSetterCallback setter, - const v8::Value* data_or_null, + const v8::Value* data_or_null, v8::PropertyAttribute attr) { ptr_to_local(&self)->SetAccessor( ptr_to_local(&key), getter, setter, ptr_to_local(data_or_null), v8::AccessControl::DEFAULT, @@ -1279,9 +1279,9 @@ MaybeBool v8__Object__DefineProperty(const v8::Object& self, MaybeBool v8__Object__SetAccessor(const v8::Object& self, const v8::Context& context, const v8::Name& key, - v8::AccessorNameGetterCallback getter, + v8::AccessorNameGetterCallback getter, v8::AccessorNameSetterCallback setter, - const v8::Value* data_or_null, + const v8::Value* data_or_null, v8::PropertyAttribute attr) { return maybe_to_maybe_bool(ptr_to_local(&self)->SetAccessor( ptr_to_local(&context), ptr_to_local(&key), getter, setter, @@ -1444,6 +1444,12 @@ const v8::Value* v8__Object__GetOwnPropertyDescriptor( ptr_to_local(&context), ptr_to_local(&key))); } +const v8::Array* v8__Object__PreviewEntries( + const v8::Object& self, + bool* is_key_value) { + return maybe_local_to_ptr(ptr_to_local(&self)->PreviewEntries(is_key_value)); +} + const v8::Array* v8__Array__New(v8::Isolate* isolate, int length) { return local_to_ptr(v8::Array::New(isolate, length)); @@ -1778,7 +1784,7 @@ void v8__Context__SetPromiseHooks(v8::Context& self, const v8::Value* v8__Context__GetSecurityToken(const v8::Context& self) { auto value = ptr_to_local(&self)->GetSecurityToken(); - return local_to_ptr(value); + return local_to_ptr(value); } void v8__Context__SetSecurityToken(v8::Context& self, @@ -1792,7 +1798,7 @@ void v8__Context__UseDefaultSecurityToken(v8::Context& self) { } void v8__Context__AllowCodeGenerationFromStrings(v8::Context& self, bool allow) { - ptr_to_local(&self)->AllowCodeGenerationFromStrings(allow); + ptr_to_local(&self)->AllowCodeGenerationFromStrings(allow); } bool v8__Context_IsCodeGenerationFromStringsAllowed(v8::Context& self) { diff --git a/src/object.rs b/src/object.rs index 530e6fc19c..10c55275af 100644 --- a/src/object.rs +++ b/src/object.rs @@ -26,6 +26,7 @@ use crate::String; use crate::Value; use std::convert::TryFrom; use std::ffi::c_void; +use std::mem::MaybeUninit; use std::num::NonZeroI32; use std::ptr::null; @@ -192,6 +193,10 @@ extern "C" { context: *const Context, key: *const Name, ) -> *const Value; + fn v8__Object__PreviewEntries( + this: *const Object, + is_key_value: *mut bool, + ) -> *const Array; fn v8__Array__New(isolate: *mut Isolate, length: int) -> *const Array; fn v8__Array__New_with_elements( @@ -807,6 +812,28 @@ impl Object { }) } } + + /// If this object is a Set, Map, WeakSet or WeakMap, this returns a + /// representation of the elements of this object as an array. + /// If this object is a SetIterator or MapIterator, this returns all elements + /// of the underlying collection, starting at the iterator's current position. + /// + /// Also returns a boolean, indicating whether the returned array contains + /// key & values (for example when the value is Set.entries()). + pub fn preview_entries<'s>( + &self, + scope: &mut HandleScope<'s>, + ) -> (Option>, bool) { + let mut is_key_value = MaybeUninit::uninit(); + unsafe { + let val = scope.cast_local(|_| { + v8__Object__PreviewEntries(self, is_key_value.as_mut_ptr()) + }); + let is_key_value = is_key_value.assume_init(); + + (val, is_key_value) + } + } } /// Object integrity levels can be used to restrict what can be done to an diff --git a/tests/test_api.rs b/tests/test_api.rs index 7281efc184..fd9886ea67 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -6741,6 +6741,85 @@ fn get_own_property_descriptor() { assert!(desc.is_undefined()); } +#[test] +fn preview_entries() { + 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); + let scope = &mut v8::ContextScope::new(scope, context); + + { + let obj = eval( + scope, + "var set = new Set([1,2,3]); set.delete(1); set.keys()", + ) + .unwrap(); + let obj = obj.to_object(scope).unwrap(); + let (preview, is_key_value) = obj.preview_entries(scope); + let preview = preview.unwrap(); + assert!(!is_key_value); + assert_eq!(preview.length(), 2); + assert_eq!( + preview + .get_index(scope, 0) + .unwrap() + .number_value(scope) + .unwrap(), + 2.0 + ); + assert_eq!( + preview + .get_index(scope, 1) + .unwrap() + .number_value(scope) + .unwrap(), + 3.0 + ); + } + + { + let obj = eval( + scope, + "var set = new Set([1,2,3]); set.delete(2); set.entries()", + ) + .unwrap(); + let obj = obj.to_object(scope).unwrap(); + let (preview, is_key_value) = obj.preview_entries(scope); + let preview = preview.unwrap(); + assert!(is_key_value); + assert_eq!(preview.length(), 4); + let first = preview + .get_index(scope, 0) + .unwrap() + .number_value(scope) + .unwrap(); + let second = preview + .get_index(scope, 2) + .unwrap() + .number_value(scope) + .unwrap(); + assert_eq!(first, 1.0); + assert_eq!(second, 3.0); + assert_eq!( + first, + preview + .get_index(scope, 1) + .unwrap() + .number_value(scope) + .unwrap(), + ); + assert_eq!( + second, + preview + .get_index(scope, 3) + .unwrap() + .number_value(scope) + .unwrap(), + ); + } +} + #[test] fn test_prototype_api() { let _setup_guard = setup::parallel_test(); From ed0aa000ef9abeacd9875860d37764f056602e0c Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Tue, 11 Jul 2023 06:50:04 -0600 Subject: [PATCH 20/70] Rolling to V8 11.6.189.9 (#1264) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5c529e81d9..22d389ed7d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.6.189.7 +V8 Version: 11.6.189.9 [![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) diff --git a/v8 b/v8 index 544e4ba971..845a647579 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 544e4ba97144b1d641d800a6d5b988a0dcfaf28f +Subproject commit 845a64757951cfba51918d79977773d82132f783 From 9d5c21ae7eccf8896e9b3d1f219fe035bf039838 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Tue, 11 Jul 2023 08:07:29 -0600 Subject: [PATCH 21/70] feat: Add Uint8 type for fastcall (#1279) --- src/fast_api.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/fast_api.rs b/src/fast_api.rs index 05db2a8ac6..ebfa389c69 100644 --- a/src/fast_api.rs +++ b/src/fast_api.rs @@ -112,6 +112,7 @@ pub enum CType { pub enum Type { Void, Bool, + Uint8, Int32, Uint32, Int64, @@ -132,6 +133,7 @@ impl From<&Type> for CType { match ty { Type::Void => CType::Void, Type::Bool => CType::Bool, + Type::Uint8 => CType::Uint8, Type::Int32 => CType::Int32, Type::Uint32 => CType::Uint32, Type::Int64 => CType::Int64, From 226c662da6033846669661ef6fa644ce84e1ef2b Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Tue, 11 Jul 2023 08:07:47 -0600 Subject: [PATCH 22/70] fix: Use unaligned read as copy_nonoverlapping requires alignment (#1278) --- src/fast_api.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/fast_api.rs b/src/fast_api.rs index ebfa389c69..8dfb28d580 100644 --- a/src/fast_api.rs +++ b/src/fast_api.rs @@ -234,14 +234,12 @@ impl FastApiOneByteString { } impl FastApiTypedArray { + /// Performs an unaligned-safe read of T from the underlying data. #[inline(always)] pub fn get(&self, index: usize) -> T { debug_assert!(index < self.length); - let mut t: T = Default::default(); - unsafe { - ptr::copy_nonoverlapping(self.data.add(index), &mut t, 1); - } - t + // SAFETY: src is valid for reads, and is a valid value for T + unsafe { ptr::read_unaligned(self.data.add(index)) } } #[inline(always)] From 4110d1bf4ea93691ead4e72ad846c9a809c8ba7e Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Tue, 11 Jul 2023 10:09:29 -0600 Subject: [PATCH 23/70] chore: Add Debug for ExternalReference (#1272) --- src/external_references.rs | 8 ++++++++ tests/test_api.rs | 7 +++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/external_references.rs b/src/external_references.rs index 6e8441f59e..3a9eb1069b 100644 --- a/src/external_references.rs +++ b/src/external_references.rs @@ -11,6 +11,7 @@ use crate::NamedGetterCallback; use crate::NamedSetterCallback; use crate::PropertyEnumeratorCallback; use std::ffi::c_void; +use std::fmt::Debug; #[derive(Clone, Copy)] pub union ExternalReference<'s> { @@ -26,6 +27,13 @@ pub union ExternalReference<'s> { pub pointer: *mut c_void, } +impl<'s> Debug for ExternalReference<'s> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // SAFETY: All union fields are the same size + unsafe { (self.pointer).fmt(f) } + } +} + #[derive(Debug, Clone)] pub struct ExternalReferences { null_terminated: Vec, diff --git a/tests/test_api.rs b/tests/test_api.rs index fd9886ea67..47cadd07c0 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -5309,7 +5309,7 @@ fn external_references() { let external_ptr = Box::into_raw(vec![0_u8, 1, 2, 3, 4].into_boxed_slice()) as *mut [u8] as *mut c_void; // Push them to the external reference table. - let refs = v8::ExternalReferences::new(&[ + let refs = [ v8::ExternalReference { function: fn_callback.map_fn_to(), }, @@ -5319,7 +5319,10 @@ fn external_references() { v8::ExternalReference { pointer: external_ptr, }, - ]); + ]; + // Exercise the Debug impl + println!("{refs:?}"); + let refs = v8::ExternalReferences::new(&refs); // TODO(piscisaureus): leaking the `ExternalReferences` collection shouldn't // be necessary. The reference needs to remain valid for the lifetime of the // `SnapshotCreator` or `Isolate` that uses it, which would be the case here From 4dd8b60bf07a559d7cb4f11720524bf1415b801e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Tue, 11 Jul 2023 20:50:03 +0200 Subject: [PATCH 24/70] chore: update to Rust 1.70.0 (#1277) --- examples/process.rs | 4 +-- rust-toolchain.toml | 2 +- src/object.rs | 34 ++++++++----------- src/primitive_array.rs | 4 +-- src/string.rs | 9 ++--- src/value.rs | 18 +++++----- tests/compile_fail/boxed_local.stderr | 3 +- .../handle_scope_escape_lifetime.stderr | 3 +- .../handle_scope_lifetime_4.stderr | 3 +- .../object_without_context_scope.stderr | 2 +- .../try_catch_exception_lifetime.stderr | 3 +- .../try_catch_message_lifetime.stderr | 3 +- tests/test_api.rs | 8 ++--- 13 files changed, 46 insertions(+), 50 deletions(-) diff --git a/examples/process.rs b/examples/process.rs index 79f833518e..d186fc2e03 100644 --- a/examples/process.rs +++ b/examples/process.rs @@ -320,9 +320,9 @@ where } /// Utility function that extracts the http request object from a wrapper object. - fn unwrap_request<'a>( + fn unwrap_request( scope: &mut v8::HandleScope, - request: v8::Local<'a, v8::Object>, + request: v8::Local, ) -> *mut Box { let external = request.get_internal_field(scope, 0).unwrap(); let external = unsafe { v8::Local::::cast(external) }; diff --git a/rust-toolchain.toml b/rust-toolchain.toml index d1df584a7d..f15cd1c929 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.66.0" +channel = "1.70.0" components = ["rustfmt", "clippy"] diff --git a/src/object.rs b/src/object.rs index 10c55275af..122280041d 100644 --- a/src/object.rs +++ b/src/object.rs @@ -567,9 +567,9 @@ impl Object { // Note: This function converts the key to a name, which possibly calls back // into JavaScript. #[inline(always)] - pub fn has<'s>( + pub fn has( &self, - scope: &mut HandleScope<'s>, + scope: &mut HandleScope, key: Local, ) -> Option { unsafe { v8__Object__Has(self, &*scope.get_current_context(), &*key) } @@ -577,20 +577,16 @@ impl Object { } #[inline(always)] - pub fn has_index<'s>( - &self, - scope: &mut HandleScope<'s>, - index: u32, - ) -> Option { + pub fn has_index(&self, scope: &mut HandleScope, index: u32) -> Option { unsafe { v8__Object__HasIndex(self, &*scope.get_current_context(), index) } .into() } /// HasOwnProperty() is like JavaScript's Object.prototype.hasOwnProperty(). #[inline(always)] - pub fn has_own_property<'s>( + pub fn has_own_property( &self, - scope: &mut HandleScope<'s>, + scope: &mut HandleScope, key: Local, ) -> Option { unsafe { @@ -600,18 +596,18 @@ impl Object { } #[inline(always)] - pub fn delete<'s>( + pub fn delete( &self, - scope: &mut HandleScope<'s>, + scope: &mut HandleScope, key: Local, ) -> Option { unsafe { v8__Object__Delete(self, &*scope.get_current_context(), &*key) } .into() } - pub fn delete_index<'s>( + pub fn delete_index( &self, - scope: &mut HandleScope<'s>, + scope: &mut HandleScope, index: u32, ) -> Option { unsafe { @@ -724,9 +720,9 @@ impl Object { /// Note: Private properties are not inherited. Do not rely on this, since it /// may change. #[inline(always)] - pub fn set_private<'s>( + pub fn set_private( &self, - scope: &mut HandleScope<'s>, + scope: &mut HandleScope, key: Local, value: Local, ) -> Option { @@ -746,9 +742,9 @@ impl Object { /// Note: Private properties are not inherited. Do not rely on this, since it /// may change. #[inline(always)] - pub fn delete_private<'s>( + pub fn delete_private( &self, - scope: &mut HandleScope<'s>, + scope: &mut HandleScope, key: Local, ) -> Option { unsafe { @@ -762,9 +758,9 @@ impl Object { /// Note: Private properties are not inherited. Do not rely on this, since it /// may change. #[inline(always)] - pub fn has_private<'s>( + pub fn has_private( &self, - scope: &mut HandleScope<'s>, + scope: &mut HandleScope, key: Local, ) -> Option { unsafe { diff --git a/src/primitive_array.rs b/src/primitive_array.rs index dddcbd97fb..584e1e08d3 100644 --- a/src/primitive_array.rs +++ b/src/primitive_array.rs @@ -48,9 +48,9 @@ impl PrimitiveArray { } #[inline(always)] - pub fn set<'s>( + pub fn set( &self, - scope: &mut HandleScope<'s>, + scope: &mut HandleScope, index: usize, item: Local<'_, Primitive>, ) { diff --git a/src/string.rs b/src/string.rs index 772062eb7c..2e0f8a51f8 100644 --- a/src/string.rs +++ b/src/string.rs @@ -91,18 +91,13 @@ extern "C" { } #[repr(C)] -#[derive(Debug)] +#[derive(Debug, Default)] pub enum NewStringType { + #[default] Normal, Internalized, } -impl Default for NewStringType { - fn default() -> Self { - NewStringType::Normal - } -} - bitflags! { #[derive(Default)] #[repr(transparent)] diff --git a/src/value.rs b/src/value.rs index 8845042208..1ad867e759 100644 --- a/src/value.rs +++ b/src/value.rs @@ -568,9 +568,9 @@ impl Value { /// Convenience function not present in the original V8 API. #[inline(always)] - pub fn to_rust_string_lossy<'s>( + pub fn to_rust_string_lossy( &self, - scope: &mut HandleScope<'s>, + scope: &mut HandleScope, ) -> std::string::String { self .to_string(scope) @@ -646,9 +646,9 @@ impl Value { } #[inline(always)] - pub fn instance_of<'s>( + pub fn instance_of( &self, - scope: &mut HandleScope<'s>, + scope: &mut HandleScope, object: Local, ) -> Option { let mut out = Maybe::::default(); @@ -664,7 +664,7 @@ impl Value { } #[inline(always)] - pub fn number_value<'s>(&self, scope: &mut HandleScope<'s>) -> Option { + pub fn number_value(&self, scope: &mut HandleScope) -> Option { let mut out = Maybe::::default(); unsafe { v8__Value__NumberValue(self, &*scope.get_current_context(), &mut out) @@ -673,7 +673,7 @@ impl Value { } #[inline(always)] - pub fn integer_value<'s>(&self, scope: &mut HandleScope<'s>) -> Option { + pub fn integer_value(&self, scope: &mut HandleScope) -> Option { let mut out = Maybe::::default(); unsafe { v8__Value__IntegerValue(self, &*scope.get_current_context(), &mut out) @@ -682,7 +682,7 @@ impl Value { } #[inline(always)] - pub fn uint32_value<'s>(&self, scope: &mut HandleScope<'s>) -> Option { + pub fn uint32_value(&self, scope: &mut HandleScope) -> Option { let mut out = Maybe::::default(); unsafe { v8__Value__Uint32Value(self, &*scope.get_current_context(), &mut out) @@ -691,7 +691,7 @@ impl Value { } #[inline(always)] - pub fn int32_value<'s>(&self, scope: &mut HandleScope<'s>) -> Option { + pub fn int32_value(&self, scope: &mut HandleScope) -> Option { let mut out = Maybe::::default(); unsafe { v8__Value__Int32Value(self, &*scope.get_current_context(), &mut out) @@ -700,7 +700,7 @@ impl Value { } #[inline(always)] - pub fn boolean_value<'s>(&self, scope: &mut HandleScope<'s, ()>) -> bool { + pub fn boolean_value(&self, scope: &mut HandleScope<'_, ()>) -> bool { unsafe { v8__Value__BooleanValue(self, scope.get_isolate_ptr()) } } diff --git a/tests/compile_fail/boxed_local.stderr b/tests/compile_fail/boxed_local.stderr index 85ee179c93..6eeef3de9f 100644 --- a/tests/compile_fail/boxed_local.stderr +++ b/tests/compile_fail/boxed_local.stderr @@ -1,9 +1,10 @@ error[E0597]: `scope2` does not live long enough - --> $DIR/boxed_local.rs:9:43 + --> tests/compile_fail/boxed_local.rs:9:43 | 7 | let _boxed_local = { | ------------ borrow later stored here 8 | let mut scope2 = v8::HandleScope::new(&mut scope1); + | ---------- binding `scope2` declared here 9 | let mut scope3 = v8::HandleScope::new(&mut scope2); | ^^^^^^^^^^^ borrowed value does not live long enough 10 | Box::new(v8::Integer::new(&mut scope3, 123)) diff --git a/tests/compile_fail/handle_scope_escape_lifetime.stderr b/tests/compile_fail/handle_scope_escape_lifetime.stderr index 5f4a7820e7..fccbc2076a 100644 --- a/tests/compile_fail/handle_scope_escape_lifetime.stderr +++ b/tests/compile_fail/handle_scope_escape_lifetime.stderr @@ -1,9 +1,10 @@ error[E0597]: `scope2` does not live long enough - --> $DIR/handle_scope_escape_lifetime.rs:9:43 + --> tests/compile_fail/handle_scope_escape_lifetime.rs:9:43 | 7 | let _local = { | ------ borrow later stored here 8 | let mut scope2 = v8::HandleScope::new(&mut scope1); + | ---------- binding `scope2` declared here 9 | let mut scope3 = v8::HandleScope::new(&mut scope2); | ^^^^^^^^^^^ borrowed value does not live long enough ... diff --git a/tests/compile_fail/handle_scope_lifetime_4.stderr b/tests/compile_fail/handle_scope_lifetime_4.stderr index 54b4112712..6728153a27 100644 --- a/tests/compile_fail/handle_scope_lifetime_4.stderr +++ b/tests/compile_fail/handle_scope_lifetime_4.stderr @@ -1,9 +1,10 @@ error[E0597]: `scope2` does not live long enough - --> $DIR/handle_scope_lifetime_4.rs:9:35 + --> tests/compile_fail/handle_scope_lifetime_4.rs:9:35 | 7 | let mut _scope3 = { | ----------- borrow later stored here 8 | let mut scope2 = v8::HandleScope::new(&mut scope1); + | ---------- binding `scope2` declared here 9 | v8::EscapableHandleScope::new(&mut scope2) | ^^^^^^^^^^^ borrowed value does not live long enough 10 | }; diff --git a/tests/compile_fail/object_without_context_scope.stderr b/tests/compile_fail/object_without_context_scope.stderr index 4e0b2bda23..beab06d57b 100644 --- a/tests/compile_fail/object_without_context_scope.stderr +++ b/tests/compile_fail/object_without_context_scope.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> tests/compile_fail/object_without_context_scope.rs:6:33 | 6 | let _object = v8::Object::new(&mut scope); - | --------------- ^^^^^^^^^^ expected struct `v8::Context`, found `()` + | --------------- ^^^^^^^^^^ expected `&mut HandleScope<'_>`, found `&mut HandleScope<'_, ()>` | | | arguments to this function are incorrect | diff --git a/tests/compile_fail/try_catch_exception_lifetime.stderr b/tests/compile_fail/try_catch_exception_lifetime.stderr index 9caa32c292..6e81835a34 100644 --- a/tests/compile_fail/try_catch_exception_lifetime.stderr +++ b/tests/compile_fail/try_catch_exception_lifetime.stderr @@ -1,9 +1,10 @@ error[E0597]: `scope3` does not live long enough - --> $DIR/try_catch_exception_lifetime.rs:11:43 + --> tests/compile_fail/try_catch_exception_lifetime.rs:11:43 | 9 | let _exception = { | ---------- borrow later stored here 10 | let mut scope3 = v8::HandleScope::new(&mut scope2); + | ---------- binding `scope3` declared here 11 | let mut scope4 = v8::HandleScope::new(&mut scope3); | ^^^^^^^^^^^ borrowed value does not live long enough ... diff --git a/tests/compile_fail/try_catch_message_lifetime.stderr b/tests/compile_fail/try_catch_message_lifetime.stderr index 04499b004f..34964012d8 100644 --- a/tests/compile_fail/try_catch_message_lifetime.stderr +++ b/tests/compile_fail/try_catch_message_lifetime.stderr @@ -1,9 +1,10 @@ error[E0597]: `scope3` does not live long enough - --> $DIR/try_catch_message_lifetime.rs:11:43 + --> tests/compile_fail/try_catch_message_lifetime.rs:11:43 | 9 | let _message = { | -------- borrow later stored here 10 | let mut scope3 = v8::HandleScope::new(&mut scope2); + | ---------- binding `scope3` declared here 11 | let mut scope4 = v8::HandleScope::new(&mut scope3); | ^^^^^^^^^^^ borrowed value does not live long enough ... diff --git a/tests/test_api.rs b/tests/test_api.rs index 47cadd07c0..1327951d24 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -679,8 +679,8 @@ fn get_isolate_from_handle() { check_handle_helper(scope, expect_some, local2); } - fn check_eval<'s>( - scope: &mut v8::HandleScope<'s>, + fn check_eval( + scope: &mut v8::HandleScope, expect_some: Option, code: &str, ) { @@ -4482,8 +4482,8 @@ fn mock_script_origin<'s>( ) } -fn mock_source<'s>( - scope: &mut v8::HandleScope<'s>, +fn mock_source( + scope: &mut v8::HandleScope, resource_name: &str, source: &str, ) -> v8::script_compiler::Source { From 308a113445b1f8b144f7bac121932ffd9c2880e3 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Wed, 12 Jul 2023 16:22:12 +0300 Subject: [PATCH 25/70] feat: Implement Rust-side const ExternalOneByteStringResource subclass (#1275) MSVC and Itanium C++ ABIs agree that for simple inheritance the basic structure of a vtable contains metadata fields at a "negative offset" from the vtable pointer, and at zero or positive offsets come the virtual function pointers in the order of declaration. The only difference between the two is that MSVC only places the virtual deleting destructor in the vtable while Itanium ABI places both the deleting and the complete object destructors in it, leading to a vtable that is one pointer larger in Itanium / on Linux. Also MSVC only has a single metadata field instead of two for Itanium. Itanium inlines the base offset into the vtable while MSVC keeps it in what is essentially the entry point into the type info data. Since the two are so similar, creating a custom vtable on Rust-side is pretty easy and can be done entirely at compile-time, meaning that instances of the class can also be created entirely at compile time. This leads to fully const external strings being possible. --- src/binding.cc | 92 ++++++++++++++++++++------------- src/lib.rs | 1 + src/string.rs | 129 ++++++++++++++++++++++++++++++++++++++++++++++ tests/test_api.rs | 14 +++++ 4 files changed, 201 insertions(+), 35 deletions(-) diff --git a/src/binding.cc b/src/binding.cc index 4725239355..24f75b52a6 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -1,5 +1,6 @@ // Copyright 2019-2021 the Deno authors. All rights reserved. MIT license. #include +#include #include #include #include @@ -850,7 +851,8 @@ two_pointers_t v8__ArrayBuffer__GetBackingStore(const v8::ArrayBuffer& self) { return make_pod(ptr_to_local(&self)->GetBackingStore()); } -bool v8__BackingStore__IsResizableByUserJavaScript(const v8::BackingStore& self) { +bool v8__BackingStore__IsResizableByUserJavaScript( + const v8::BackingStore& self) { return ptr_to_local(&self)->IsResizableByUserJavaScript(); } @@ -1013,6 +1015,33 @@ class ExternalStaticOneByteStringResource const int _length; }; +// NOTE: This class is never used and only serves as a reference for +// the OneByteConst struct created on Rust-side. +class ExternalConstOneByteStringResource + : public v8::String::ExternalOneByteStringResource { + public: + ExternalConstOneByteStringResource(int length) + : _length(length) { + static_assert(offsetof(ExternalConstOneByteStringResource, _length) == 16, + "ExternalConstOneByteStringResource's length was not at offset 16"); + static_assert(sizeof(ExternalConstOneByteStringResource) == 24, + "ExternalConstOneByteStringResource size was not 24"); + static_assert(alignof(ExternalConstOneByteStringResource) == 8, + "ExternalConstOneByteStringResource align was not 8"); + } + const char* data() const override { return nullptr; } + size_t length() const override { return _length; } + void Dispose() override {} + + private: + const int _length; +}; + +const v8::String* v8__String__NewExternalOneByte( + v8::Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) { + return maybe_local_to_ptr(v8::String::NewExternalOneByte(isolate, resource)); +} + const v8::String* v8__String__NewExternalOneByteStatic(v8::Isolate* isolate, const char* data, int length) { @@ -1150,8 +1179,7 @@ void v8__ObjectTemplate__SetNamedPropertyHandler( v8::GenericNamedPropertyEnumeratorCallback enumerator, v8::GenericNamedPropertyDefinerCallback definer, v8::GenericNamedPropertyDescriptorCallback descriptor, - const v8::Value* data_or_null, - v8::PropertyHandlerFlags flags) { + const v8::Value* data_or_null, v8::PropertyHandlerFlags flags) { ptr_to_local(&self)->SetHandler(v8::NamedPropertyHandlerConfiguration( getter, setter, query, deleter, enumerator, definer, descriptor, ptr_to_local(data_or_null), flags)); @@ -1165,8 +1193,7 @@ void v8__ObjectTemplate__SetIndexedPropertyHandler( v8::IndexedPropertyEnumeratorCallback enumerator, v8::IndexedPropertyDefinerCallback definer, v8::IndexedPropertyDescriptorCallback descriptor, - const v8::Value* data_or_null, - v8::PropertyHandlerFlags flags) { + const v8::Value* data_or_null, v8::PropertyHandlerFlags flags) { ptr_to_local(&self)->SetHandler(v8::IndexedPropertyHandlerConfiguration( getter, setter, query, deleter, enumerator, definer, descriptor, ptr_to_local(data_or_null), flags)); @@ -1269,9 +1296,9 @@ MaybeBool v8__Object__DefineOwnProperty(const v8::Object& self, } MaybeBool v8__Object__DefineProperty(const v8::Object& self, - const v8::Context& context, - const v8::Name& key, - v8::PropertyDescriptor& desc) { + const v8::Context& context, + const v8::Name& key, + v8::PropertyDescriptor& desc) { return maybe_to_maybe_bool(ptr_to_local(&self)->DefineProperty( ptr_to_local(&context), ptr_to_local(&key), desc)); } @@ -1285,7 +1312,7 @@ MaybeBool v8__Object__SetAccessor(const v8::Object& self, v8::PropertyAttribute attr) { return maybe_to_maybe_bool(ptr_to_local(&self)->SetAccessor( ptr_to_local(&context), ptr_to_local(&key), getter, setter, - ptr_to_local(data_or_null), v8::AccessControl::DEFAULT,attr)); + ptr_to_local(data_or_null), v8::AccessControl::DEFAULT, attr)); } v8::Isolate* v8__Object__GetIsolate(const v8::Object& self) { @@ -1430,16 +1457,16 @@ MaybeBool v8__Object__HasPrivate(const v8::Object& self, ptr_to_local(&context), ptr_to_local(&key))); } -void v8__Object__GetPropertyAttributes( - const v8::Object& self, const v8::Context& context, - const v8::Value& key, v8::Maybe* out) { +void v8__Object__GetPropertyAttributes(const v8::Object& self, + const v8::Context& context, + const v8::Value& key, + v8::Maybe* out) { *out = ptr_to_local(&self)->GetPropertyAttributes(ptr_to_local(&context), ptr_to_local(&key)); } const v8::Value* v8__Object__GetOwnPropertyDescriptor( - const v8::Object& self, const v8::Context& context, - const v8::Name& key) { + const v8::Object& self, const v8::Context& context, const v8::Name& key) { return maybe_local_to_ptr(ptr_to_local(&self)->GetOwnPropertyDescriptor( ptr_to_local(&context), ptr_to_local(&key))); } @@ -1450,7 +1477,6 @@ const v8::Array* v8__Object__PreviewEntries( return maybe_local_to_ptr(ptr_to_local(&self)->PreviewEntries(is_key_value)); } - const v8::Array* v8__Array__New(v8::Isolate* isolate, int length) { return local_to_ptr(v8::Array::New(isolate, length)); } @@ -1536,7 +1562,7 @@ void v8__Set__Clear(const v8::Set& self) { } v8::Set* v8__Set__Add(const v8::Set& self, const v8::Context& context, - const v8::Value& key) { + const v8::Value& key) { return maybe_local_to_ptr( ptr_to_local(&self)->Add(ptr_to_local(&context), ptr_to_local(&key))); } @@ -1787,8 +1813,7 @@ const v8::Value* v8__Context__GetSecurityToken(const v8::Context& self) { return local_to_ptr(value); } -void v8__Context__SetSecurityToken(v8::Context& self, - const v8::Value* token) { +void v8__Context__SetSecurityToken(v8::Context& self, const v8::Value* token) { auto c = ptr_to_local(&self); c->SetSecurityToken(ptr_to_local(token)); } @@ -1802,7 +1827,7 @@ void v8__Context__AllowCodeGenerationFromStrings(v8::Context& self, bool allow) } bool v8__Context_IsCodeGenerationFromStringsAllowed(v8::Context& self) { - return ptr_to_local(&self)->IsCodeGenerationFromStringsAllowed(); + return ptr_to_local(&self)->IsCodeGenerationFromStringsAllowed(); } const v8::Context* v8__Context__FromSnapshot(v8::Isolate* isolate, @@ -1962,9 +1987,10 @@ int v8__Function__ScriptId(const v8::Function& self) { return ptr_to_local(&self)->ScriptId(); } -const v8::ScriptOrigin* v8__Function__GetScriptOrigin(const v8::Function& self) { - std::unique_ptr u = - std::make_unique(ptr_to_local(&self)->GetScriptOrigin()); +const v8::ScriptOrigin* v8__Function__GetScriptOrigin( + const v8::Function& self) { + std::unique_ptr u = std::make_unique( + ptr_to_local(&self)->GetScriptOrigin()); return u.release(); } @@ -1993,10 +2019,9 @@ v8::CTypeInfo* v8__CTypeInfo__New__From__Slice(unsigned int len, return v; } -v8::CFunctionInfo* v8__CFunctionInfo__New(const v8::CTypeInfo& return_info, - unsigned int args_len, - v8::CTypeInfo* args_info, - v8::CFunctionInfo::Int64Representation repr) { +v8::CFunctionInfo* v8__CFunctionInfo__New( + const v8::CTypeInfo& return_info, unsigned int args_len, + v8::CTypeInfo* args_info, v8::CFunctionInfo::Int64Representation repr) { std::unique_ptr info = std::make_unique( v8::CFunctionInfo(return_info, args_len, args_info, repr)); return info.release(); @@ -2120,7 +2145,7 @@ const v8::StackTrace* v8__StackTrace__CurrentStackTrace(v8::Isolate* isolate, } const v8::String* v8__StackTrace__CurrentScriptNameOrSourceURL( - v8::Isolate* isolate) { + v8::Isolate* isolate) { return local_to_ptr(v8::StackTrace::CurrentScriptNameOrSourceURL(isolate)); } @@ -2300,13 +2325,11 @@ int v8__ScriptOrigin__ScriptId(const v8::ScriptOrigin& self) { return ptr_to_local(&self)->ScriptId(); } -const v8::Value* v8__ScriptOrigin__ResourceName( - const v8::ScriptOrigin& self) { +const v8::Value* v8__ScriptOrigin__ResourceName(const v8::ScriptOrigin& self) { return local_to_ptr(ptr_to_local(&self)->ResourceName()); } -const v8::Value* v8__ScriptOrigin__SourceMapUrl( - const v8::ScriptOrigin& self) { +const v8::Value* v8__ScriptOrigin__SourceMapUrl(const v8::ScriptOrigin& self) { return local_to_ptr(ptr_to_local(&self)->SourceMapUrl()); } @@ -3429,8 +3452,7 @@ bool v8__PropertyDescriptor__has_enumerable( return self->has_enumerable(); } -bool v8__PropertyDescriptor__has_writable( - const v8::PropertyDescriptor* self) { +bool v8__PropertyDescriptor__has_writable(const v8::PropertyDescriptor* self) { return self->has_writable(); } @@ -3447,12 +3469,12 @@ bool v8__PropertyDescriptor__has_set(const v8::PropertyDescriptor* self) { } void v8__PropertyDescriptor__set_enumerable(v8::PropertyDescriptor* self, - bool enumurable) { + bool enumurable) { self->set_enumerable(enumurable); } void v8__PropertyDescriptor__set_configurable(v8::PropertyDescriptor* self, - bool configurable) { + bool configurable) { self->set_configurable(configurable); } diff --git a/src/lib.rs b/src/lib.rs index 6b59205be7..c38e541e33 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -139,6 +139,7 @@ pub use script_compiler::CachedData; pub use snapshot::FunctionCodeHandling; pub use snapshot::StartupData; pub use string::NewStringType; +pub use string::OneByteConst; pub use string::WriteOptions; pub use support::SharedPtr; pub use support::SharedRef; diff --git a/src/string.rs b/src/string.rs index 2e0f8a51f8..7a4ee9314a 100644 --- a/src/string.rs +++ b/src/string.rs @@ -69,6 +69,11 @@ extern "C" { options: WriteOptions, ) -> int; + fn v8__String__NewExternalOneByte( + isolate: *mut Isolate, + onebyte_const: *const OneByteConst, + ) -> *const String; + fn v8__String__NewExternalOneByteStatic( isolate: *mut Isolate, buffer: *const char, @@ -90,6 +95,102 @@ extern "C" { fn v8__String__ContainsOnlyOneByte(this: *const String) -> bool; } +#[repr(C)] +#[derive(Debug)] +pub struct OneByteConst { + vtable: *const OneByteConstNoOp, + cached_data: *const char, + length: int, +} + +// SAFETY: The vtable for OneByteConst is an immutable static and all +// of the included functions are thread-safe, the cached_data pointer +// is never changed and points to a static ASCII string, and the +// length is likewise never changed. Thus, it is safe to share the +// OneByteConst across threads. This means that multiple isolates +// can use the same OneByteConst statics simultaneously. +unsafe impl Sync for OneByteConst {} + +extern "C" fn one_byte_const_no_op(_this: *const OneByteConst) {} +extern "C" fn one_byte_const_is_cacheable(_this: *const OneByteConst) -> bool { + true +} +extern "C" fn one_byte_const_data(this: *const OneByteConst) -> *const char { + // SAFETY: Only called from C++ with a valid OneByteConst pointer. + unsafe { (*this).cached_data } +} +extern "C" fn one_byte_const_length(this: *const OneByteConst) -> usize { + // SAFETY: Only called from C++ with a valid OneByteConst pointer. + unsafe { (*this).length as usize } +} + +type OneByteConstNoOp = extern "C" fn(*const OneByteConst); +type OneByteConstIsCacheable = extern "C" fn(*const OneByteConst) -> bool; +type OneByteConstData = extern "C" fn(*const OneByteConst) -> *const char; +type OneByteConstLength = extern "C" fn(*const OneByteConst) -> usize; + +#[repr(C)] +struct OneByteConstVtable { + #[cfg(target_family = "windows")] + // In SysV / Itanium ABI -0x10 offset of the vtable + // tells how many bytes the vtable pointer pointing to + // this vtable is offset from the base class. For + // single inheritance this is always 0. + _offset_to_top: usize, + // In Itanium ABI the -0x08 offset contains the type_info + // pointer, and in MSVC it contains the RTTI Complete Object + // Locator pointer. V8 is normally compiled with `-fno-rtti` + // meaning that this pointer is a nullptr on both + // Itanium and MSVC. + _typeinfo: *const (), + // After the metadata fields come the virtual function + // pointers. The vtable pointer in a class instance points + // to the first virtual function pointer, making this + // the 0x00 offset of the table. + // The order of the virtual function pointers is determined + // by their order of declaration in the classes. + delete1: OneByteConstNoOp, + // In SysV / Itanium ABI, a class vtable includes the + // deleting destructor and the compete object destructor. + // In MSVC, it only includes the deleting destructor. + #[cfg(not(target_family = "windows"))] + delete2: OneByteConstNoOp, + is_cacheable: OneByteConstIsCacheable, + dispose: OneByteConstNoOp, + lock: OneByteConstNoOp, + unlock: OneByteConstNoOp, + data: OneByteConstData, + length: OneByteConstLength, +} + +const ONE_BYTE_CONST_VTABLE: OneByteConstVtable = OneByteConstVtable { + #[cfg(target_family = "windows")] + _offset_to_top: 0, + _typeinfo: std::ptr::null(), + delete1: one_byte_const_no_op, + #[cfg(not(target_family = "windows"))] + delete2: one_byte_const_no_op, + is_cacheable: one_byte_const_is_cacheable, + dispose: one_byte_const_no_op, + lock: one_byte_const_no_op, + unlock: one_byte_const_no_op, + data: one_byte_const_data, + length: one_byte_const_length, +}; + +/// Compile-time function to determine if a string is ASCII. Note that UTF-8 chars +/// longer than one byte have the high-bit set and thus, are not ASCII. +const fn is_ascii(s: &'static [u8]) -> bool { + let mut i = 0; + while i < s.len() { + if !s[i].is_ascii() { + return false; + } + i += 1; + } + true +} + #[repr(C)] #[derive(Debug, Default)] pub enum NewStringType { @@ -332,6 +433,34 @@ impl String { Self::new_from_utf8(scope, value.as_ref(), NewStringType::Normal) } + // Compile-time function to create an external string resource. + // The buffer is checked to contain only ASCII characters. + #[inline(always)] + pub const fn create_external_onebyte_const( + buffer: &'static [u8], + ) -> OneByteConst { + is_ascii(buffer); + OneByteConst { + vtable: &ONE_BYTE_CONST_VTABLE.delete1, + cached_data: buffer.as_ptr() as *const char, + length: buffer.len() as i32, + } + } + + // Creates a v8::String from a `&'static OneByteConst` + // which is guaranteed to be Latin-1 or ASCII. + #[inline(always)] + pub fn new_from_onebyte_const<'s>( + scope: &mut HandleScope<'s, ()>, + onebyte_const: &'static OneByteConst, + ) -> Option> { + unsafe { + scope.cast_local(|sd| { + v8__String__NewExternalOneByte(sd.get_isolate_ptr(), onebyte_const) + }) + } + } + // Creates a v8::String from a `&'static [u8]`, // must be Latin-1 or ASCII, not UTF-8 ! #[inline(always)] diff --git a/tests/test_api.rs b/tests/test_api.rs index 1327951d24..385a8c9347 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -8509,6 +8509,9 @@ fn compile_function() { assert_eq!(42 * 1337, result.int32_value(scope).unwrap()); } +static EXAMPLE_STRING: v8::OneByteConst = + v8::String::create_external_onebyte_const(b"const static"); + #[test] fn external_strings() { let _setup_guard = setup::parallel_test(); @@ -8575,6 +8578,17 @@ fn external_strings() { assert!(!latin1.is_external_twobyte()); assert!(latin1.is_onebyte()); assert!(latin1.contains_only_onebyte()); + + // one-byte "const" test + let const_ref_string = + v8::String::new_from_onebyte_const(scope, &EXAMPLE_STRING).unwrap(); + assert!(const_ref_string.is_external()); + assert!(const_ref_string.is_external_onebyte()); + assert!(!const_ref_string.is_external_twobyte()); + assert!(const_ref_string.is_onebyte()); + assert!(const_ref_string.contains_only_onebyte()); + assert!(const_ref_string + .strict_equals(v8::String::new(scope, "const static").unwrap().into())); } #[test] From 096c540393764d31e6fb660462423015c2393854 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Thu, 13 Jul 2023 10:42:58 -0600 Subject: [PATCH 26/70] chore: update to Rust 1.71 (#1283) --- rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index f15cd1c929..9058c7d87d 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.70.0" +channel = "1.71.0" components = ["rustfmt", "clippy"] From fcf0281d3eb48b22981564203773bf078473547d Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Fri, 14 Jul 2023 02:51:34 +0300 Subject: [PATCH 27/70] fix(OneByteConst): missing ASCII assertion, assert length (#1282) Fix missing ASCII assertion, assert length --- src/string.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/string.rs b/src/string.rs index 7a4ee9314a..965187fea7 100644 --- a/src/string.rs +++ b/src/string.rs @@ -100,7 +100,7 @@ extern "C" { pub struct OneByteConst { vtable: *const OneByteConstNoOp, cached_data: *const char, - length: int, + length: usize, } // SAFETY: The vtable for OneByteConst is an immutable static and all @@ -121,7 +121,7 @@ extern "C" fn one_byte_const_data(this: *const OneByteConst) -> *const char { } extern "C" fn one_byte_const_length(this: *const OneByteConst) -> usize { // SAFETY: Only called from C++ with a valid OneByteConst pointer. - unsafe { (*this).length as usize } + unsafe { (*this).length } } type OneByteConstNoOp = extern "C" fn(*const OneByteConst); @@ -439,11 +439,13 @@ impl String { pub const fn create_external_onebyte_const( buffer: &'static [u8], ) -> OneByteConst { - is_ascii(buffer); + // Assert that the buffer contains only ASCII, and that the + // length is less or equal to (64-bit) v8::String::kMaxLength. + assert!(is_ascii(buffer) && buffer.len() <= ((1 << 29) - 24)); OneByteConst { vtable: &ONE_BYTE_CONST_VTABLE.delete1, cached_data: buffer.as_ptr() as *const char, - length: buffer.len() as i32, + length: buffer.len(), } } From 1d3572b5aa3a819f318f9b5a2a71014c9db41733 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Tue, 18 Jul 2023 03:33:51 -0600 Subject: [PATCH 28/70] Rolling to V8 11.6.189.11 (#1281) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 22d389ed7d..f14afb6d2c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.6.189.9 +V8 Version: 11.6.189.11 [![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) diff --git a/v8 b/v8 index 845a647579..b7a4d3fddc 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 845a64757951cfba51918d79977773d82132f783 +Subproject commit b7a4d3fddc1abd21630150f7411cc6ef0a62b98f From f360663e6763aff38490ab0700de5ef2cceb9723 Mon Sep 17 00:00:00 2001 From: Andreu Botella Date: Wed, 19 Jul 2023 14:52:58 +0200 Subject: [PATCH 29/70] feat: Add `{Dis,}allowJavascriptExecutionScope` (#862) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds two new types of scopes: - DisallowJavascriptExecutionScope - AllowJavascriptExecutionScope The first one can be used to prevent execution of JavaScript (with customizable behavior on an attempt of executing JS, eg. crashing the process); while the second one can be constructed from the first to temporarily enable executing JS. These are useful for "value serializers" to prevent user defined objects from causing unintended behavior. --------- Co-authored-by: Bartek Iwańczuk --- src/binding.cc | 32 ++ src/lib.rs | 3 + src/scope.rs | 437 ++++++++++++++++++ .../handle_scope_escape_to_nowhere.stderr | 6 + tests/test_api.rs | 121 +++++ 5 files changed, 599 insertions(+) diff --git a/src/binding.cc b/src/binding.cc index 24f75b52a6..6fc2704930 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -65,6 +65,14 @@ static_assert(sizeof(v8::ReturnValue) == sizeof(size_t) * 1, static_assert(sizeof(v8::TryCatch) == sizeof(size_t) * 6, "TryCatch size mismatch"); +static_assert(sizeof(v8::Isolate::DisallowJavascriptExecutionScope) == + sizeof(size_t) * 2, + "DisallowJavascriptExecutionScope size mismatch"); + +static_assert(sizeof(v8::Isolate::AllowJavascriptExecutionScope) == + sizeof(size_t) * 2, + "AllowJavascriptExecutionScope size mismatch"); + static_assert(sizeof(v8::Location) == sizeof(int) * 2, "Location size mismatch"); @@ -2250,6 +2258,30 @@ void v8__TryCatch__SetCaptureMessage(v8::TryCatch* self, bool value) { self->SetCaptureMessage(value); } +void v8__DisallowJavascriptExecutionScope__CONSTRUCT( + uninit_t* buf, + v8::Isolate* isolate, + v8::Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure) { + construct_in_place( + buf, isolate, on_failure); +} + +void v8__DisallowJavascriptExecutionScope__DESTRUCT( + v8::Isolate::DisallowJavascriptExecutionScope* self) { + self->~DisallowJavascriptExecutionScope(); +} + +void v8__AllowJavascriptExecutionScope__CONSTRUCT( + uninit_t* buf, + v8::Isolate* isolate) { + construct_in_place(buf, isolate); +} + +void v8__AllowJavascriptExecutionScope__DESTRUCT( + v8::Isolate::AllowJavascriptExecutionScope* self) { + self->~AllowJavascriptExecutionScope(); +} + #define V(NAME) \ const v8::NAME* v8__##NAME##__New(const v8::ArrayBuffer& buf_ptr, \ size_t byte_offset, size_t length) { \ diff --git a/src/lib.rs b/src/lib.rs index c38e541e33..a205007a3e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -129,10 +129,13 @@ pub use property_descriptor::*; pub use property_filter::*; pub use property_handler_flags::*; pub use proxy::*; +pub use scope::AllowJavascriptExecutionScope; pub use scope::CallbackScope; pub use scope::ContextScope; +pub use scope::DisallowJavascriptExecutionScope; pub use scope::EscapableHandleScope; pub use scope::HandleScope; +pub use scope::OnFailure; pub use scope::TryCatch; pub use script::ScriptOrigin; pub use script_compiler::CachedData; diff --git a/src/scope.rs b/src/scope.rs index 8ccfadc68d..00dfea56bc 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -76,6 +76,17 @@ //! - This scope type is only to be constructed inside embedder defined //! callbacks when these are called by V8. //! - When a scope is created inside, type is erased to `HandleScope<'s>`. +//! +//! - `DisallowJavascriptExecutionScope<'s, P>` +//! - 's = lifetime of the `DisallowJavascriptExecutionScope` scope. +//! - `P` is either a `HandleScope`, `ContextScope`, `EscapableHandleScope` +//! or a `TryCatch`. +//! - Derefs to `P`. +//! +//! - `AllowJavascriptExecutionScope<'s, P>` +//! - 's = lifetime of the `AllowJavascriptExecutionScope` scope. +//! - `P` is `DisallowJavascriptExecutionScope`. +//! - Derefs to `HandleScope<'s, ()>`. use std::alloc::alloc; use std::alloc::Layout; @@ -585,6 +596,50 @@ impl<'s> CallbackScope<'s> { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(C)] +pub enum OnFailure { + CrashOnFailure, + ThrowOnFailure, + DumpOnFailure, +} + +#[derive(Debug)] +pub struct DisallowJavascriptExecutionScope<'s, P> { + _data: NonNull, + _phantom: PhantomData<&'s mut P>, +} + +impl<'s, P: param::NewDisallowJavascriptExecutionScope<'s>> + DisallowJavascriptExecutionScope<'s, P> +{ + #[allow(clippy::new_ret_no_self)] + pub fn new(param: &'s mut P, on_failure: OnFailure) -> P::NewScope { + param + .get_scope_data_mut() + .new_disallow_javascript_execution_scope_data(on_failure) + .as_scope() + } +} + +#[derive(Debug)] +pub struct AllowJavascriptExecutionScope<'s, P> { + _data: NonNull, + _phantom: PhantomData<&'s mut P>, +} + +impl<'s, P: param::NewAllowJavascriptExecutionScope<'s>> + AllowJavascriptExecutionScope<'s, P> +{ + #[allow(clippy::new_ret_no_self)] + pub fn new(param: &'s mut P) -> P::NewScope { + param + .get_scope_data_mut() + .new_allow_javascript_execution_scope_data() + .as_scope() + } +} + macro_rules! impl_as { // Implements `AsRef` and AsMut` on a scope type. (<$($params:tt),+> $src_type:ty as Isolate) => { @@ -622,6 +677,8 @@ impl_as!(<'s, 'p, P> ContextScope<'s, P> as Isolate); impl_as!(<'s, C> HandleScope<'s, C> as Isolate); impl_as!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> as Isolate); impl_as!(<'s, P> TryCatch<'s, P> as Isolate); +impl_as!(<'s, P> DisallowJavascriptExecutionScope<'s, P> as Isolate); +impl_as!(<'s, P> AllowJavascriptExecutionScope<'s, P> as Isolate); impl_as!(<'s, C> CallbackScope<'s, C> as Isolate); impl_as!(<'s, 'p> ContextScope<'s, HandleScope<'p>> as HandleScope<'p, ()>); @@ -630,6 +687,10 @@ impl_as!(<'s, C> HandleScope<'s, C> as HandleScope<'s, ()>); impl_as!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> as HandleScope<'s, ()>); impl_as!(<'s, 'p, C> TryCatch<'s, HandleScope<'p, C>> as HandleScope<'p, ()>); impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as HandleScope<'p, ()>); +impl_as!(<'s, 'p, C> DisallowJavascriptExecutionScope<'s, HandleScope<'p, C>> as HandleScope<'p, ()>); +impl_as!(<'s, 'p, 'e, C> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as HandleScope<'p, ()>); +impl_as!(<'s, 'p, C> AllowJavascriptExecutionScope<'s, HandleScope<'p, C>> as HandleScope<'p, ()>); +impl_as!(<'s, 'p, 'e, C> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as HandleScope<'p, ()>); impl_as!(<'s, C> CallbackScope<'s, C> as HandleScope<'s, ()>); impl_as!(<'s, 'p> ContextScope<'s, HandleScope<'p>> as HandleScope<'p>); @@ -638,15 +699,23 @@ impl_as!(<'s> HandleScope<'s> as HandleScope<'s>); impl_as!(<'s, 'e> EscapableHandleScope<'s, 'e> as HandleScope<'s>); impl_as!(<'s, 'p> TryCatch<'s, HandleScope<'p>> as HandleScope<'p>); impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p>); +impl_as!(<'s, 'p> DisallowJavascriptExecutionScope<'s, HandleScope<'p>> as HandleScope<'p>); +impl_as!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p>); +impl_as!(<'s, 'p> AllowJavascriptExecutionScope<'s, HandleScope<'p>> as HandleScope<'p>); +impl_as!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as HandleScope<'p>); impl_as!(<'s> CallbackScope<'s> as HandleScope<'s>); impl_as!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e, ()>); impl_as!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> as EscapableHandleScope<'s, 'e, ()>); impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as EscapableHandleScope<'p, 'e, ()>); +impl_as!(<'s, 'p, 'e, C> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as EscapableHandleScope<'p, 'e, ()>); +impl_as!(<'s, 'p, 'e, C> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as EscapableHandleScope<'p, 'e, ()>); impl_as!(<'s, 'p, 'e> ContextScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>); impl_as!(<'s, 'e> EscapableHandleScope<'s, 'e> as EscapableHandleScope<'s, 'e>); impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>); +impl_as!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>); +impl_as!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>); impl_as!(<'s, 'p, C> TryCatch<'s, HandleScope<'p, C>> as TryCatch<'s, HandleScope<'p, ()>>); impl_as!(<'s, 'p, 'e, C> TryCatch<'s, EscapableHandleScope<'p, 'e, C>> as TryCatch<'s, HandleScope<'p, ()>>); @@ -656,6 +725,25 @@ impl_as!(<'s, 'p> TryCatch<'s, HandleScope<'p>> as TryCatch<'s, HandleScope<'p>> impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as TryCatch<'s, HandleScope<'p>>); impl_as!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as TryCatch<'s, EscapableHandleScope<'p, 'e>>); +impl_as!(<'s, 'p, C> DisallowJavascriptExecutionScope<'s, HandleScope<'p, C>> as DisallowJavascriptExecutionScope<'s, HandleScope<'p, ()>>); +impl_as!(<'s, 'p, 'e, C> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as DisallowJavascriptExecutionScope<'s, HandleScope<'p, ()>>); +impl_as!(<'s, 'p, 'e, C> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, ()>>); + +impl_as!(<'s, 'p> DisallowJavascriptExecutionScope<'s, HandleScope<'p>> as DisallowJavascriptExecutionScope<'s, HandleScope<'p>>); +impl_as!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as DisallowJavascriptExecutionScope<'s, HandleScope<'p>>); +impl_as!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>>); + +impl_as!(<'s, 'p, C> AllowJavascriptExecutionScope<'s, HandleScope<'p, C>> as AllowJavascriptExecutionScope<'s, HandleScope<'p, ()>>); +impl_as!(<'s, 'p, 'e, C> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as AllowJavascriptExecutionScope<'s, HandleScope<'p, ()>>); +impl_as!(<'s, 'p, 'e, C> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>> as AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, ()>>); + +impl_as!(<'s, 'p> AllowJavascriptExecutionScope<'s, HandleScope<'p>> as AllowJavascriptExecutionScope<'s, HandleScope<'p>>); +impl_as!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as AllowJavascriptExecutionScope<'s, HandleScope<'p>>); +impl_as!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>>); + +impl_as!(<'s, 'p, P> DisallowJavascriptExecutionScope<'s, TryCatch<'p, P>> as TryCatch<'p, P>); +impl_as!(<'s, 'p, P> AllowJavascriptExecutionScope<'s, TryCatch<'p, P>> as TryCatch<'p, P>); + macro_rules! impl_deref { (<$($params:tt),+> $src_type:ty as $tgt_type:ty) => { impl<$($params),*> Deref for $src_type { @@ -687,6 +775,18 @@ impl_deref!(<'s, 'p> TryCatch<'s, HandleScope<'p>> as HandleScope<'p>); impl_deref!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e, ()>> as EscapableHandleScope<'p, 'e, ()>); impl_deref!(<'s, 'p, 'e> TryCatch<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>); +impl_deref!(<'s, 'p> DisallowJavascriptExecutionScope<'s, HandleScope<'p, ()>> as HandleScope<'p, ()>); +impl_deref!(<'s, 'p> DisallowJavascriptExecutionScope<'s, HandleScope<'p>> as HandleScope<'p>); +impl_deref!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, ()>> as EscapableHandleScope<'p, 'e, ()>); +impl_deref!(<'s, 'p, 'e> DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>); +impl_deref!(<'s, 'p, P> DisallowJavascriptExecutionScope<'s, TryCatch<'p, P>> as TryCatch<'p, P>); + +impl_deref!(<'s, 'p> AllowJavascriptExecutionScope<'s, HandleScope<'p, ()>> as HandleScope<'p, ()>); +impl_deref!(<'s, 'p> AllowJavascriptExecutionScope<'s, HandleScope<'p>> as HandleScope<'p>); +impl_deref!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, ()>> as EscapableHandleScope<'p, 'e, ()>); +impl_deref!(<'s, 'p, 'e> AllowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e>> as EscapableHandleScope<'p, 'e>); +impl_deref!(<'s, 'p, P> AllowJavascriptExecutionScope<'s, TryCatch<'p, P>> as TryCatch<'p, P>); + impl_deref!(<'s> CallbackScope<'s, ()> as HandleScope<'s, ()>); impl_deref!(<'s> CallbackScope<'s> as HandleScope<'s>); @@ -707,6 +807,8 @@ impl_scope_drop!(<'s, 'p, P> ContextScope<'s, P>); impl_scope_drop!(<'s, C> HandleScope<'s, C> ); impl_scope_drop!(<'s, 'e, C> EscapableHandleScope<'s, 'e, C> ); impl_scope_drop!(<'s, P> TryCatch<'s, P> ); +impl_scope_drop!(<'s, P> DisallowJavascriptExecutionScope<'s, P>); +impl_scope_drop!(<'s, P> AllowJavascriptExecutionScope<'s, P>); impl_scope_drop!(<'s, C> CallbackScope<'s, C> ); pub unsafe trait Scope: Sized {} @@ -768,6 +870,18 @@ mod param { type NewScope =

>::NewScope; } + impl<'s, 'p: 's, P: NewContextScope<'s>> NewContextScope<'s> + for DisallowJavascriptExecutionScope<'p, P> + { + type NewScope =

>::NewScope; + } + + impl<'s, 'p: 's, P: NewContextScope<'s>> NewContextScope<'s> + for AllowJavascriptExecutionScope<'p, P> + { + type NewScope =

>::NewScope; + } + impl<'s, 'p: 's, C> NewContextScope<'s> for CallbackScope<'p, C> { type NewScope = ContextScope<'s, HandleScope<'p>>; } @@ -804,6 +918,18 @@ mod param { type NewScope =

>::NewScope; } + impl<'s, 'p: 's, P: NewHandleScope<'s>> NewHandleScope<'s> + for DisallowJavascriptExecutionScope<'p, P> + { + type NewScope =

>::NewScope; + } + + impl<'s, 'p: 's, P: NewHandleScope<'s>> NewHandleScope<'s> + for AllowJavascriptExecutionScope<'p, P> + { + type NewScope =

>::NewScope; + } + impl<'s, 'p: 's, C> NewHandleScope<'s> for CallbackScope<'p, C> { type NewScope = HandleScope<'s, C>; } @@ -850,6 +976,19 @@ mod param { type NewScope =

>::NewScope; } + impl<'s, 'p: 's, 'e: 'p, P: NewEscapableHandleScope<'s, 'e>> + NewEscapableHandleScope<'s, 'e> + for DisallowJavascriptExecutionScope<'p, P> + { + type NewScope =

>::NewScope; + } + + impl<'s, 'p: 's, 'e: 'p, P: NewEscapableHandleScope<'s, 'e>> + NewEscapableHandleScope<'s, 'e> for AllowJavascriptExecutionScope<'p, P> + { + type NewScope =

>::NewScope; + } + impl<'s, 'p: 's, C> NewEscapableHandleScope<'s, 'p> for CallbackScope<'p, C> { type NewScope = EscapableHandleScope<'s, 'p, C>; } @@ -876,10 +1015,101 @@ mod param { type NewScope = TryCatch<'s, P>; } + impl<'s, 'p: 's, P> NewTryCatch<'s> + for DisallowJavascriptExecutionScope<'p, P> + { + type NewScope = TryCatch<'s, P>; + } + + impl<'s, 'p: 's, P> NewTryCatch<'s> for AllowJavascriptExecutionScope<'p, P> { + type NewScope = TryCatch<'s, P>; + } + impl<'s, 'p: 's, C> NewTryCatch<'s> for CallbackScope<'p, C> { type NewScope = TryCatch<'s, HandleScope<'p, C>>; } + pub trait NewDisallowJavascriptExecutionScope<'s>: + getter::GetScopeData + { + type NewScope: Scope; + } + + impl<'s, 'p: 's, P: NewDisallowJavascriptExecutionScope<'s>> + NewDisallowJavascriptExecutionScope<'s> for ContextScope<'p, P> + { + type NewScope =

>::NewScope; + } + + impl<'s, 'p: 's, C> NewDisallowJavascriptExecutionScope<'s> + for HandleScope<'p, C> + { + type NewScope = DisallowJavascriptExecutionScope<'s, HandleScope<'p, C>>; + } + + impl<'s, 'p: 's, 'e: 'p, C> NewDisallowJavascriptExecutionScope<'s> + for EscapableHandleScope<'p, 'e, C> + { + type NewScope = + DisallowJavascriptExecutionScope<'s, EscapableHandleScope<'p, 'e, C>>; + } + + impl<'s, 'p: 's, P> NewDisallowJavascriptExecutionScope<'s> + for TryCatch<'p, P> + { + type NewScope = DisallowJavascriptExecutionScope<'s, TryCatch<'p, P>>; + } + + impl<'s, 'p: 's, P> NewDisallowJavascriptExecutionScope<'s> + for DisallowJavascriptExecutionScope<'p, P> + { + type NewScope = DisallowJavascriptExecutionScope<'s, P>; + } + + impl<'s, 'p: 's, P> NewDisallowJavascriptExecutionScope<'s> + for AllowJavascriptExecutionScope<'p, P> + { + type NewScope = DisallowJavascriptExecutionScope<'s, P>; + } + + pub trait NewAllowJavascriptExecutionScope<'s>: getter::GetScopeData { + type NewScope: Scope; + } + + impl<'s, 'p: 's, P: NewAllowJavascriptExecutionScope<'s>> + NewAllowJavascriptExecutionScope<'s> for ContextScope<'p, P> + { + type NewScope =

>::NewScope; + } + + impl<'s, 'p: 's, C> NewAllowJavascriptExecutionScope<'s> + for HandleScope<'p, C> + { + type NewScope = HandleScope<'p, C>; + } + + impl<'s, 'p: 's, 'e: 'p, C> NewAllowJavascriptExecutionScope<'s> + for EscapableHandleScope<'p, 'e, C> + { + type NewScope = EscapableHandleScope<'p, 'e, C>; + } + + impl<'s, 'p: 's, P> NewAllowJavascriptExecutionScope<'s> for TryCatch<'p, P> { + type NewScope = TryCatch<'s, P>; + } + + impl<'s, 'p: 's, P: Scope> NewAllowJavascriptExecutionScope<'s> + for DisallowJavascriptExecutionScope<'p, P> + { + type NewScope = P; + } + + impl<'s, 'p: 's, P> NewAllowJavascriptExecutionScope<'s> + for AllowJavascriptExecutionScope<'p, P> + { + type NewScope = AllowJavascriptExecutionScope<'s, P>; + } + pub trait NewCallbackScope<'s>: Sized + getter::GetIsolate<'s> { type NewScope: Scope; @@ -1226,6 +1456,49 @@ pub(crate) mod data { }) } + #[inline(always)] + pub(super) fn new_disallow_javascript_execution_scope_data( + &mut self, + on_failure: OnFailure, + ) -> &mut Self { + self.new_scope_data_with(|data| { + let isolate = data.isolate; + data.scope_type_specific_data.init_with(|| { + ScopeTypeSpecificData::DisallowJavascriptExecutionScope { + raw_scope: unsafe { + raw::DisallowJavascriptExecutionScope::uninit() + }, + } + }); + match &mut data.scope_type_specific_data { + ScopeTypeSpecificData::DisallowJavascriptExecutionScope { + raw_scope, + } => unsafe { raw_scope.init(isolate, on_failure) }, + _ => unreachable!(), + } + }) + } + + #[inline(always)] + pub(super) fn new_allow_javascript_execution_scope_data( + &mut self, + ) -> &mut Self { + self.new_scope_data_with(|data| { + let isolate = data.isolate; + data.scope_type_specific_data.init_with(|| { + ScopeTypeSpecificData::AllowJavascriptExecutionScope { + raw_scope: unsafe { raw::AllowJavascriptExecutionScope::uninit() }, + } + }); + match &mut data.scope_type_specific_data { + ScopeTypeSpecificData::AllowJavascriptExecutionScope { + raw_scope, + } => unsafe { raw_scope.init(isolate) }, + _ => unreachable!(), + } + }) + } + #[inline(always)] pub(super) fn new_callback_scope_data<'s>( &'s mut self, @@ -1553,6 +1826,12 @@ pub(crate) mod data { TryCatch { raw_try_catch: raw::TryCatch, }, + DisallowJavascriptExecutionScope { + raw_scope: raw::DisallowJavascriptExecutionScope, + }, + AllowJavascriptExecutionScope { + raw_scope: raw::AllowJavascriptExecutionScope, + }, } impl Default for ScopeTypeSpecificData { @@ -1714,6 +1993,77 @@ mod raw { } } + #[repr(C)] + #[derive(Debug)] + pub(super) struct DisallowJavascriptExecutionScope([MaybeUninit; 2]); + + impl DisallowJavascriptExecutionScope { + /// Creates an uninitialized `DisallowJavascriptExecutionScope`. + /// + /// This function is marked unsafe because the caller must ensure that the + /// returned value isn't dropped before `init()` has been called. + pub unsafe fn uninit() -> Self { + Self(MaybeUninit::uninit().assume_init()) + } + + /// This function is marked unsafe because `init()` must be called exactly + /// once, no more and no less, after creating a + /// `DisallowJavascriptExecutionScope` value with + /// `DisallowJavascriptExecutionScope::uninit()`. + pub unsafe fn init( + &mut self, + isolate: NonNull, + on_failure: OnFailure, + ) { + let buf = NonNull::from(self).cast(); + v8__DisallowJavascriptExecutionScope__CONSTRUCT( + buf.as_ptr(), + isolate.as_ptr(), + on_failure, + ); + } + } + + impl Drop for DisallowJavascriptExecutionScope { + #[inline(always)] + fn drop(&mut self) { + unsafe { v8__DisallowJavascriptExecutionScope__DESTRUCT(self) }; + } + } + + #[repr(C)] + #[derive(Debug)] + pub(super) struct AllowJavascriptExecutionScope([MaybeUninit; 2]); + + impl AllowJavascriptExecutionScope { + /// Creates an uninitialized `AllowJavascriptExecutionScope`. + /// + /// This function is marked unsafe because the caller must ensure that the + /// returned value isn't dropped before `init()` has been called. + pub unsafe fn uninit() -> Self { + Self(MaybeUninit::uninit().assume_init()) + } + + /// This function is marked unsafe because `init()` must be called exactly + /// once, no more and no less, after creating an + /// `AllowJavascriptExecutionScope` value with + /// `AllowJavascriptExecutionScope::uninit()`. + pub unsafe fn init(&mut self, isolate: NonNull) { + let buf = NonNull::from(self).cast(); + v8__AllowJavascriptExecutionScope__CONSTRUCT( + buf.as_ptr(), + isolate.as_ptr(), + ); + } + } + + impl Drop for AllowJavascriptExecutionScope { + #[inline(always)] + fn drop(&mut self) { + unsafe { v8__AllowJavascriptExecutionScope__DESTRUCT(self) }; + } + } + extern "C" { pub(super) fn v8__Isolate__GetCurrentContext( isolate: *mut Isolate, @@ -1796,6 +2146,23 @@ mod raw { ) -> *const Message; pub(super) fn v8__TryCatch__ReThrow(this: *mut TryCatch) -> *const Value; + pub(super) fn v8__DisallowJavascriptExecutionScope__CONSTRUCT( + buf: *mut MaybeUninit, + isolate: *mut Isolate, + on_failure: OnFailure, + ); + pub(super) fn v8__DisallowJavascriptExecutionScope__DESTRUCT( + this: *mut DisallowJavascriptExecutionScope, + ); + + pub(super) fn v8__AllowJavascriptExecutionScope__CONSTRUCT( + buf: *mut MaybeUninit, + isolate: *mut Isolate, + ); + pub(super) fn v8__AllowJavascriptExecutionScope__DESTRUCT( + this: *mut AllowJavascriptExecutionScope, + ); + pub(super) fn v8__Message__GetIsolate(this: *const Message) -> *mut Isolate; pub(super) fn v8__Object__GetIsolate(this: *const Object) -> *mut Isolate; @@ -1865,6 +2232,28 @@ mod tests { let d = d.deref_mut(); AssertTypeOf(d).is::(); } + { + let l3_djses = &mut DisallowJavascriptExecutionScope::new( + l2_cxs, + OnFailure::CrashOnFailure, + ); + AssertTypeOf(l3_djses) + .is::>(); + let d = l3_djses.deref_mut(); + AssertTypeOf(d).is::(); + let d = d.deref_mut(); + AssertTypeOf(d).is::>(); + let d = d.deref_mut(); + AssertTypeOf(d).is::(); + { + let l4_ajses = &mut AllowJavascriptExecutionScope::new(l3_djses); + AssertTypeOf(l4_ajses).is::(); + let d = l4_ajses.deref_mut(); + AssertTypeOf(d).is::>(); + let d = d.deref_mut(); + AssertTypeOf(d).is::(); + } + } { let l3_ehs = &mut EscapableHandleScope::new(l2_cxs); AssertTypeOf(l3_ehs).is::(); @@ -1892,6 +2281,32 @@ mod tests { let d = d.deref_mut(); AssertTypeOf(d).is::(); } + { + let l4_djses = &mut DisallowJavascriptExecutionScope::new( + l3_ehs, + OnFailure::CrashOnFailure, + ); + AssertTypeOf(l4_djses) + .is::>(); + let d = l4_djses.deref_mut(); + AssertTypeOf(d).is::(); + let d = d.deref_mut(); + AssertTypeOf(d).is::(); + let d = d.deref_mut(); + AssertTypeOf(d).is::>(); + let d = d.deref_mut(); + AssertTypeOf(d).is::(); + { + let l5_ajses = &mut AllowJavascriptExecutionScope::new(l4_djses); + AssertTypeOf(l5_ajses).is::(); + let d = l5_ajses.deref_mut(); + AssertTypeOf(d).is::(); + let d = d.deref_mut(); + AssertTypeOf(d).is::>(); + let d = d.deref_mut(); + AssertTypeOf(d).is::(); + } + } } } { @@ -1901,6 +2316,28 @@ mod tests { AssertTypeOf(d).is::>(); let d = d.deref_mut(); AssertTypeOf(d).is::(); + { + let l3_djses = &mut DisallowJavascriptExecutionScope::new( + l2_tc, + OnFailure::CrashOnFailure, + ); + AssertTypeOf(l3_djses) + .is::>>>(); + let d = l3_djses.deref_mut(); + AssertTypeOf(d).is::>>(); + let d = d.deref_mut(); + AssertTypeOf(d).is::>(); + let d = d.deref_mut(); + AssertTypeOf(d).is::(); + { + let l4_ajses = &mut AllowJavascriptExecutionScope::new(l3_djses); + AssertTypeOf(l4_ajses).is::>>(); + let d = l4_ajses.deref_mut(); + AssertTypeOf(d).is::>(); + let d = d.deref_mut(); + AssertTypeOf(d).is::(); + } + } } { let l2_ehs = &mut EscapableHandleScope::new(l1_hs); diff --git a/tests/compile_fail/handle_scope_escape_to_nowhere.stderr b/tests/compile_fail/handle_scope_escape_to_nowhere.stderr index 7fe08661bf..d0021e1b20 100644 --- a/tests/compile_fail/handle_scope_escape_to_nowhere.stderr +++ b/tests/compile_fail/handle_scope_escape_to_nowhere.stderr @@ -7,8 +7,10 @@ error[E0277]: the trait bound `OwnedIsolate: v8::scope::param::NewEscapableHandl | required by a bound introduced by this call | = help: the following other types implement trait `v8::scope::param::NewEscapableHandleScope<'s, 'e>`: + as v8::scope::param::NewEscapableHandleScope<'s, 'e>> as v8::scope::param::NewEscapableHandleScope<'s, 'p>> as v8::scope::param::NewEscapableHandleScope<'s, 'e>> + as v8::scope::param::NewEscapableHandleScope<'s, 'e>> as v8::scope::param::NewEscapableHandleScope<'s, 'p>> as v8::scope::param::NewEscapableHandleScope<'s, 'p>> as v8::scope::param::NewEscapableHandleScope<'s, 'e>> @@ -25,8 +27,10 @@ error[E0277]: the trait bound `OwnedIsolate: v8::scope::param::NewEscapableHandl | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `v8::scope::param::NewEscapableHandleScope<'_, '_>` is not implemented for `OwnedIsolate` | = help: the following other types implement trait `v8::scope::param::NewEscapableHandleScope<'s, 'e>`: + as v8::scope::param::NewEscapableHandleScope<'s, 'e>> as v8::scope::param::NewEscapableHandleScope<'s, 'p>> as v8::scope::param::NewEscapableHandleScope<'s, 'e>> + as v8::scope::param::NewEscapableHandleScope<'s, 'e>> as v8::scope::param::NewEscapableHandleScope<'s, 'p>> as v8::scope::param::NewEscapableHandleScope<'s, 'p>> as v8::scope::param::NewEscapableHandleScope<'s, 'e>> @@ -38,8 +42,10 @@ error[E0277]: the trait bound `OwnedIsolate: v8::scope::param::NewEscapableHandl | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `v8::scope::param::NewEscapableHandleScope<'_, '_>` is not implemented for `OwnedIsolate` | = help: the following other types implement trait `v8::scope::param::NewEscapableHandleScope<'s, 'e>`: + as v8::scope::param::NewEscapableHandleScope<'s, 'e>> as v8::scope::param::NewEscapableHandleScope<'s, 'p>> as v8::scope::param::NewEscapableHandleScope<'s, 'e>> + as v8::scope::param::NewEscapableHandleScope<'s, 'e>> as v8::scope::param::NewEscapableHandleScope<'s, 'p>> as v8::scope::param::NewEscapableHandleScope<'s, 'p>> as v8::scope::param::NewEscapableHandleScope<'s, 'e>> diff --git a/tests/test_api.rs b/tests/test_api.rs index 385a8c9347..fb79fb0a0f 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -10647,3 +10647,124 @@ fn exception_thrown_but_continues_execution() { let _result = script.run(scope); assert_eq!(CALL_COUNT.load(Ordering::SeqCst), 2); } + +#[test] +fn disallow_javascript_execution_scope() { + let _setup_guard = setup::parallel_test(); + + let mut isolate = v8::Isolate::new(Default::default()); + let mut scope = v8::HandleScope::new(&mut isolate); + let context = v8::Context::new(&mut scope); + let mut scope = v8::ContextScope::new(&mut scope, context); + + // We can run JS before the scope begins. + assert_eq!( + eval(&mut scope, "42").unwrap().uint32_value(&mut scope), + Some(42) + ); + + { + let try_catch = &mut v8::TryCatch::new(&mut scope); + { + let scope = &mut v8::DisallowJavascriptExecutionScope::new( + try_catch, + v8::OnFailure::ThrowOnFailure, + ); + assert!(eval(scope, "42").is_none()); + } + assert!(try_catch.has_caught()); + try_catch.reset(); + } + + // And we can run JS after the scope ends. + assert_eq!( + eval(&mut scope, "42").unwrap().uint32_value(&mut scope), + Some(42) + ); +} + +// TODO: Test DisallowJavascriptExecutionScope with OnFailure::CrashOnFailure +// and OnFailure::DumpOnFailure. #[should_panic] obviously doesn't work on +// those. + +#[test] +fn allow_javascript_execution_scope() { + let _setup_guard = setup::parallel_test(); + + let mut isolate = v8::Isolate::new(Default::default()); + let mut scope = v8::HandleScope::new(&mut isolate); + let context = v8::Context::new(&mut scope); + let mut scope = v8::ContextScope::new(&mut scope, context); + + let disallow_scope = &mut v8::DisallowJavascriptExecutionScope::new( + &mut scope, + v8::OnFailure::CrashOnFailure, + ); + let allow_scope = &mut v8::AllowJavascriptExecutionScope::new(disallow_scope); + assert_eq!( + eval(allow_scope, "42").unwrap().uint32_value(allow_scope), + Some(42) + ); +} + +#[test] +fn allow_scope_in_read_host_object() { + // The scope that is passed to ValueDeserializerImpl::read_host_object is + // internally a DisallowJavascriptExecutionScope, so an allow scope must be + // created in order to run JS code in that callback. + struct Serializer; + impl v8::ValueSerializerImpl for Serializer { + fn write_host_object<'s>( + &mut self, + _scope: &mut v8::HandleScope<'s>, + _object: v8::Local<'s, v8::Object>, + _value_serializer: &mut dyn v8::ValueSerializerHelper, + ) -> Option { + // Doesn't look at the object or writes anything. + Some(true) + } + + fn throw_data_clone_error<'s>( + &mut self, + _scope: &mut v8::HandleScope<'s>, + _message: v8::Local<'s, v8::String>, + ) { + todo!() + } + } + + struct Deserializer; + impl v8::ValueDeserializerImpl for Deserializer { + fn read_host_object<'s>( + &mut self, + scope: &mut v8::HandleScope<'s>, + _value_deserializer: &mut dyn v8::ValueDeserializerHelper, + ) -> Option> { + let scope2 = &mut v8::AllowJavascriptExecutionScope::new(scope); + let value = eval(scope2, "{}").unwrap(); + let object = v8::Local::::try_from(value).unwrap(); + Some(object) + } + } + + let _setup_guard = setup::parallel_test(); + + let mut isolate = v8::Isolate::new(Default::default()); + let mut scope = v8::HandleScope::new(&mut isolate); + let context = v8::Context::new(&mut scope); + let mut scope = v8::ContextScope::new(&mut scope, context); + + let serialized = { + let mut serializer = + v8::ValueSerializer::new(&mut scope, Box::new(Serializer)); + serializer + .write_value(context, v8::Object::new(&mut scope).into()) + .unwrap(); + serializer.release() + }; + + let mut deserializer = + v8::ValueDeserializer::new(&mut scope, Box::new(Deserializer), &serialized); + let value = deserializer.read_value(context).unwrap(); + assert!(value.is_object()); +} From e1c403f384d5760fc4ef883bbf5fd482e18bf049 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Fri, 21 Jul 2023 05:57:26 -0600 Subject: [PATCH 30/70] Rolling to V8 11.6.189.12 (#1286) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f14afb6d2c..752c9783fb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.6.189.11 +V8 Version: 11.6.189.12 [![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) diff --git a/v8 b/v8 index b7a4d3fddc..96bea5eafa 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit b7a4d3fddc1abd21630150f7411cc6ef0a62b98f +Subproject commit 96bea5eafa4374f3c7aba1a838af5f259c0bab53 From e908964fc43a643e76ece94942c0e6857e624e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Fri, 21 Jul 2023 17:42:18 +0200 Subject: [PATCH 31/70] feat: Add v8::Value::type_repr() (#1285) --- src/value.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/value.rs b/src/value.rs index 1ad867e759..0fa8aee9cd 100644 --- a/src/value.rs +++ b/src/value.rs @@ -724,4 +724,92 @@ impl Value { } .unwrap() } + + /// Utility method that returns human readable representation of the + /// underlying value. + pub fn type_repr(&self) -> &'static str { + if self.is_module_namespace_object() { + "Module" + } else if self.is_wasm_module_object() { + "WASM module" + } else if self.is_wasm_memory_object() { + "WASM memory object" + } else if self.is_proxy() { + "Proxy" + } else if self.is_shared_array_buffer() { + "SharedArrayBuffer" + } else if self.is_data_view() { + "DataView" + } else if self.is_big_uint64_array() { + "BigUint64Array" + } else if self.is_big_int64_array() { + "BigInt64Array" + } else if self.is_float64_array() { + "Float64Array" + } else if self.is_float32_array() { + "Float32Array" + } else if self.is_int32_array() { + "Int32Array" + } else if self.is_uint32_array() { + "Uint32Array" + } else if self.is_int16_array() { + "Int16Array" + } else if self.is_uint16_array() { + "Uint16Array" + } else if self.is_int8_array() { + "Int8Array" + } else if self.is_uint8_clamped_array() { + "Uint8ClampedArray" + } else if self.is_uint8_array() { + "Uint8Array" + } else if self.is_typed_array() { + "TypedArray" + } else if self.is_array_buffer_view() { + "ArrayBufferView" + } else if self.is_array_buffer() { + "ArrayBuffer" + } else if self.is_weak_set() { + "WeakSet" + } else if self.is_weak_map() { + "WeakMap" + } else if self.is_set_iterator() { + "Set Iterator" + } else if self.is_map_iterator() { + "Map Iterator" + } else if self.is_set() { + "Set" + } else if self.is_map() { + "Map" + } else if self.is_promise() { + "Promise" + } else if self.is_generator_function() { + "Generator function" + } else if self.is_async_function() { + "Async function" + } else if self.is_reg_exp() { + "RegExp" + } else if self.is_date() { + "Date" + } else if self.is_number() { + "Number" + } else if self.is_boolean() { + "Boolean" + } else if self.is_big_int() { + "bigint" + } else if self.is_array() { + "array" + } else if self.is_function() { + "function" + } else if self.is_symbol() { + "symbol" + } else if self.is_string() { + "string" + } else if self.is_null() { + "null" + } else if self.is_undefined() { + "undefined" + } else { + "unknown" + } + } } From c923d787500851b96c1b8a802c219cd0a4d82036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sat, 22 Jul 2023 23:28:48 +0200 Subject: [PATCH 32/70] v0.74.3 (#1287) --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 895e336a06..19e2a829ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1183,7 +1183,7 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "v8" -version = "0.74.2" +version = "0.74.3" dependencies = [ "align-data", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index 8ed2dd29dd..a77dd0645f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.74.2" +version = "0.74.3" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From 1d6988942b0222f1fc89fb181d4892255c4327f4 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Tue, 25 Jul 2023 05:08:28 -0600 Subject: [PATCH 33/70] Rolling to V8 11.6.189.14 (#1288) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 752c9783fb..ed0fd00b52 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.6.189.12 +V8 Version: 11.6.189.14 [![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) diff --git a/v8 b/v8 index 96bea5eafa..a662b728ae 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 96bea5eafa4374f3c7aba1a838af5f259c0bab53 +Subproject commit a662b728aed47635be5c67052597f1ba7a69549a From 715060df6e71024c68089f5127b30311502ec9dd Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Thu, 27 Jul 2023 16:10:17 +0300 Subject: [PATCH 34/70] fix: 32-bit build fails on non-size_t based size assertions (#1289) --- src/binding.cc | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/binding.cc b/src/binding.cc index 6fc2704930..57d8bdae74 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -65,10 +65,6 @@ static_assert(sizeof(v8::ReturnValue) == sizeof(size_t) * 1, static_assert(sizeof(v8::TryCatch) == sizeof(size_t) * 6, "TryCatch size mismatch"); -static_assert(sizeof(v8::Isolate::DisallowJavascriptExecutionScope) == - sizeof(size_t) * 2, - "DisallowJavascriptExecutionScope size mismatch"); - static_assert(sizeof(v8::Isolate::AllowJavascriptExecutionScope) == sizeof(size_t) * 2, "AllowJavascriptExecutionScope size mismatch"); @@ -96,6 +92,9 @@ static_assert(offsetof(v8::ScriptCompiler::CachedData, rejected) == 12, "CachedData.rejected offset mismatch"); static_assert(offsetof(v8::ScriptCompiler::CachedData, buffer_policy) == 16, "CachedData.buffer_policy offset mismatch"); +static_assert(sizeof(v8::Isolate::DisallowJavascriptExecutionScope) == + 16, + "DisallowJavascriptExecutionScope size mismatch"); #else static_assert(sizeof(v8::ScriptCompiler::CachedData) == 16, "CachedData size mismatch"); @@ -107,6 +106,9 @@ static_assert(offsetof(v8::ScriptCompiler::CachedData, rejected) == 8, "CachedData.rejected offset mismatch"); static_assert(offsetof(v8::ScriptCompiler::CachedData, buffer_policy) == 12, "CachedData.buffer_policy offset mismatch"); +static_assert(sizeof(v8::Isolate::DisallowJavascriptExecutionScope) == + 12, + "DisallowJavascriptExecutionScope size mismatch"); #endif extern "C" { @@ -1030,12 +1032,12 @@ class ExternalConstOneByteStringResource public: ExternalConstOneByteStringResource(int length) : _length(length) { - static_assert(offsetof(ExternalConstOneByteStringResource, _length) == 16, - "ExternalConstOneByteStringResource's length was not at offset 16"); - static_assert(sizeof(ExternalConstOneByteStringResource) == 24, - "ExternalConstOneByteStringResource size was not 24"); - static_assert(alignof(ExternalConstOneByteStringResource) == 8, - "ExternalConstOneByteStringResource align was not 8"); + static_assert(offsetof(ExternalConstOneByteStringResource, _length) == sizeof(size_t) * 2, + "ExternalConstOneByteStringResource's length was not at offset of sizeof(size_t) * 2"); + static_assert(sizeof(ExternalConstOneByteStringResource) == sizeof(size_t) * 3, + "ExternalConstOneByteStringResource size was not sizeof(size_t) * 3"); + static_assert(alignof(ExternalConstOneByteStringResource) == sizeof(size_t), + "ExternalConstOneByteStringResource align was not sizeof(size_t)"); } const char* data() const override { return nullptr; } size_t length() const override { return _length; } From 86fddc2fc8c87be36561ad6cbd60900b9a1abe09 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Fri, 28 Jul 2023 05:27:55 -0600 Subject: [PATCH 35/70] Rolling to V8 11.6.189.15 (#1291) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ed0fd00b52..42b57f02fc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.6.189.14 +V8 Version: 11.6.189.15 [![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) diff --git a/v8 b/v8 index a662b728ae..d0a4394546 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit a662b728aed47635be5c67052597f1ba7a69549a +Subproject commit d0a43945465192a91d49c06efbcf304e8355d934 From 4b8ee0b235fd0463c03d9ffaf330d2f37ab70b5c Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Fri, 4 Aug 2023 14:49:44 +0200 Subject: [PATCH 36/70] Rolling to V8 11.6.189.16 (#1292) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 42b57f02fc..7a781ff74d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.6.189.15 +V8 Version: 11.6.189.16 [![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) diff --git a/v8 b/v8 index d0a4394546..41f3d89183 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit d0a43945465192a91d49c06efbcf304e8355d934 +Subproject commit 41f3d89183173cccefd080647299ac3ab58ba214 From 8c8f88a294166f2ca63dd3612c9b366fa11d64dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Tue, 8 Aug 2023 16:12:30 +0200 Subject: [PATCH 37/70] chore: track v8 11.7 (#1295) --- tools/auto_update_v8.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/auto_update_v8.ts b/tools/auto_update_v8.ts index d541a38b60..70c1b019cb 100644 --- a/tools/auto_update_v8.ts +++ b/tools/auto_update_v8.ts @@ -1,4 +1,4 @@ -const V8_TRACKING_BRANCH = "11.6-lkgr-denoland"; +const V8_TRACKING_BRANCH = "11.7-lkgr-denoland"; const AUTOROLL_BRANCH = "autoroll"; function extractVersion() { From 45732562037de81539069e34d25856553edd4de0 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Tue, 8 Aug 2023 19:29:54 -0400 Subject: [PATCH 38/70] Rolling to V8 11.7.439.1 (#1296) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartek Iwańczuk --- .gitmodules | 3 +++ .gn | 6 ------ README.md | 2 +- build.rs | 2 +- src/binding.cc | 38 +++++++++++++++++++++++--------------- src/icu.rs | 6 +++--- src/isolate.rs | 2 +- tests/test_api.rs | 4 ++-- third_party/abseil-cpp | 1 + third_party/icu | 2 +- v8 | 2 +- 11 files changed, 37 insertions(+), 31 deletions(-) create mode 160000 third_party/abseil-cpp diff --git a/.gitmodules b/.gitmodules index 4d712d7e8e..5ff41bf655 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,6 @@ [submodule "third_party/icu"] path = third_party/icu url = https://github.com/denoland/icu.git +[submodule "third_party/abseil-cpp"] + path = third_party/abseil-cpp + url = https://chromium.googlesource.com/chromium/src/third_party/abseil-cpp.git diff --git a/.gn b/.gn index 0ba2aeb930..6b4b9d2b26 100644 --- a/.gn +++ b/.gn @@ -51,12 +51,6 @@ default_args = { # compiler" snapshots, and sometimes uses them both at the same time. v8_enable_shared_ro_heap = false - # V8 introduced a bug in 11.1 that causes the External Pointer Table to never - # be cleaned which causes resource exhaustion. Disabling pointer compression - # makes sure that the EPT is not used. - # https://bugs.chromium.org/p/v8/issues/detail?id=13640&q=garbage%20collection&can=2 - v8_enable_pointer_compression = false - # V8 11.6 hardcoded an assumption in `mksnapshot` that shared RO heap # is enabled. In our case it's disabled so without this flag we can't # compile. diff --git a/README.md b/README.md index 7a781ff74d..f77bd777ff 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.6.189.16 +V8 Version: 11.7.439.1 [![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) diff --git a/build.rs b/build.rs index ce173e2475..27e134bf5e 100644 --- a/build.rs +++ b/build.rs @@ -883,6 +883,6 @@ edge [fontsize=10] fn test_static_lib_size() { let static_lib_size = std::fs::metadata(static_lib_path()).unwrap().len(); eprintln!("static lib size {}", static_lib_size); - assert!(static_lib_size <= 230u64 << 20); // No more than 230 MiB. + assert!(static_lib_size <= 270u64 << 20); // No more than 270 MiB. } } diff --git a/src/binding.cc b/src/binding.cc index 57d8bdae74..ebd1c32665 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -484,17 +484,17 @@ bool v8__Data__EQ(const v8::Data& self, const v8::Data& other) { } bool v8__Data__IsBigInt(const v8::Data& self) { - return v8::Utils::OpenHandle(&self)->IsBigInt(); + return IsBigInt(*v8::Utils::OpenHandle(&self)); } bool v8__Data__IsBoolean(const v8::Data& self) { - return v8::Utils::OpenHandle(&self)->IsBoolean(); + return IsBoolean(*v8::Utils::OpenHandle(&self)); } bool v8__Data__IsContext(const v8::Data& self) { return self.IsContext(); } bool v8__Data__IsFixedArray(const v8::Data& self) { - return v8::Utils::OpenHandle(&self)->IsFixedArray(); + return IsFixedArray(*v8::Utils::OpenHandle(&self)); } bool v8__Data__IsFunctionTemplate(const v8::Data& self) { @@ -504,15 +504,15 @@ bool v8__Data__IsFunctionTemplate(const v8::Data& self) { bool v8__Data__IsModule(const v8::Data& self) { return self.IsModule(); } bool v8__Data__IsModuleRequest(const v8::Data& self) { - return v8::Utils::OpenHandle(&self)->IsModuleRequest(); + return IsModuleRequest(*v8::Utils::OpenHandle(&self)); } bool v8__Data__IsName(const v8::Data& self) { - return v8::Utils::OpenHandle(&self)->IsName(); + return IsName(*v8::Utils::OpenHandle(&self)); } bool v8__Data__IsNumber(const v8::Data& self) { - return v8::Utils::OpenHandle(&self)->IsNumber(); + return IsNumber(*v8::Utils::OpenHandle(&self)); } bool v8__Data__IsObjectTemplate(const v8::Data& self) { @@ -520,17 +520,17 @@ bool v8__Data__IsObjectTemplate(const v8::Data& self) { } bool v8__Data__IsPrimitive(const v8::Data& self) { - return v8::Utils::OpenHandle(&self)->IsPrimitive() && !self.IsPrivate(); + return IsPrimitive(*v8::Utils::OpenHandle(&self)) && !self.IsPrivate(); } bool v8__Data__IsPrivate(const v8::Data& self) { return self.IsPrivate(); } bool v8__Data__IsString(const v8::Data& self) { - return v8::Utils::OpenHandle(&self)->IsString(); + return IsString(*v8::Utils::OpenHandle(&self)); } bool v8__Data__IsSymbol(const v8::Data& self) { - return v8::Utils::OpenHandle(&self)->IsPublicSymbol(); + return IsPublicSymbol(*v8::Utils::OpenHandle(&self)); } bool v8__Data__IsValue(const v8::Data& self) { return self.IsValue(); } @@ -3060,11 +3060,19 @@ void v8__HeapProfiler__TakeHeapSnapshot(v8::Isolate* isolate, const_cast(snapshot)->Delete(); } +// This is necessary for v8__internal__GetIsolateFromHeapObject() to be +// reliable enough for our purposes. +#if UINTPTR_MAX == 0xffffffffffffffff && \ + !(defined V8_SHARED_RO_HEAP or defined V8_COMPRESS_POINTERS) +#error V8 must be built with either the 'v8_enable_pointer_compression' or \ +'v8_enable_shared_ro_heap' feature enabled. +#endif + v8::Isolate* v8__internal__GetIsolateFromHeapObject(const v8::Data& data) { namespace i = v8::internal; i::Object object(reinterpret_cast(data)); i::Isolate* isolate; - return object.IsHeapObject() && + return IsHeapObject(object) && i::GetIsolateFromHeapObject(object.GetHeapObject(), &isolate) ? reinterpret_cast(isolate) : nullptr; @@ -3074,10 +3082,10 @@ int v8__Value__GetHash(const v8::Value& data) { namespace i = v8::internal; i::Object object(reinterpret_cast(data)); i::Isolate* isolate; - int hash = object.IsHeapObject() && i::GetIsolateFromHeapObject( + int hash = IsHeapObject(object) && i::GetIsolateFromHeapObject( object.GetHeapObject(), &isolate) - ? object.GetOrCreateHash(isolate).value() - : i::Smi::ToInt(object.GetHash()); + ? i::Object::GetOrCreateHash(object, isolate).value() + : i::Smi::ToInt(i::Object::GetHash(object)); assert(hash != 0); return hash; } @@ -3401,8 +3409,8 @@ void v8__CompiledWasmModule__DELETE(v8::CompiledWasmModule* self) { extern "C" { size_t icu_get_default_locale(char* output, size_t output_len) { - const icu_72::Locale& default_locale = icu::Locale::getDefault(); - icu_72::CheckedArrayByteSink sink(output, static_cast(output_len)); + const icu_73::Locale& default_locale = icu::Locale::getDefault(); + icu_73::CheckedArrayByteSink sink(output, static_cast(output_len)); UErrorCode status = U_ZERO_ERROR; default_locale.toLanguageTag(sink, status); assert(status == U_ZERO_ERROR); diff --git a/src/icu.rs b/src/icu.rs index 71dcd996a7..15c1be3940 100644 --- a/src/icu.rs +++ b/src/icu.rs @@ -5,7 +5,7 @@ use std::ffi::CString; extern "C" { fn icu_get_default_locale(output: *mut char, output_len: usize) -> usize; fn icu_set_default_locale(locale: *const char); - fn udata_setCommonData_72(this: *const u8, error_code: *mut i32); + fn udata_setCommonData_73(this: *const u8, error_code: *mut i32); } /// This function bypasses the normal ICU data loading process and allows you to force ICU's system @@ -42,10 +42,10 @@ extern "C" { /// functionality for application data. // TODO(ry) Map error code to something useful. #[inline(always)] -pub fn set_common_data_72(data: &'static [u8]) -> Result<(), i32> { +pub fn set_common_data_73(data: &'static [u8]) -> Result<(), i32> { let mut error_code = 0i32; unsafe { - udata_setCommonData_72(data.as_ptr(), &mut error_code); + udata_setCommonData_73(data.as_ptr(), &mut error_code); } if error_code == 0 { Ok(()) diff --git a/src/isolate.rs b/src/isolate.rs index b71f8c5e4e..ade12644b8 100644 --- a/src/isolate.rs +++ b/src/isolate.rs @@ -543,7 +543,7 @@ impl Isolate { // Byte offset inside `Isolate` where the isolate data slots are stored. This // should be the same as the value of `kIsolateEmbedderDataOffset` which is // defined in `v8-internal.h`. - const EMBEDDER_DATA_OFFSET: usize = size_of::<[*const (); 62]>(); + const EMBEDDER_DATA_OFFSET: usize = size_of::<[*const (); 67]>(); // Isolate data slots used internally by rusty_v8. const ANNEX_SLOT: u32 = 0; diff --git a/tests/test_api.rs b/tests/test_api.rs index fb79fb0a0f..0f57885864 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -46,7 +46,7 @@ mod setup { fn initialize_once() { static START: Once = Once::new(); START.call_once(|| { - assert!(v8::icu::set_common_data_72(align_data::include_aligned!( + assert!(v8::icu::set_common_data_73(align_data::include_aligned!( align_data::Align16, "../third_party/icu/common/icudtl.dat" )) @@ -8193,7 +8193,7 @@ fn icu_date() { #[test] fn icu_set_common_data_fail() { - assert!(v8::icu::set_common_data_72(&[1, 2, 3]).is_err()); + assert!(v8::icu::set_common_data_73(&[1, 2, 3]).is_err()); } #[test] diff --git a/third_party/abseil-cpp b/third_party/abseil-cpp new file mode 160000 index 0000000000..583dc6d1b3 --- /dev/null +++ b/third_party/abseil-cpp @@ -0,0 +1 @@ +Subproject commit 583dc6d1b3a0dd44579718699e37cad2f0c41a26 diff --git a/third_party/icu b/third_party/icu index 629a4bb99b..a22a8f2422 160000 --- a/third_party/icu +++ b/third_party/icu @@ -1 +1 @@ -Subproject commit 629a4bb99bf9f088120a2435deb6f630fc30f351 +Subproject commit a22a8f24224ddda8b856437d7e8560de1da3f8e1 diff --git a/v8 b/v8 index 41f3d89183..5163da1ee1 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 41f3d89183173cccefd080647299ac3ab58ba214 +Subproject commit 5163da1ee15f95956b1cf8da5b0a91e7470f4b0f From dbca136bee783511f5c2ee898e71884e97522090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 9 Aug 2023 16:30:57 +0200 Subject: [PATCH 39/70] ci: exclude def files from third_party/abseil-cpp (#1298) --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index a77dd0645f..3a292ee214 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ exclude = [ "third_party/icu/source/samples/", "third_party/icu/source/tools/", "third_party/icu/tzres/", + "third_party/abseil-cpp/*.def", "tools/clang", "v8/ChangeLog", "v8/benchmarks/", From 8bea295a0ee21a40d27f4216be4e3b856cf97652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 9 Aug 2023 16:55:53 +0200 Subject: [PATCH 40/70] v0.75.0 (#1299) --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19e2a829ab..08ea333d42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1183,7 +1183,7 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "v8" -version = "0.74.3" +version = "0.75.0" dependencies = [ "align-data", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index 3a292ee214..a981757659 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.74.3" +version = "0.75.0" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From 32fad1464368f4ce644097d8191b0a86cd202d2b Mon Sep 17 00:00:00 2001 From: "Troy J. Farrell" Date: Thu, 17 Aug 2023 03:24:49 +0600 Subject: [PATCH 41/70] Remove a redundant and confusing sentence from FAQ (#1297) --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f77bd777ff..6c31edfc33 100644 --- a/README.md +++ b/README.md @@ -150,11 +150,10 @@ attempts that carefully balances the requirements of cargo crates and GN/Ninja. **V8 has a very large API with hundreds of methods. Why don't you automate the generation of this binding code?** -In the limit we would like to auto-generate bindings. We have actually started -down this route several times, however due to many eccentric features of the V8 -API, this has not proven successful. Therefore we are proceeding in a -brute-force fashion for now, focusing on solving our stated goals first. We hope -to auto-generate bindings in the future. +We have actually started down this route several times, however due to many +eccentric features of the V8 API, this has not proven successful. Therefore we +are proceeding in a brute-force fashion for now, focusing on solving our stated +goals first. We hope to auto-generate bindings in the future. **Why are you building this?** From c77f06441e41b03fd0893e2a562ea2ac07f9b327 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Wed, 23 Aug 2023 12:14:19 -0400 Subject: [PATCH 42/70] Rolling to V8 11.7.439.5 (#1300) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6c31edfc33..f506dd4a00 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.7.439.1 +V8 Version: 11.7.439.5 [![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) diff --git a/v8 b/v8 index 5163da1ee1..137fc2a297 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 5163da1ee15f95956b1cf8da5b0a91e7470f4b0f +Subproject commit 137fc2a297b0f8cf9b1c3f1e7adb86803bad9dda From 7c78966d55363d7d13ecc408bd082d915758ac39 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Wed, 23 Aug 2023 20:28:19 -0700 Subject: [PATCH 43/70] chore: turn pointer compression off again (#1302) The memory leak caused by the EPT table not being subject to garbage collection is apparently still there. --- .gn | 11 +++++++++++ src/binding.cc | 8 -------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.gn b/.gn index 6b4b9d2b26..de04c86b51 100644 --- a/.gn +++ b/.gn @@ -55,4 +55,15 @@ default_args = { # is enabled. In our case it's disabled so without this flag we can't # compile. v8_enable_verify_heap = false + + # V8 introduced a bug in 11.1 that causes the External Pointer Table to never + # be cleaned which causes resource exhaustion. Disabling pointer compression + # makes sure that the EPT is not used. + # https://bugs.chromium.org/p/v8/issues/detail?id=13640&q=garbage%20collection&can=2 + v8_enable_pointer_compression = false + + # Maglev *should* be supported when pointer compression is disabled as per + # https://chromium-review.googlesource.com/c/v8/v8/+/4753150, but it still + # fails to compile. + v8_enable_maglev = false } diff --git a/src/binding.cc b/src/binding.cc index ebd1c32665..12cb83f789 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -3060,14 +3060,6 @@ void v8__HeapProfiler__TakeHeapSnapshot(v8::Isolate* isolate, const_cast(snapshot)->Delete(); } -// This is necessary for v8__internal__GetIsolateFromHeapObject() to be -// reliable enough for our purposes. -#if UINTPTR_MAX == 0xffffffffffffffff && \ - !(defined V8_SHARED_RO_HEAP or defined V8_COMPRESS_POINTERS) -#error V8 must be built with either the 'v8_enable_pointer_compression' or \ -'v8_enable_shared_ro_heap' feature enabled. -#endif - v8::Isolate* v8__internal__GetIsolateFromHeapObject(const v8::Data& data) { namespace i = v8::internal; i::Object object(reinterpret_cast(data)); From 3d1c2c03138f51af7fa4fe230f777404f0ed5725 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Thu, 24 Aug 2023 15:56:19 +0200 Subject: [PATCH 44/70] Rolling to V8 11.7.439.6 (#1304) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f506dd4a00..1ce9cf0bea 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.7.439.5 +V8 Version: 11.7.439.6 [![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) diff --git a/v8 b/v8 index 137fc2a297..40ca314580 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 137fc2a297b0f8cf9b1c3f1e7adb86803bad9dda +Subproject commit 40ca3145809218c5545c33d313e7bc32261e7850 From 3ff89f41462baab9c0bd8eaf8d7b1f4503ab4a0e Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Thu, 24 Aug 2023 11:58:08 -0400 Subject: [PATCH 45/70] v0.75.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08ea333d42..1d61439e3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1183,7 +1183,7 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "v8" -version = "0.75.0" +version = "0.75.1" dependencies = [ "align-data", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index a981757659..d8c6e327e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.75.0" +version = "0.75.1" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From a0aa26d64822132319ac2c45b609ddf60ebda913 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Aug 2023 17:43:19 +0000 Subject: [PATCH 46/70] build(deps): bump bumpalo from 3.9.1 to 3.13.0 (#1306) Bumps [bumpalo](https://github.com/fitzgen/bumpalo) from 3.9.1 to 3.13.0. - [Changelog](https://github.com/fitzgen/bumpalo/blob/main/CHANGELOG.md) - [Commits](https://github.com/fitzgen/bumpalo/compare/3.9.1...3.13.0) --- updated-dependencies: - dependency-name: bumpalo dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d61439e3a..f5a0a5615d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,9 +96,9 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytemuck" From aa203e032c7d12bc329252487ddc4a250b94c2b3 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Fri, 1 Sep 2023 12:35:38 +0200 Subject: [PATCH 47/70] Rolling to V8 11.7.439.14 (#1307) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1ce9cf0bea..ed6eaa2dfa 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.7.439.6 +V8 Version: 11.7.439.14 [![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) diff --git a/v8 b/v8 index 40ca314580..a01f96cbb8 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 40ca3145809218c5545c33d313e7bc32261e7850 +Subproject commit a01f96cbb8b9aa5042fe918f43c6e4d582f9b036 From 987d520221ca0e8349441a72a0af8e68015aa239 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Fri, 1 Sep 2023 08:54:52 -0400 Subject: [PATCH 48/70] fix: don't allocate for zero-length strings (#1309) --- src/string.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/string.rs b/src/string.rs index 965187fea7..0fce1fbc6b 100644 --- a/src/string.rs +++ b/src/string.rs @@ -552,9 +552,15 @@ impl String { &self, scope: &mut Isolate, ) -> std::string::String { - let len_utf8 = self.utf8_length(scope); let len_utf16 = self.length(); + // No need to allocate or do any work for zero-length strings + if len_utf16 == 0 { + return std::string::String::new(); + } + + let len_utf8 = self.utf8_length(scope); + // If len_utf8 == len_utf16 and the string is one-byte, we can take the fast memcpy path. This is true iff the // string is 100% 7-bit ASCII. if self.is_onebyte() && len_utf8 == len_utf16 { @@ -612,9 +618,15 @@ impl String { scope: &mut Isolate, buffer: &'a mut [MaybeUninit; N], ) -> Cow<'a, str> { + let len_utf16 = self.length(); + + // No need to allocate or do any work for zero-length strings + if len_utf16 == 0 { + return "".into(); + } + // TODO(mmastrac): Ideally we should be able to access the string's internal representation let len_utf8 = self.utf8_length(scope); - let len_utf16 = self.length(); // If len_utf8 == len_utf16 and the string is one-byte, we can take the fast memcpy path. This is true iff the // string is 100% 7-bit ASCII. From 4cf545b925d24958e63c951c6c4ec5eb4362e467 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Wed, 6 Sep 2023 13:23:41 +0200 Subject: [PATCH 49/70] Rolling to V8 11.7.439.15 (#1311) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ed6eaa2dfa..6220aac83e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.7.439.14 +V8 Version: 11.7.439.15 [![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) diff --git a/v8 b/v8 index a01f96cbb8..b3d2f06279 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit a01f96cbb8b9aa5042fe918f43c6e4d582f9b036 +Subproject commit b3d2f06279f8e8bfade9e84fd1bec806b9c7ebbc From bdd4fc3f6e46163bac3bd71c8a12e6af4499ab76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Fri, 8 Sep 2023 14:58:23 +0200 Subject: [PATCH 50/70] chore: track v8 11.8 (#1315) --- tools/auto_update_v8.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/auto_update_v8.ts b/tools/auto_update_v8.ts index 70c1b019cb..faf247d38a 100644 --- a/tools/auto_update_v8.ts +++ b/tools/auto_update_v8.ts @@ -1,4 +1,4 @@ -const V8_TRACKING_BRANCH = "11.7-lkgr-denoland"; +const V8_TRACKING_BRANCH = "11.8-lkgr-denoland"; const AUTOROLL_BRANCH = "autoroll"; function extractVersion() { From 6eb4b811dfcbbe2623df331197ea4cdf39f94197 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Fri, 8 Sep 2023 17:01:54 +0200 Subject: [PATCH 51/70] Rolling to V8 11.8.172.1 (#1316) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6220aac83e..1d0a91f0d5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.7.439.15 +V8 Version: 11.8.172.1 [![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) diff --git a/v8 b/v8 index b3d2f06279..15a8016f9e 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit b3d2f06279f8e8bfade9e84fd1bec806b9c7ebbc +Subproject commit 15a8016f9e4e93296958c0709a1dd944068c68f1 From 53e048ffc798f6a531cd264d14922904614891d6 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Tue, 12 Sep 2023 16:26:42 -0700 Subject: [PATCH 52/70] fix: crash on x86_64 systems that support memory protection keys (#1318) Co-authored-by: Matt Mastracci --- src/binding.cc | 58 +++++++++++++++++++ src/lib.rs | 1 + src/platform.rs | 54 +++++++++++++++++ tests/slots.rs | 2 +- tests/test_api.rs | 2 +- tests/test_api_entropy_source.rs | 4 +- tests/test_api_flags.rs | 4 +- ...test_platform_atomics_pump_message_loop.rs | 4 +- 8 files changed, 124 insertions(+), 5 deletions(-) diff --git a/src/binding.cc b/src/binding.cc index 12cb83f789..6dab984650 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -1,9 +1,11 @@ // Copyright 2019-2021 the Deno authors. All rights reserved. MIT license. +#include #include #include #include #include #include +#include #include "support.h" #include "unicode/locid.h" @@ -17,9 +19,12 @@ #include "v8/include/v8.h" #include "v8/src/api/api-inl.h" #include "v8/src/api/api.h" +#include "v8/src/base/debug/stack_trace.h" +#include "v8/src/base/sys-info.h" #include "v8/src/execution/isolate-utils-inl.h" #include "v8/src/execution/isolate-utils.h" #include "v8/src/flags/flags.h" +#include "v8/src/libplatform/default-platform.h" #include "v8/src/objects/objects-inl.h" #include "v8/src/objects/objects.h" #include "v8/src/objects/smi.h" @@ -2579,6 +2584,49 @@ v8::StartupData v8__SnapshotCreator__CreateBlob( return self->CreateBlob(function_code_handling); } +class UnprotectedDefaultPlatform : public v8::platform::DefaultPlatform { + using IdleTaskSupport = v8::platform::IdleTaskSupport; + using InProcessStackDumping = v8::platform::InProcessStackDumping; + using PriorityMode = v8::platform::PriorityMode; + using TracingController = v8::TracingController; + + static constexpr int kMaxThreadPoolSize = 16; + + public: + explicit UnprotectedDefaultPlatform( + int thread_pool_size, IdleTaskSupport idle_task_support, + std::unique_ptr tracing_controller = {}, + PriorityMode priority_mode = PriorityMode::kDontApply) + : v8::platform::DefaultPlatform(thread_pool_size, idle_task_support, + std::move(tracing_controller), + priority_mode) {} + + static std::unique_ptr New( + int thread_pool_size, IdleTaskSupport idle_task_support, + InProcessStackDumping in_process_stack_dumping, + std::unique_ptr tracing_controller = {}, + PriorityMode priority_mode = PriorityMode::kDontApply) { + // This implementation is semantically equivalent to the implementation of + // `v8::platform::NewDefaultPlatform()`. + DCHECK_GE(thread_pool_size, 0); + if (thread_pool_size < 1) { + thread_pool_size = + std::max(v8::base::SysInfo::NumberOfProcessors() - 1, 1); + } + thread_pool_size = std::min(thread_pool_size, kMaxThreadPoolSize); + if (in_process_stack_dumping == InProcessStackDumping::kEnabled) { + v8::base::debug::EnableInProcessStackDumping(); + } + return std::make_unique( + thread_pool_size, idle_task_support, std::move(tracing_controller), + priority_mode); + } + + v8::ThreadIsolatedAllocator* GetThreadIsolatedAllocator() override { + return nullptr; + } +}; + v8::Platform* v8__Platform__NewDefaultPlatform(int thread_pool_size, bool idle_task_support) { return v8::platform::NewDefaultPlatform( @@ -2589,6 +2637,16 @@ v8::Platform* v8__Platform__NewDefaultPlatform(int thread_pool_size, .release(); } +v8::Platform* v8__Platform__NewUnprotectedDefaultPlatform( + int thread_pool_size, bool idle_task_support) { + return UnprotectedDefaultPlatform::New( + thread_pool_size, + idle_task_support ? v8::platform::IdleTaskSupport::kEnabled + : v8::platform::IdleTaskSupport::kDisabled, + v8::platform::InProcessStackDumping::kDisabled, nullptr) + .release(); +} + v8::Platform* v8__Platform__NewSingleThreadedDefaultPlatform( bool idle_task_support) { return v8::platform::NewSingleThreadedDefaultPlatform( diff --git a/src/lib.rs b/src/lib.rs index a205007a3e..a6c2a69c45 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -120,6 +120,7 @@ pub use module::*; pub use object::*; pub use platform::new_default_platform; pub use platform::new_single_threaded_default_platform; +pub use platform::new_unprotected_default_platform; pub use platform::Platform; pub use primitives::*; pub use private::*; diff --git a/src/platform.rs b/src/platform.rs index 01b42905b0..a1a15dfd66 100644 --- a/src/platform.rs +++ b/src/platform.rs @@ -14,6 +14,10 @@ extern "C" { thread_pool_size: int, idle_task_support: bool, ) -> *mut Platform; + fn v8__Platform__NewUnprotectedDefaultPlatform( + thread_pool_size: int, + idle_task_support: bool, + ) -> *mut Platform; fn v8__Platform__NewSingleThreadedDefaultPlatform( idle_task_support: bool, ) -> *mut Platform; @@ -58,6 +62,16 @@ pub struct Platform(Opaque); /// If |idle_task_support| is enabled then the platform will accept idle /// tasks (IdleTasksEnabled will return true) and will rely on the embedder /// calling v8::platform::RunIdleTasks to process the idle tasks. +/// +/// The default platform for v8 may include restrictions and caveats on thread +/// creation and initialization. This platform should only be used in cases +/// where v8 can be reliably initialized on the application's main thread, or +/// the parent thread to all threads in the system that will use v8. +/// +/// One example of a restriction is the use of Memory Protection Keys (pkeys) on +/// modern Linux systems using modern Intel/AMD processors. This particular +/// technology requires that all threads using v8 are created as descendent +/// threads of the thread that called `v8::Initialize`. #[inline(always)] pub fn new_default_platform( thread_pool_size: u32, @@ -66,6 +80,18 @@ pub fn new_default_platform( Platform::new(thread_pool_size, idle_task_support) } +/// Creates a platform that is identical to the default platform, but does not +/// enforce thread-isolated allocations. This may reduce security in some cases, +/// so this method should be used with caution in cases where the threading +/// guarantees of `new_default_platform` cannot be upheld (generally for tests). +#[inline(always)] +pub fn new_unprotected_default_platform( + thread_pool_size: u32, + idle_task_support: bool, +) -> UniqueRef { + Platform::new_unprotected(thread_pool_size, idle_task_support) +} + /// The same as new_default_platform() but disables the worker thread pool. /// It must be used with the --single-threaded V8 flag. /// @@ -88,6 +114,16 @@ impl Platform { /// If |idle_task_support| is enabled then the platform will accept idle /// tasks (IdleTasksEnabled will return true) and will rely on the embedder /// calling v8::platform::RunIdleTasks to process the idle tasks. + /// + /// The default platform for v8 may include restrictions and caveats on thread + /// creation and initialization. This platform should only be used in cases + /// where v8 can be reliably initialized on the application's main thread, or + /// the parent thread to all threads in the system that will use v8. + /// + /// One example of a restriction is the use of Memory Protection Keys (pkeys) + /// on modern Linux systems using modern Intel/AMD processors. This particular + /// technology requires that all threads using v8 are created as descendent + /// threads of the thread that called `v8::Initialize`. #[inline(always)] pub fn new( thread_pool_size: u32, @@ -101,6 +137,24 @@ impl Platform { } } + /// Creates a platform that is identical to the default platform, but does not + /// enforce thread-isolated allocations. This may reduce security in some + /// cases, so this method should be used with caution in cases where the + /// threading guarantees of `new_default_platform` cannot be upheld (generally + /// for tests). + #[inline(always)] + pub fn new_unprotected( + thread_pool_size: u32, + idle_task_support: bool, + ) -> UniqueRef { + unsafe { + UniqueRef::from_raw(v8__Platform__NewUnprotectedDefaultPlatform( + thread_pool_size.min(16) as i32, + idle_task_support, + )) + } + } + /// The same as new() but disables the worker thread pool. /// It must be used with the --single-threaded V8 flag. /// diff --git a/tests/slots.rs b/tests/slots.rs index 5e204c5b5d..e491fbe596 100644 --- a/tests/slots.rs +++ b/tests/slots.rs @@ -15,7 +15,7 @@ fn setup() { START.call_once(|| { v8::V8::set_flags_from_string("--expose_gc"); v8::V8::initialize_platform( - v8::new_default_platform(0, false).make_shared(), + v8::new_unprotected_default_platform(0, false).make_shared(), ); v8::V8::initialize(); }); diff --git a/tests/test_api.rs b/tests/test_api.rs index 0f57885864..6c418bcede 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -55,7 +55,7 @@ mod setup { "--no_freeze_flags_after_init --expose_gc --harmony-import-assertions --harmony-shadow-realm --allow_natives_syntax --turbo_fast_api_calls", ); v8::V8::initialize_platform( - v8::new_default_platform(0, false).make_shared(), + v8::new_unprotected_default_platform(0, false).make_shared(), ); v8::V8::initialize(); }); diff --git a/tests/test_api_entropy_source.rs b/tests/test_api_entropy_source.rs index 3611e4f010..e8aa329d0f 100644 --- a/tests/test_api_entropy_source.rs +++ b/tests/test_api_entropy_source.rs @@ -18,7 +18,9 @@ fn set_entropy_source() { true }); - v8::V8::initialize_platform(v8::new_default_platform(0, false).make_shared()); + v8::V8::initialize_platform( + v8::new_unprotected_default_platform(0, false).make_shared(), + ); v8::V8::initialize(); // Assumes that every isolate creates a PRNG from scratch, which is currently true. diff --git a/tests/test_api_flags.rs b/tests/test_api_flags.rs index 713b58c268..5ee6a2b4c3 100644 --- a/tests/test_api_flags.rs +++ b/tests/test_api_flags.rs @@ -4,7 +4,9 @@ #[test] fn set_flags_from_string() { v8::V8::set_flags_from_string("--use_strict"); - v8::V8::initialize_platform(v8::new_default_platform(0, false).make_shared()); + v8::V8::initialize_platform( + v8::new_unprotected_default_platform(0, false).make_shared(), + ); v8::V8::initialize(); let isolate = &mut v8::Isolate::new(Default::default()); let scope = &mut v8::HandleScope::new(isolate); diff --git a/tests/test_platform_atomics_pump_message_loop.rs b/tests/test_platform_atomics_pump_message_loop.rs index 8c1c55994d..76fa5275f6 100644 --- a/tests/test_platform_atomics_pump_message_loop.rs +++ b/tests/test_platform_atomics_pump_message_loop.rs @@ -3,7 +3,9 @@ fn atomics_pump_message_loop() { v8::V8::set_flags_from_string( "--allow-natives-syntax --harmony-sharedarraybuffer", ); - v8::V8::initialize_platform(v8::new_default_platform(0, false).make_shared()); + v8::V8::initialize_platform( + v8::new_unprotected_default_platform(0, false).make_shared(), + ); v8::V8::initialize(); let isolate = &mut v8::Isolate::new(Default::default()); let scope = &mut v8::HandleScope::new(isolate); From f147f0250dfa0bf8244f0ef026a95657a0216c29 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Wed, 13 Sep 2023 01:30:24 +0200 Subject: [PATCH 53/70] Rolling to V8 11.8.172.3 (#1317) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1d0a91f0d5..7286264142 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.8.172.1 +V8 Version: 11.8.172.3 [![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) diff --git a/v8 b/v8 index 15a8016f9e..71b061db7c 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 15a8016f9e4e93296958c0709a1dd944068c68f1 +Subproject commit 71b061db7c222b7972d90e3fa1be010d95c6b2cc From 0f0697039ebfa6c1e8fc2a6db5d7d76063d658fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 13 Sep 2023 16:40:57 +0200 Subject: [PATCH 54/70] v0.76.0 (#1319) --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5a0a5615d..391e844edd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1183,7 +1183,7 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "v8" -version = "0.75.1" +version = "0.76.0" dependencies = [ "align-data", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index d8c6e327e9..8a1edd71fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.75.1" +version = "0.76.0" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From b2a7cfe0c2a094b974c628cbd8d51ff2d3f0a250 Mon Sep 17 00:00:00 2001 From: Laurence Rowe Date: Mon, 18 Sep 2023 16:48:13 -0700 Subject: [PATCH 55/70] fix(Symbol): deprecate `for_global` in favour of `for_key` and `for_api` (#1324) `for_global` was documented as `for_key` but implemented as `for_api`. Closes #1323 --- src/symbol.rs | 36 ++++++++++++++++++++++++++++++++++++ tests/test_api.rs | 14 ++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/symbol.rs b/src/symbol.rs index 42e0da83ee..a118092fed 100644 --- a/src/symbol.rs +++ b/src/symbol.rs @@ -10,6 +10,10 @@ extern "C" { isolate: *mut Isolate, description: *const String, ) -> *const Symbol; + fn v8__Symbol__For( + isolate: *mut Isolate, + description: *const String, + ) -> *const Symbol; fn v8__Symbol__ForApi( isolate: *mut Isolate, description: *const String, @@ -58,6 +62,38 @@ impl Symbol { /// To minimize the potential for clashes, use qualified descriptions as keys. /// Corresponds to v8::Symbol::For() in C++. #[inline(always)] + pub fn for_key<'s>( + scope: &mut HandleScope<'s, ()>, + description: Local, + ) -> Local<'s, Symbol> { + unsafe { + scope + .cast_local(|sd| v8__Symbol__For(sd.get_isolate_ptr(), &*description)) + } + .unwrap() + } + + /// Retrieve a global symbol. Similar to `for_key`, but using a separate + /// registry that is not accessible by (and cannot clash with) JavaScript code. + /// Corresponds to v8::Symbol::ForApi() in C++. + #[inline(always)] + pub fn for_api<'s>( + scope: &mut HandleScope<'s, ()>, + description: Local, + ) -> Local<'s, Symbol> { + unsafe { + scope.cast_local(|sd| { + v8__Symbol__ForApi(sd.get_isolate_ptr(), &*description) + }) + } + .unwrap() + } + + #[deprecated( + since = "0.77.0", + note = "This was documented as `for_key` but implemented as `for_api`" + )] + #[inline(always)] pub fn for_global<'s>( scope: &mut HandleScope<'s, ()>, description: Local, diff --git a/tests/test_api.rs b/tests/test_api.rs index 6c418bcede..804ae2af52 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -7374,14 +7374,24 @@ fn symbol() { let s = v8::Symbol::new(scope, Some(desc)); assert!(s.description(scope) == desc); - let s_pub = v8::Symbol::for_global(scope, desc); + let s_pub = v8::Symbol::for_key(scope, desc); assert!(s_pub.description(scope) == desc); assert!(s_pub != s); - let s_pub2 = v8::Symbol::for_global(scope, desc); + let s_pub2 = v8::Symbol::for_key(scope, desc); assert!(s_pub2 != s); assert!(s_pub == s_pub2); + let s_api = v8::Symbol::for_api(scope, desc); + assert!(s_api.description(scope) == desc); + assert!(s_api != s); + assert!(s_api != s_pub); + + let s_api2 = v8::Symbol::for_api(scope, desc); + assert!(s_api2 != s); + assert!(s_api2 != s_pub); + assert!(s_api == s_api2); + let context = v8::Context::new(scope); let scope = &mut v8::ContextScope::new(scope, context); From 35578c8580cfd63b7148bf0a39407e2cda1be8b9 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Wed, 20 Sep 2023 08:37:10 -0600 Subject: [PATCH 56/70] fix: never create a null slice (#1326) --- src/fast_api.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/fast_api.rs b/src/fast_api.rs index 8dfb28d580..1eb432f991 100644 --- a/src/fast_api.rs +++ b/src/fast_api.rs @@ -228,6 +228,12 @@ pub struct FastApiOneByteString { impl FastApiOneByteString { #[inline(always)] pub fn as_bytes(&self) -> &[u8] { + // Ensure that we never create a null-ptr slice (even a zero-length null-ptr slice + // is invalid because of Rust's niche packing). + if self.data.is_null() { + return &mut []; + } + // 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) } } @@ -236,14 +242,37 @@ impl FastApiOneByteString { impl FastApiTypedArray { /// Performs an unaligned-safe read of T from the underlying data. #[inline(always)] - pub fn get(&self, index: usize) -> T { + pub const fn get(&self, index: usize) -> T { debug_assert!(index < self.length); // SAFETY: src is valid for reads, and is a valid value for T unsafe { ptr::read_unaligned(self.data.add(index)) } } + /// Given a pointer to a `FastApiTypedArray`, returns a slice pointing to the + /// data if safe to do so. + /// + /// # Safety + /// + /// The pointer must not be null and the caller must choose a lifetime that is + /// safe. + #[inline(always)] + pub unsafe fn get_storage_from_pointer_if_aligned<'a>( + ptr: *mut Self, + ) -> Option<&'a mut [T]> { + debug_assert!(!ptr.is_null()); + let self_ref = ptr.as_mut().unwrap_unchecked(); + self_ref.get_storage_if_aligned() + } + + /// Returns a slace pointing to the underlying data if safe to do so. #[inline(always)] pub fn get_storage_if_aligned(&self) -> Option<&mut [T]> { + // Ensure that we never create a null-ptr slice (even a zero-length null-ptr slice + // is invalid because of Rust's niche packing). + if self.data.is_null() { + return Some(&mut []); + } + // Ensure that we never return an unaligned buffer if (self.data as usize) % align_of::() != 0 { return None; } From 8f282fa04b0dce179f74244862e078a50479cb5e Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Wed, 20 Sep 2023 11:56:59 -0600 Subject: [PATCH 57/70] chore: typo (#1327) --- src/fast_api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fast_api.rs b/src/fast_api.rs index 1eb432f991..961145f846 100644 --- a/src/fast_api.rs +++ b/src/fast_api.rs @@ -264,7 +264,7 @@ impl FastApiTypedArray { self_ref.get_storage_if_aligned() } - /// Returns a slace pointing to the underlying data if safe to do so. + /// Returns a slice pointing to the underlying data if safe to do so. #[inline(always)] pub fn get_storage_if_aligned(&self) -> Option<&mut [T]> { // Ensure that we never create a null-ptr slice (even a zero-length null-ptr slice From 55cc17a6b7c7db77f231b15c8368919636ce5052 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Thu, 21 Sep 2023 02:19:03 -0400 Subject: [PATCH 58/70] Rolling to V8 11.8.172.6 (#1320) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7286264142..d77707534b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.8.172.3 +V8 Version: 11.8.172.6 [![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) diff --git a/v8 b/v8 index 71b061db7c..6dccdd60aa 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 71b061db7c222b7972d90e3fa1be010d95c6b2cc +Subproject commit 6dccdd60aac64dc962c39cf6d45ff4799c3d9c04 From 97fab5ce0fd51e1697b09205817d20bc2da5994b Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 21 Sep 2023 09:00:21 +0200 Subject: [PATCH 59/70] v0.77.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 391e844edd..e0dd9c5170 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1183,7 +1183,7 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "v8" -version = "0.76.0" +version = "0.77.0" dependencies = [ "align-data", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index 8a1edd71fd..e3f53f7eaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.76.0" +version = "0.77.0" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From bb5dadb4187ac63ba39eeaa3b90d529d79501e8b Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Fri, 22 Sep 2023 11:34:30 -0600 Subject: [PATCH 60/70] fix: better fix for empty Uint8Array (#1329) --- src/fast_api.rs | 10 ++++---- tests/test_api.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/src/fast_api.rs b/src/fast_api.rs index 961145f846..96a0a9e1f8 100644 --- a/src/fast_api.rs +++ b/src/fast_api.rs @@ -267,13 +267,13 @@ impl FastApiTypedArray { /// Returns a slice pointing to the underlying data if safe to do so. #[inline(always)] pub fn get_storage_if_aligned(&self) -> Option<&mut [T]> { - // Ensure that we never create a null-ptr slice (even a zero-length null-ptr slice - // is invalid because of Rust's niche packing). - if self.data.is_null() { + // 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. + if self.length == 0 { return Some(&mut []); } - // Ensure that we never return an unaligned buffer - if (self.data as usize) % align_of::() != 0 { + // Ensure that we never return an unaligned or null buffer + if self.data.is_null() || (self.data as usize) % align_of::() != 0 { return None; } Some(unsafe { std::slice::from_raw_parts_mut(self.data, self.length) }) diff --git a/tests/test_api.rs b/tests/test_api.rs index 804ae2af52..6b37ad15c3 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -15,8 +15,8 @@ use std::ptr::{addr_of, NonNull}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use std::sync::Mutex; -use v8::fast_api::CType; use v8::fast_api::Type::*; +use v8::fast_api::{CType, FastApiTypedArray}; use v8::inspector::ChannelBase; use v8::{fast_api, AccessorConfiguration}; @@ -9566,6 +9566,64 @@ fn test_fast_calls() { assert_eq!("fast", unsafe { WHO }); } +#[test] +fn test_fast_calls_empty_buffer() { + static mut WHO: &str = "none"; + unsafe fn fast_fn( + _recv: v8::Local, + buffer: *mut FastApiTypedArray, + ) { + assert_eq!(WHO, "slow"); + WHO = "fast"; + assert_eq!( + 0, + FastApiTypedArray::get_storage_from_pointer_if_aligned(buffer) + .unwrap() + .len() + ); + } + + fn slow_fn( + _scope: &mut v8::HandleScope, + _args: v8::FunctionCallbackArguments, + _rv: v8::ReturnValue, + ) { + unsafe { + WHO = "slow"; + } + } + + const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new( + &[V8Value, TypedArray(CType::Uint8)], + fast_api::CType::Void, + fast_fn as _, + ); + + 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); + 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, None, None, None); + + 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(arr) { func(arr); } + %PrepareFunctionForOptimization(f); + f(new Uint8Array(0)); + %OptimizeFunctionOnNextCall(f); + f(new Uint8Array(0)); + "#; + eval(scope, source).unwrap(); + assert_eq!(unsafe { WHO }, "fast"); +} + #[test] fn test_fast_calls_sequence() { static mut WHO: &str = "none"; From 768e5988312b71c69681894225fb984e0b334e4b Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Fri, 22 Sep 2023 11:40:55 -0600 Subject: [PATCH 61/70] 0.78.0 (#1330) --- Cargo.lock | 724 ++++++++++++++++++++++++++++++++++------------------- Cargo.toml | 2 +- 2 files changed, 465 insertions(+), 261 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0dd9c5170..dcca202b71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ "memchr", ] @@ -48,9 +48,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "ash" @@ -58,20 +58,29 @@ version = "0.33.3+1.2.191" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc4f1d82f164f838ae413296d1131aa6fa79b917d25bebaa7033d25620c09219" dependencies = [ - "libloading", + "libloading 0.7.4", ] [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "basic-toml" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bfc506e7a2370ec239e1d072507b2a80c833083699d3c6fa176fbb4de8448c6" +dependencies = [ + "serde", +] [[package]] name = "bit-set" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ "bit-vec", ] @@ -88,6 +97,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "block" version = "0.1.6" @@ -96,15 +111,15 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytemuck" -version = "1.7.3" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" [[package]] name = "byteorder" @@ -119,14 +134,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf2eec61efe56aa1e813f5126959296933cf0700030e4314786c48779a66ab82" dependencies = [ "log", - "nix", + "nix 0.22.3", ] [[package]] name = "cc" -version = "1.0.72" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -148,14 +166,14 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "cocoa" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "block", "cocoa-foundation", - "core-foundation 0.9.2", + "core-foundation 0.9.3", "core-graphics 0.22.3", "foreign-types", "libc", @@ -164,15 +182,14 @@ dependencies = [ [[package]] name = "cocoa-foundation" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" dependencies = [ - "bitflags", + "bitflags 1.3.2", "block", - "core-foundation 0.9.2", + "core-foundation 0.9.3", "core-graphics-types", - "foreign-types", "libc", "objc", ] @@ -205,11 +222,11 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ - "core-foundation-sys 0.8.3", + "core-foundation-sys 0.8.4", "libc", ] @@ -221,9 +238,9 @@ checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "core-graphics" @@ -231,7 +248,7 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation 0.7.0", "foreign-types", "libc", @@ -243,8 +260,8 @@ version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ - "bitflags", - "core-foundation 0.9.2", + "bitflags 1.3.2", + "core-foundation 0.9.3", "core-graphics-types", "foreign-types", "libc", @@ -252,13 +269,12 @@ dependencies = [ [[package]] name = "core-graphics-types" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" dependencies = [ - "bitflags", - "core-foundation 0.9.2", - "foreign-types", + "bitflags 1.3.2", + "core-foundation 0.9.3", "libc", ] @@ -287,16 +303,16 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2daefd788d1e96e0a9d66dee4b828b883509bc3ea9ce30665f04c3246372690c" dependencies = [ - "bitflags", - "libloading", + "bitflags 1.3.2", + "libloading 0.7.4", "winapi", ] [[package]] name = "darling" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ "darling_core", "darling_macro", @@ -304,27 +320,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn", + "syn 1.0.109", ] [[package]] name = "darling_macro" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -335,11 +351,11 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] name = "dlib" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading", + "libloading 0.8.0", ] [[package]] @@ -350,9 +366,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "either" -version = "1.6.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "env_logger" @@ -364,6 +380,33 @@ dependencies = [ "regex", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fnv" version = "1.0.7" @@ -417,9 +460,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.4" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if 1.0.0", "libc", @@ -428,9 +471,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "glow" @@ -446,11 +489,11 @@ dependencies = [ [[package]] name = "gpu-alloc" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e64cbb8d36508d3e19da95e56e196a84f674fc190881f2cc010000798838aa6" +checksum = "22beaafc29b38204457ea030f6fb7a84c9e4dd1b86e311ba0542533453d87f62" dependencies = [ - "bitflags", + "bitflags 1.3.2", "gpu-alloc-types", ] @@ -460,18 +503,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "gpu-descriptor" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a538f217be4d405ff4719a283ca68323cc2384003eca5baaa87501e821c81dda" +checksum = "0b0c02e1ba0bdb14e965058ca34e09c020f8e507a760df1121728e0aef68d57a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "gpu-descriptor-types", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -480,24 +523,39 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "hexf-parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -506,19 +564,29 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "indexmap" -version = "1.8.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", ] [[package]] name = "inplace_it" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90953f308a79fe6d62a4643e51f848fbfddcd05975a38e69fdf4ab86a7baf7ca" +checksum = "e567468c50f3d4bc7397702e09b380139f9b9288b4e909b070571007f8b5bf78" [[package]] name = "instant" @@ -534,9 +602,9 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jni-sys" @@ -546,9 +614,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.55" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -560,7 +628,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" dependencies = [ "libc", - "libloading", + "libloading 0.7.4", ] [[package]] @@ -571,37 +639,51 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "libloading" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ "cfg-if 1.0.0", "winapi", ] +[[package]] +name = "libloading" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" +dependencies = [ + "cfg-if 1.0.0", + "windows-sys", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" + [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "malloc_buf" @@ -614,9 +696,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.1" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memmap2" @@ -642,7 +724,7 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0514f491f4cc03632ab399ee01e2c1c1b12d3e1cf2d667c1ff5f87d6dcd2084" dependencies = [ - "bitflags", + "bitflags 1.3.2", "block", "core-graphics-types", "foreign-types", @@ -658,24 +740,14 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "0.8.0" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba272f85fa0b41fc91872be579b3bbe0f56b792aa361a380eb669469f68dafb2" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", + "wasi", + "windows-sys", ] [[package]] @@ -685,11 +757,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "806f448a7ce662ca79ef5484ef8f451a9b7c51b8166c95f5a667228b3825a6ca" dependencies = [ "bit-set", - "bitflags", + "bitflags 1.3.2", "codespan-reporting", "fxhash", "hexf-parse", - "indexmap", + "indexmap 1.9.3", "log", "num-traits", "spirv", @@ -714,24 +786,31 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d868f654c72e75f8687572699cdabe755f03effbb62542768e995d5b8d699d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "jni-sys", "ndk-sys", "num_enum", "thiserror", ] +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + [[package]] name = "ndk-glue" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc291b8de2095cba8dab7cf381bf582ff4c17a09acf854c32e46545b08085d28" +checksum = "c71bee8ea72d685477e28bd004cfe1bf99c754d688cd78cad139eae4089484d4" dependencies = [ "android_logger", "lazy_static", "libc", "log", "ndk 0.5.0", + "ndk-context", "ndk-macro", "ndk-sys", ] @@ -746,7 +825,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -761,7 +840,7 @@ version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cc", "cfg-if 1.0.0", "libc", @@ -769,53 +848,55 @@ dependencies = [ ] [[package]] -name = "nom" -version = "7.1.0" +name = "nix" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ - "memchr", - "minimal-lexical", - "version_check", + "bitflags 1.3.2", + "cfg-if 1.0.0", + "libc", + "memoffset", ] [[package]] -name = "ntapi" -version = "0.3.6" +name = "nom" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ - "winapi", + "memchr", + "minimal-lexical", ] [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] [[package]] name = "num_enum" -version = "0.5.6" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.6" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -839,9 +920,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "parking_lot" @@ -856,9 +937,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ "cfg-if 1.0.0", "instant", @@ -870,9 +951,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pixels" @@ -890,9 +971,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "pollster" @@ -902,43 +983,43 @@ checksum = "5da3b0203fd7ee5720aa0b5e790b591aa5d3f41c3ed2c34a3a393382198af2f7" [[package]] name = "proc-macro-crate" -version = "1.1.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ - "thiserror", - "toml", + "once_cell", + "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "profiling" -version = "1.0.5" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9145ac0af1d93c638c98c40cf7d25665f427b2a44ad0a99b1dccf3e2f25bb987" +checksum = "f89dff0959d98c9758c88826cc002e2c3d0b9dfac4139711d1f30de442f1139b" [[package]] name = "quote" -version = "1.0.9" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "range-alloc" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6" +checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" [[package]] name = "raw-window-handle" @@ -947,32 +1028,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e28f55143d0548dad60bb4fbdc835a3d7ac6acc3324506450c5fdd6e42903a76" dependencies = [ "libc", - "raw-window-handle 0.4.2", + "raw-window-handle 0.4.3", ] [[package]] name = "raw-window-handle" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba75eee94a9d5273a68c9e1e105d9cffe1ef700532325788389e5a83e2522b7" +checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" dependencies = [ "cty", ] [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.5.6" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", @@ -981,9 +1074,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.26" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "renderdoc-sys" @@ -991,11 +1084,24 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" +[[package]] +name = "rustix" +version = "0.38.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "safe_arch" @@ -1008,38 +1114,41 @@ dependencies = [ [[package]] name = "scoped-tls" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.125" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.37", ] [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -1057,23 +1166,23 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.8.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smithay-client-toolkit" -version = "0.15.3" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1325f292209cee78d5035530932422a30aa4c8fda1a16593ac083c1de211e68a" +checksum = "8a28f16a97fa0e8ce563b2774d1e732dd5d4025d2772c5dba0a41a0f90a29da3" dependencies = [ - "bitflags", + "bitflags 1.3.2", "calloop", "dlib", "lazy_static", "log", "memmap2", - "nix", + "nix 0.22.3", "pkg-config", "wayland-client", "wayland-cursor", @@ -1086,7 +1195,7 @@ version = "0.2.0+1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" dependencies = [ - "bitflags", + "bitflags 1.3.2", "num-traits", ] @@ -1098,66 +1207,85 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.69" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] name = "termcolor" -version = "1.1.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.37", ] [[package]] -name = "toml" -version = "0.5.8" +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" + +[[package]] +name = "toml_edit" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "serde", + "indexmap 2.0.0", + "toml_datetime", + "winnow", ] [[package]] name = "trybuild" -version = "1.0.61" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc92f558afb6d1d7c6f175eb8d615b8ef49c227543e68e19c123d4ee43d8a7d" +checksum = "196a58260a906cedb9bf6d8034b6379d0c11f552416960452f267402ceeddff1" dependencies = [ + "basic-toml", "glob", "once_cell", "serde", "serde_derive", "serde_json", "termcolor", - "toml", ] [[package]] @@ -1170,23 +1298,23 @@ dependencies = [ ] [[package]] -name = "unicode-width" -version = "0.1.9" +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "unicode-xid" -version = "0.2.1" +name = "unicode-width" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "v8" -version = "0.77.0" +version = "0.78.0" dependencies = [ "align-data", - "bitflags", + "bitflags 1.3.2", "fslock", "once_cell", "trybuild", @@ -1201,15 +1329,15 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" -version = "0.10.3+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a2e384a3f170b0c7543787a91411175b71afd56ba4d3a0ae5678d4e2243c0e" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.78" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -1217,24 +1345,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.78" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.37", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.28" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -1244,9 +1372,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.78" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1254,33 +1382,33 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.78" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.37", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.78" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wayland-client" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91223460e73257f697d9e23d401279123d36039a3f7a449e983f123292d4458f" +checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" dependencies = [ - "bitflags", + "bitflags 1.3.2", "downcast-rs", "libc", - "nix", + "nix 0.24.3", "scoped-tls", "wayland-commons", "wayland-scanner", @@ -1289,11 +1417,11 @@ dependencies = [ [[package]] name = "wayland-commons" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f6e5e340d7c13490eca867898c4cec5af56c27a5ffe5c80c6fc4708e22d33e" +checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" dependencies = [ - "nix", + "nix 0.24.3", "once_cell", "smallvec", "wayland-sys", @@ -1301,22 +1429,22 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c52758f13d5e7861fc83d942d3d99bf270c83269575e52ac29e5b73cb956a6bd" +checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" dependencies = [ - "nix", + "nix 0.24.3", "wayland-client", "xcursor", ] [[package]] name = "wayland-protocols" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60147ae23303402e41fe034f74fb2c35ad0780ee88a1c40ac09a3be1e7465741" +checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" dependencies = [ - "bitflags", + "bitflags 1.3.2", "wayland-client", "wayland-commons", "wayland-scanner", @@ -1324,9 +1452,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a1ed3143f7a143187156a2ab52742e89dac33245ba505c17224df48939f9e0" +checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" dependencies = [ "proc-macro2", "quote", @@ -1335,9 +1463,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9341df79a8975679188e37dab3889bfa57c44ac2cb6da166f519a81cbe452d4" +checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" dependencies = [ "dlib", "lazy_static", @@ -1346,9 +1474,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.55" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" dependencies = [ "js-sys", "wasm-bindgen", @@ -1381,7 +1509,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35600627b6c718ad0e23ed75fb6140bfe32cdf21c8f539ce3c9ab8180e2cb38e" dependencies = [ "arrayvec", - "bitflags", + "bitflags 1.3.2", "cfg_aliases", "copyless", "fxhash", @@ -1405,7 +1533,7 @@ dependencies = [ "arrayvec", "ash", "bit-set", - "bitflags", + "bitflags 1.3.2", "block", "core-graphics-types", "d3d12", @@ -1417,7 +1545,7 @@ dependencies = [ "inplace_it", "js-sys", "khronos-egl", - "libloading", + "libloading 0.7.4", "log", "metal", "naga", @@ -1440,18 +1568,19 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e15e44ba88ec415466e18e91881319e7c9e96cb905dc623305168aea65b85ccc" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "which" -version = "4.2.5" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "lazy_static", - "libc", + "home", + "once_cell", + "rustix", ] [[package]] @@ -1482,9 +1611,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -1495,15 +1624,81 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "winit" version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b43cc931d58b99461188607efd7acb2a093e65fc621f54cad78517a6063e73a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cocoa", - "core-foundation 0.9.2", + "core-foundation 0.9.3", "core-graphics 0.22.3", "core-video-sys", "dispatch", @@ -1518,7 +1713,7 @@ dependencies = [ "objc", "parking_lot", "percent-encoding", - "raw-window-handle 0.4.2", + "raw-window-handle 0.4.3", "smithay-client-toolkit", "wasm-bindgen", "wayland-client", @@ -1528,14 +1723,23 @@ dependencies = [ "x11-dl", ] +[[package]] +name = "winnow" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +dependencies = [ + "memchr", +] + [[package]] name = "x11-dl" -version = "2.19.1" +version = "2.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" dependencies = [ - "lazy_static", "libc", + "once_cell", "pkg-config", ] @@ -1550,6 +1754,6 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.4" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" +checksum = "bab77e97b50aee93da431f2cee7cd0f43b4d1da3c408042f2d7d164187774f0a" diff --git a/Cargo.toml b/Cargo.toml index e3f53f7eaa..72823d52cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.77.0" +version = "0.78.0" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From 12dca0cf0379f69a52bd710a4a64bf5efe9bcdc0 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Fri, 29 Sep 2023 18:20:29 -0600 Subject: [PATCH 62/70] feat: add scope-less data() access on ArrayBufferView (#1338) --- src/array_buffer_view.rs | 14 ++++++++++++++ src/binding.cc | 5 +++++ tests/test_api.rs | 18 ++++++++++++++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/array_buffer_view.rs b/src/array_buffer_view.rs index d81dcabe5b..fac10e43bf 100644 --- a/src/array_buffer_view.rs +++ b/src/array_buffer_view.rs @@ -11,6 +11,9 @@ extern "C" { fn v8__ArrayBufferView__Buffer( this: *const ArrayBufferView, ) -> *const ArrayBuffer; + fn v8__ArrayBufferView__Buffer__Data( + this: *const ArrayBufferView, + ) -> *mut c_void; fn v8__ArrayBufferView__ByteLength(this: *const ArrayBufferView) -> usize; fn v8__ArrayBufferView__ByteOffset(this: *const ArrayBufferView) -> usize; fn v8__ArrayBufferView__CopyContents( @@ -30,6 +33,17 @@ impl ArrayBufferView { unsafe { scope.cast_local(|_| v8__ArrayBufferView__Buffer(self)) } } + /// Returns the underlying storage for this `ArrayBufferView`, including the built-in `byte_offset`. + /// This is a more efficient way of calling `buffer(scope)->data()`, and may be called without a + /// scope. + #[inline(always)] + pub fn data(&self) -> *mut c_void { + unsafe { + v8__ArrayBufferView__Buffer__Data(self) + .add(v8__ArrayBufferView__ByteOffset(self)) + } + } + /// Size of a view in bytes. #[inline(always)] pub fn byte_length(&self) -> usize { diff --git a/src/binding.cc b/src/binding.cc index 6dab984650..dd8ccacabd 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -1657,6 +1657,11 @@ const v8::ArrayBuffer* v8__ArrayBufferView__Buffer( return local_to_ptr(ptr_to_local(&self)->Buffer()); } +const void* v8__ArrayBufferView__Buffer__Data( + const v8::ArrayBufferView& self) { + return ptr_to_local(&self)->Buffer()->Data(); +} + size_t v8__ArrayBufferView__ByteLength(const v8::ArrayBufferView& self) { return ptr_to_local(&self)->ByteLength(); } diff --git a/tests/test_api.rs b/tests/test_api.rs index 6b37ad15c3..577442aba3 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -5022,22 +5022,32 @@ fn array_buffer_view() { let scope = &mut v8::HandleScope::new(isolate); let context = v8::Context::new(scope); let scope = &mut v8::ContextScope::new(scope, context); - let source = - v8::String::new(scope, "new Uint8Array([23,23,23,23])").unwrap(); + let source = v8::String::new( + scope, + "new Uint8Array(new Uint8Array([22,22,23,23,23,23]).buffer, 2, 4)", + ) + .unwrap(); let script = v8::Script::compile(scope, source, None).unwrap(); source.to_rust_string_lossy(scope); let result: v8::Local = script.run(scope).unwrap().try_into().unwrap(); assert_eq!(result.byte_length(), 4); - assert_eq!(result.byte_offset(), 0); + assert_eq!(result.byte_offset(), 2); let mut dest = [0; 4]; let copy_bytes = result.copy_contents(&mut dest); assert_eq!(copy_bytes, 4); assert_eq!(dest, [23, 23, 23, 23]); + let slice = unsafe { + std::slice::from_raw_parts( + result.data() as *const u8, + result.byte_length(), + ) + }; + assert_eq!(dest, slice); let maybe_ab = result.buffer(scope); assert!(maybe_ab.is_some()); let ab = maybe_ab.unwrap(); - assert_eq!(ab.byte_length(), 4); + assert_eq!(ab.byte_length(), 6); } } From bf277f4f8e90c221bdb82f2cf19f20166665de78 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Mon, 2 Oct 2023 12:08:51 -0600 Subject: [PATCH 63/70] feat: new_backing_store_from_bytes and empty for ArrayBuffer and SharedArrayBuffer (#1334) --- Cargo.lock | 7 ++ Cargo.toml | 1 + src/array_buffer.rs | 143 +++++++++++++++++++++++++++---------- src/binding.cc | 6 ++ src/shared_array_buffer.rs | 114 ++++++++++++++++++++++------- tests/test_api.rs | 23 ++++++ 6 files changed, 230 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dcca202b71..d43d4d8e77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,6 +127,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + [[package]] name = "calloop" version = "0.9.3" @@ -1315,6 +1321,7 @@ version = "0.78.0" dependencies = [ "align-data", "bitflags 1.3.2", + "bytes", "fslock", "once_cell", "trybuild", diff --git a/Cargo.toml b/Cargo.toml index 72823d52cd..016f9f6b67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,6 +88,7 @@ fslock = "0.1.8" which = "4.2.5" [dev-dependencies] +bytes = "1" align-data = "0.1.0" fslock = "0.1.8" trybuild = "1.0.61" diff --git a/src/array_buffer.rs b/src/array_buffer.rs index 523ea45dc6..a7dff16cea 100644 --- a/src/array_buffer.rs +++ b/src/array_buffer.rs @@ -5,7 +5,6 @@ use std::ffi::c_void; use std::ops::Deref; use std::ptr; use std::ptr::null; -use std::ptr::null_mut; use std::ptr::NonNull; use std::slice; @@ -60,6 +59,7 @@ extern "C" { deleter: BackingStoreDeleterCallback, deleter_data: *mut c_void, ) -> *mut BackingStore; + fn v8__BackingStore__EmptyBackingStore(shared: bool) -> *mut BackingStore; fn v8__BackingStore__Data(this: *const BackingStore) -> *mut c_void; fn v8__BackingStore__ByteLength(this: *const BackingStore) -> usize; @@ -246,25 +246,50 @@ pub type BackingStoreDeleterCallback = unsafe extern "C" fn( deleter_data: *mut c_void, ); -pub unsafe extern "C" fn boxed_slice_deleter_callback( - data: *mut c_void, - byte_length: usize, - _deleter_data: *mut c_void, -) { - let slice_ptr = ptr::slice_from_raw_parts_mut(data as *mut u8, byte_length); - let b = Box::from_raw(slice_ptr); - drop(b); +pub(crate) mod sealed { + pub trait Rawable { + fn into_raw(self) -> *const (); + unsafe fn drop_raw(ptr: *const (), size: usize); + } } -pub unsafe extern "C" fn vec_deleter_callback( - data: *mut c_void, - byte_length: usize, - deleter_data: *mut c_void, -) { - let capacity = deleter_data as usize; - drop(Vec::from_raw_parts(data as *mut u8, byte_length, capacity)) +impl sealed::Rawable<[u8]> for Vec { + unsafe fn drop_raw(ptr: *const (), size: usize) { + as sealed::Rawable<[u8]>>::drop_raw(ptr, size); + } + + fn into_raw(self) -> *const () { + self.into_boxed_slice().into_raw() + } } +macro_rules! rawable { + ($container:ident) => { + impl sealed::Rawable for $container { + fn into_raw(self) -> *const () { + Self::into_raw(self) as _ + } + + unsafe fn drop_raw(ptr: *const (), _len: usize) { + _ = Self::from_raw(ptr as _); + } + } + + impl sealed::Rawable<[u8]> for $container<[u8]> { + fn into_raw(self) -> *const () { + Self::into_raw(self) as _ + } + + unsafe fn drop_raw(ptr: *const (), len: usize) { + _ = Self::from_raw(ptr::slice_from_raw_parts_mut(ptr as _, len)); + } + } + }; +} + +// Implement Rawable for single-ownership container types +rawable!(Box); + /// A wrapper around the backing store (i.e. the raw memory) of an array buffer. /// See a document linked in http://crbug.com/v8/9908 for more information. /// @@ -396,6 +421,16 @@ impl ArrayBuffer { .unwrap() } + /// Create a new, empty ArrayBuffer. + #[inline(always)] + pub fn empty<'s>(scope: &mut HandleScope<'s>) -> Local<'s, ArrayBuffer> { + // SAFETY: This is a v8-provided empty backing store + let backing_store = unsafe { + UniqueRef::from_raw(v8__BackingStore__EmptyBackingStore(false)) + }; + Self::with_backing_store(scope, &backing_store.make_shared()) + } + /// Data length in bytes. #[inline(always)] pub fn byte_length(&self) -> usize { @@ -489,16 +524,7 @@ impl ArrayBuffer { pub fn new_backing_store_from_boxed_slice( data: Box<[u8]>, ) -> UniqueRef { - let byte_length = data.len(); - let data_ptr = Box::into_raw(data) as *mut c_void; - unsafe { - UniqueRef::from_raw(v8__ArrayBuffer__NewBackingStore__with_data( - data_ptr, - byte_length, - boxed_slice_deleter_callback, - null_mut(), - )) - } + Self::new_backing_store_from_bytes(data) } /// Returns a new standalone BackingStore that takes over the ownership of @@ -509,20 +535,59 @@ impl ArrayBuffer { /// The result can be later passed to ArrayBuffer::New. The raw pointer /// to the buffer must not be passed again to any V8 API function. #[inline(always)] - pub fn new_backing_store_from_vec( - mut data: Vec, - ) -> UniqueRef { - let byte_length = data.len(); - let capacity = data.capacity(); - let data_ptr = data.as_mut_ptr() as *mut c_void; - std::mem::forget(data); + pub fn new_backing_store_from_vec(data: Vec) -> UniqueRef { + Self::new_backing_store_from_bytes(data) + } + + /// Returns a new standalone BackingStore backed by a container that dereferences + /// to a mutable slice of bytes. The object is dereferenced once, and the resulting slice's + /// memory is used for the lifetime of the buffer. + /// + /// This method may be called with most single-ownership containers that implement `AsMut<[u8]>`, including + /// `Box<[u8]>`, and `Vec`. This will also support most other mutable bytes containers (including `bytes::BytesMut`), + /// though these buffers will need to be boxed to manage ownership of memory. + /// + /// ``` + /// // Vector of bytes + /// let backing_store = v8::ArrayBuffer::new_backing_store_from_bytes(vec![1, 2, 3]); + /// // Boxes slice of bytes + /// let boxed_slice: Box<[u8]> = vec![1, 2, 3].into_boxed_slice(); + /// let backing_store = v8::ArrayBuffer::new_backing_store_from_bytes(boxed_slice); + /// // BytesMut from bytes crate + /// let backing_store = v8::ArrayBuffer::new_backing_store_from_bytes(Box::new(bytes::BytesMut::new())); + /// ``` + #[inline(always)] + pub fn new_backing_store_from_bytes( + mut bytes: T, + ) -> UniqueRef + where + U: ?Sized, + U: AsMut<[u8]>, + T: AsMut, + T: sealed::Rawable, + { + let len = bytes.as_mut().as_mut().len(); + let slice = bytes.as_mut().as_mut().as_mut_ptr(); + let ptr = T::into_raw(bytes); + + extern "C" fn drop_rawable, U: ?Sized>( + _ptr: *mut c_void, + len: usize, + data: *mut c_void, + ) { + // SAFETY: We know that data is a raw T from above + unsafe { >::drop_raw(data as _, len) } + } + + // SAFETY: We are extending the lifetime of a slice, but we're locking away the box that we + // derefed from so there's no way to get another mutable reference. unsafe { - UniqueRef::from_raw(v8__ArrayBuffer__NewBackingStore__with_data( - data_ptr, - byte_length, - vec_deleter_callback, - capacity as *mut c_void, - )) + Self::new_backing_store_from_ptr( + slice as _, + len, + drop_rawable::, + ptr as _, + ) } } diff --git a/src/binding.cc b/src/binding.cc index dd8ccacabd..ed4e778b96 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -866,6 +866,12 @@ two_pointers_t v8__ArrayBuffer__GetBackingStore(const v8::ArrayBuffer& self) { return make_pod(ptr_to_local(&self)->GetBackingStore()); } +v8::BackingStore* v8__BackingStore__EmptyBackingStore(bool shared) { + std::unique_ptr u = + i::BackingStore::EmptyBackingStore(shared ? i::SharedFlag::kShared : i::SharedFlag::kNotShared); + return static_cast(u.release()); +} + bool v8__BackingStore__IsResizableByUserJavaScript( const v8::BackingStore& self) { return ptr_to_local(&self)->IsResizableByUserJavaScript(); diff --git a/src/shared_array_buffer.rs b/src/shared_array_buffer.rs index 0259adc3e6..d414c5ed33 100644 --- a/src/shared_array_buffer.rs +++ b/src/shared_array_buffer.rs @@ -1,10 +1,7 @@ // Copyright 2019-2021 the Deno authors. All rights reserved. MIT license. use std::ffi::c_void; -use std::ptr::null_mut; -use crate::array_buffer::boxed_slice_deleter_callback; -use crate::array_buffer::vec_deleter_callback; use crate::support::SharedRef; use crate::support::UniqueRef; use crate::BackingStore; @@ -38,6 +35,7 @@ extern "C" { deleter: BackingStoreDeleterCallback, deleter_data: *mut c_void, ) -> *mut BackingStore; + fn v8__BackingStore__EmptyBackingStore(shared: bool) -> *mut BackingStore; } impl SharedArrayBuffer { @@ -76,6 +74,17 @@ impl SharedArrayBuffer { .unwrap() } + /// Create a new, empty SharedArrayBuffer. + #[inline(always)] + pub fn empty<'s>( + scope: &mut HandleScope<'s>, + ) -> Local<'s, SharedArrayBuffer> { + // SAFETY: This is a v8-provided empty backing store + let backing_store = + unsafe { UniqueRef::from_raw(v8__BackingStore__EmptyBackingStore(true)) }; + Self::with_backing_store(scope, &backing_store.make_shared()) + } + /// Data length in bytes. #[inline(always)] pub fn byte_length(&self) -> usize { @@ -124,16 +133,7 @@ impl SharedArrayBuffer { pub fn new_backing_store_from_boxed_slice( data: Box<[u8]>, ) -> UniqueRef { - let byte_length = data.len(); - let data_ptr = Box::into_raw(data) as *mut c_void; - unsafe { - UniqueRef::from_raw(v8__SharedArrayBuffer__NewBackingStore__with_data( - data_ptr, - byte_length, - boxed_slice_deleter_callback, - null_mut(), - )) - } + Self::new_backing_store_from_bytes(data) } /// Returns a new standalone BackingStore that takes over the ownership of @@ -144,19 +144,83 @@ impl SharedArrayBuffer { /// The result can be later passed to SharedArrayBuffer::New. The raw pointer /// to the buffer must not be passed again to any V8 API function. #[inline(always)] - pub fn new_backing_store_from_vec( - mut data: Vec, - ) -> UniqueRef { - let byte_length = data.len(); - let data_ptr = data.as_mut_ptr() as *mut c_void; - std::mem::forget(data); + pub fn new_backing_store_from_vec(data: Vec) -> UniqueRef { + Self::new_backing_store_from_bytes(data) + } + + /// Returns a new standalone BackingStore backed by a container that dereferences + /// to a mutable slice of bytes. The object is dereferenced once, and the resulting slice's + /// memory is used for the lifetime of the buffer. + /// + /// This method may be called with most single-ownership containers that implement `AsMut<[u8]>`, including + /// `Box<[u8]>`, and `Vec`. This will also support most other mutable bytes containers (including `bytes::BytesMut`), + /// though these buffers will need to be boxed to manage ownership of memory. + /// + /// ``` + /// // Vector of bytes + /// let backing_store = v8::ArrayBuffer::new_backing_store_from_bytes(vec![1, 2, 3]); + /// // Boxes slice of bytes + /// let boxed_slice: Box<[u8]> = vec![1, 2, 3].into_boxed_slice(); + /// let backing_store = v8::ArrayBuffer::new_backing_store_from_bytes(boxed_slice); + /// // BytesMut from bytes crate + /// let backing_store = v8::ArrayBuffer::new_backing_store_from_bytes(Box::new(bytes::BytesMut::new())); + /// ``` + #[inline(always)] + pub fn new_backing_store_from_bytes( + mut bytes: T, + ) -> UniqueRef + where + U: ?Sized, + U: AsMut<[u8]>, + T: AsMut, + T: crate::array_buffer::sealed::Rawable, + { + let len = bytes.as_mut().as_mut().len(); + let slice = bytes.as_mut().as_mut().as_mut_ptr(); + let ptr = T::into_raw(bytes); + + extern "C" fn drop_rawable< + T: crate::array_buffer::sealed::Rawable, + U: ?Sized, + >( + _ptr: *mut c_void, + len: usize, + data: *mut c_void, + ) { + // SAFETY: We know that data is a raw T from above + unsafe { + >::drop_raw(data as _, len) + } + } + + // SAFETY: We are extending the lifetime of a slice, but we're locking away the box that we + // derefed from so there's no way to get another mutable reference. unsafe { - UniqueRef::from_raw(v8__SharedArrayBuffer__NewBackingStore__with_data( - data_ptr, - byte_length, - vec_deleter_callback, - null_mut(), - )) + Self::new_backing_store_from_ptr( + slice as _, + len, + drop_rawable::, + ptr as _, + ) } } + + /// Returns a new standalone shared BackingStore backed by given ptr. + /// + /// SAFETY: This API consumes raw pointers so is inherently + /// unsafe. Usually you should use new_backing_store_from_boxed_slice. + #[inline(always)] + pub unsafe fn new_backing_store_from_ptr( + data_ptr: *mut c_void, + byte_length: usize, + deleter_callback: BackingStoreDeleterCallback, + deleter_data: *mut c_void, + ) -> UniqueRef { + UniqueRef::from_raw(v8__SharedArrayBuffer__NewBackingStore__with_data( + data_ptr, + byte_length, + deleter_callback, + deleter_data, + )) + } } diff --git a/tests/test_api.rs b/tests/test_api.rs index 577442aba3..491a9fc7c2 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -828,6 +828,24 @@ fn array_buffer() { assert_eq!(10, shared_bs_2.byte_length()); assert_eq!(shared_bs_2[0].get(), 0); assert_eq!(shared_bs_2[9].get(), 9); + + // Empty + let ab = v8::ArrayBuffer::empty(scope); + assert_eq!(0, ab.byte_length()); + assert!(!ab.get_backing_store().is_shared()); + + // From a bytes::BytesMut + let mut data = bytes::BytesMut::new(); + data.extend_from_slice(&[0; 16]); + data[0] = 1; + let unique_bs = + v8::ArrayBuffer::new_backing_store_from_bytes(Box::new(data)); + assert_eq!(unique_bs.get(0).unwrap().get(), 1); + + let ab = + v8::ArrayBuffer::with_backing_store(scope, &unique_bs.make_shared()); + assert_eq!(ab.byte_length(), 16); + assert_eq!(ab.get_backing_store().get(0).unwrap().get(), 1); } } @@ -5607,6 +5625,11 @@ fn shared_array_buffer() { assert_eq!(shared_bs_3.byte_length(), 10); assert_eq!(shared_bs_3[0].get(), 0); assert_eq!(shared_bs_3[9].get(), 9); + + // Empty + let ab = v8::SharedArrayBuffer::empty(scope); + assert_eq!(ab.byte_length(), 0); + assert!(ab.get_backing_store().is_shared()); } } From 088c9989297594264701c9034b74e29c4f0e691c Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Mon, 2 Oct 2023 12:40:46 -0600 Subject: [PATCH 64/70] 0.79.0 (#1339) --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d43d4d8e77..1f1a3808ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1317,7 +1317,7 @@ checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "v8" -version = "0.78.0" +version = "0.79.0" dependencies = [ "align-data", "bitflags 1.3.2", diff --git a/Cargo.toml b/Cargo.toml index 016f9f6b67..ec76c58f2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.78.0" +version = "0.79.0" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From efca1408f64aa734daf24ef42f8307c9d8bdb168 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Tue, 3 Oct 2023 09:17:18 -0600 Subject: [PATCH 65/70] fix: arraybuffer init from vec was broken if vec reallocated to box (#1341) --- src/array_buffer.rs | 60 +++++++++++++++++++++----------------- src/shared_array_buffer.rs | 9 ++++-- tests/test_api.rs | 30 ++++++++++++++++++- 3 files changed, 69 insertions(+), 30 deletions(-) diff --git a/src/array_buffer.rs b/src/array_buffer.rs index a7dff16cea..6baa64e362 100644 --- a/src/array_buffer.rs +++ b/src/array_buffer.rs @@ -3,7 +3,6 @@ use std::cell::Cell; use std::ffi::c_void; use std::ops::Deref; -use std::ptr; use std::ptr::null; use std::ptr::NonNull; use std::slice; @@ -248,7 +247,7 @@ pub type BackingStoreDeleterCallback = unsafe extern "C" fn( pub(crate) mod sealed { pub trait Rawable { - fn into_raw(self) -> *const (); + fn into_raw(self) -> (*const (), *const u8); unsafe fn drop_raw(ptr: *const (), size: usize); } } @@ -258,38 +257,40 @@ impl sealed::Rawable<[u8]> for Vec { as sealed::Rawable<[u8]>>::drop_raw(ptr, size); } - fn into_raw(self) -> *const () { + fn into_raw(self) -> (*const (), *const u8) { self.into_boxed_slice().into_raw() } } -macro_rules! rawable { - ($container:ident) => { - impl sealed::Rawable for $container { - fn into_raw(self) -> *const () { - Self::into_raw(self) as _ - } +impl sealed::Rawable for Box +where + T: AsMut<[u8]>, +{ + fn into_raw(mut self) -> (*const (), *const u8) { + let data = self.as_mut().as_mut().as_mut_ptr(); + let ptr = Self::into_raw(self); + (ptr as _, data) + } - unsafe fn drop_raw(ptr: *const (), _len: usize) { - _ = Self::from_raw(ptr as _); - } - } + unsafe fn drop_raw(ptr: *const (), _len: usize) { + _ = Self::from_raw(ptr as _); + } +} - impl sealed::Rawable<[u8]> for $container<[u8]> { - fn into_raw(self) -> *const () { - Self::into_raw(self) as _ - } +impl sealed::Rawable<[u8]> for Box<[u8]> { + fn into_raw(mut self) -> (*const (), *const u8) { + // Thin the fat pointer + let ptr = self.as_mut_ptr(); + std::mem::forget(self); + (ptr as _, ptr) + } - unsafe fn drop_raw(ptr: *const (), len: usize) { - _ = Self::from_raw(ptr::slice_from_raw_parts_mut(ptr as _, len)); - } - } - }; + unsafe fn drop_raw(ptr: *const (), len: usize) { + // Fatten the thin pointer + _ = Self::from_raw(std::ptr::slice_from_raw_parts_mut(ptr as _, len)); + } } -// Implement Rawable for single-ownership container types -rawable!(Box); - /// A wrapper around the backing store (i.e. the raw memory) of an array buffer. /// See a document linked in http://crbug.com/v8/9908 for more information. /// @@ -567,8 +568,13 @@ impl ArrayBuffer { T: sealed::Rawable, { let len = bytes.as_mut().as_mut().len(); - let slice = bytes.as_mut().as_mut().as_mut_ptr(); - let ptr = T::into_raw(bytes); + if len == 0 { + return unsafe { + UniqueRef::from_raw(v8__BackingStore__EmptyBackingStore(false)) + }; + } + + let (ptr, slice) = T::into_raw(bytes); extern "C" fn drop_rawable, U: ?Sized>( _ptr: *mut c_void, diff --git a/src/shared_array_buffer.rs b/src/shared_array_buffer.rs index d414c5ed33..17f26dbfc4 100644 --- a/src/shared_array_buffer.rs +++ b/src/shared_array_buffer.rs @@ -176,8 +176,13 @@ impl SharedArrayBuffer { T: crate::array_buffer::sealed::Rawable, { let len = bytes.as_mut().as_mut().len(); - let slice = bytes.as_mut().as_mut().as_mut_ptr(); - let ptr = T::into_raw(bytes); + if len == 0 { + return unsafe { + UniqueRef::from_raw(v8__BackingStore__EmptyBackingStore(false)) + }; + } + + let (ptr, slice) = T::into_raw(bytes); extern "C" fn drop_rawable< T: crate::array_buffer::sealed::Rawable, diff --git a/tests/test_api.rs b/tests/test_api.rs index 491a9fc7c2..84fc6c80c5 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -834,13 +834,41 @@ fn array_buffer() { assert_eq!(0, ab.byte_length()); assert!(!ab.get_backing_store().is_shared()); + // Empty but from vec + let ab = v8::ArrayBuffer::with_backing_store( + scope, + &v8::ArrayBuffer::new_backing_store_from_bytes(vec![]).make_shared(), + ); + assert_eq!(0, ab.byte_length()); + assert!(!ab.get_backing_store().is_shared()); + + // Empty but from vec with a huge capacity + let mut v = Vec::with_capacity(10_000_000); + v.extend_from_slice(&[1, 2, 3, 4]); + let ab = v8::ArrayBuffer::with_backing_store( + scope, + &v8::ArrayBuffer::new_backing_store_from_bytes(v).make_shared(), + ); + // Allocate a completely unused buffer overtop of the old allocation + let mut v2: Vec = Vec::with_capacity(10_000_000); + v2.extend_from_slice(&[10, 20, 30, 40]); + // Make sure the the arraybuffer didn't get stomped + assert_eq!(4, ab.byte_length()); + assert_eq!(1, ab.get_backing_store()[0].get()); + assert_eq!(2, ab.get_backing_store()[1].get()); + assert_eq!(3, ab.get_backing_store()[2].get()); + assert_eq!(4, ab.get_backing_store()[3].get()); + assert!(!ab.get_backing_store().is_shared()); + drop(v2); + // From a bytes::BytesMut let mut data = bytes::BytesMut::new(); - data.extend_from_slice(&[0; 16]); + data.extend_from_slice(&[100; 16]); data[0] = 1; let unique_bs = v8::ArrayBuffer::new_backing_store_from_bytes(Box::new(data)); assert_eq!(unique_bs.get(0).unwrap().get(), 1); + assert_eq!(unique_bs.get(15).unwrap().get(), 100); let ab = v8::ArrayBuffer::with_backing_store(scope, &unique_bs.make_shared()); From da5ca4f2d15409620b7bdeababe96de254f36be8 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Tue, 3 Oct 2023 09:23:59 -0600 Subject: [PATCH 66/70] feat: add get_backing_store to ArrayBufferView (#1342) --- src/array_buffer_view.rs | 12 ++++++++++++ tests/test_api.rs | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/array_buffer_view.rs b/src/array_buffer_view.rs index fac10e43bf..88c4d3ffc3 100644 --- a/src/array_buffer_view.rs +++ b/src/array_buffer_view.rs @@ -4,8 +4,10 @@ use std::ffi::c_void; use crate::support::int; use crate::ArrayBuffer; use crate::ArrayBufferView; +use crate::BackingStore; use crate::HandleScope; use crate::Local; +use crate::SharedRef; extern "C" { fn v8__ArrayBufferView__Buffer( @@ -33,6 +35,16 @@ impl ArrayBufferView { unsafe { scope.cast_local(|_| v8__ArrayBufferView__Buffer(self)) } } + /// Get a shared pointer to the backing store of this array buffer. This + /// pointer coordinates the lifetime management of the internal storage + /// with any live ArrayBuffers on the heap, even across isolates. The embedder + /// should not attempt to manage lifetime of the storage through other means. + #[inline(always)] + pub fn get_backing_store(&self) -> Option> { + let buffer = unsafe { v8__ArrayBufferView__Buffer(self) }; + unsafe { buffer.as_ref().map(|buffer| buffer.get_backing_store()) } + } + /// Returns the underlying storage for this `ArrayBufferView`, including the built-in `byte_offset`. /// This is a more efficient way of calling `buffer(scope)->data()`, and may be called without a /// scope. diff --git a/tests/test_api.rs b/tests/test_api.rs index 84fc6c80c5..d21a4009ad 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -5094,6 +5094,10 @@ fn array_buffer_view() { assert!(maybe_ab.is_some()); let ab = maybe_ab.unwrap(); assert_eq!(ab.byte_length(), 6); + assert_eq!( + result.get_backing_store().unwrap().data(), + ab.get_backing_store().data() + ); } } From 547e7ca86865552d14354e3407bda515e8d03151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Tue, 3 Oct 2023 18:24:45 +0200 Subject: [PATCH 67/70] v0.79.1 (#1343) --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f1a3808ca..0f8dedadcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1317,7 +1317,7 @@ checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "v8" -version = "0.79.0" +version = "0.79.1" dependencies = [ "align-data", "bitflags 1.3.2", diff --git a/Cargo.toml b/Cargo.toml index ec76c58f2c..5c62bd6795 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.79.0" +version = "0.79.1" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"] From 09a6fdea3c01687e950c3b84569bf0d047bb5260 Mon Sep 17 00:00:00 2001 From: denobot <33910674+denobot@users.noreply.github.com> Date: Fri, 6 Oct 2023 13:31:09 -0400 Subject: [PATCH 68/70] Rolling to V8 11.8.172.13 (#1335) --- README.md | 2 +- v8 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d77707534b..e014f7d872 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Rusty V8 Binding -V8 Version: 11.8.172.6 +V8 Version: 11.8.172.13 [![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) diff --git a/v8 b/v8 index 6dccdd60aa..69fd0491ac 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 6dccdd60aac64dc962c39cf6d45ff4799c3d9c04 +Subproject commit 69fd0491aca048782ce6267cc366ddb8ab470b01 From cdfb89e8a70585bedda5da9defc27574ae322585 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Sat, 7 Oct 2023 21:34:11 +0530 Subject: [PATCH 69/70] Add test for `--expose-deno-builtins` (#1344) --- tests/test_api.rs | 19 ++++++++++++++++++- v8 | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/test_api.rs b/tests/test_api.rs index d21a4009ad..c2ca246ba0 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -52,7 +52,7 @@ mod setup { )) .is_ok()); v8::V8::set_flags_from_string( - "--no_freeze_flags_after_init --expose_gc --harmony-import-assertions --harmony-shadow-realm --allow_natives_syntax --turbo_fast_api_calls", + "--no_freeze_flags_after_init --expose_deno_builtins --expose_gc --harmony-import-assertions --harmony-shadow-realm --allow_natives_syntax --turbo_fast_api_calls", ); v8::V8::initialize_platform( v8::new_unprotected_default_platform(0, false).make_shared(), @@ -10901,3 +10901,20 @@ fn allow_scope_in_read_host_object() { let value = deserializer.read_value(context).unwrap(); assert!(value.is_object()); } + +#[test] +fn has_deno_builtins() { + 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); + let scope = &mut v8::ContextScope::new(scope, context); + + for builtin_name in &["fromUtf8", "toUtf8", "isOneByte"] { + let name = v8::String::new(scope, builtin_name).unwrap(); + let value = context.global(scope).get(scope, name.into()).unwrap(); + assert!(value.is_function()); + } +} diff --git a/v8 b/v8 index 69fd0491ac..99232750c0 160000 --- a/v8 +++ b/v8 @@ -1 +1 @@ -Subproject commit 69fd0491aca048782ce6267cc366ddb8ab470b01 +Subproject commit 99232750c02ebf21013c72ffaec0f0d7c3bfb964 From ba5d0870dbd6342a6b4586e63ad9229c9248581d Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Sat, 7 Oct 2023 22:08:16 +0530 Subject: [PATCH 70/70] v0.79.2 (#1345) --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f8dedadcc..3d58c869a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1317,7 +1317,7 @@ checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "v8" -version = "0.79.1" +version = "0.79.2" dependencies = [ "align-data", "bitflags 1.3.2", diff --git a/Cargo.toml b/Cargo.toml index 5c62bd6795..68c19f7339 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v8" -version = "0.79.1" +version = "0.79.2" description = "Rust bindings to V8" readme = "README.md" authors = ["the Deno authors"]