diff --git a/vendor/v8-152.2.0/src/context.rs b/vendor/v8-152.2.0/src/context.rs index 308cab9f39..1f4b3d37b9 100644 --- a/vendor/v8-152.2.0/src/context.rs +++ b/vendor/v8-152.2.0/src/context.rs @@ -28,6 +28,7 @@ unsafe extern "C" { ) -> *const Context; fn v8__Isolate__GetCurrent() -> *mut RealIsolate; fn v8__Context__Global(this: *const Context) -> *const Object; + fn v8__Context__DetachGlobal(this: *const Context); fn v8__Context__GetExtrasBindingObject(this: *const Context) -> *const Object; fn v8__Context__GetNumberOfEmbedderDataFields(this: *const Context) -> u32; @@ -143,6 +144,13 @@ impl Context { unsafe { scope.cast_local(|_| v8__Context__Global(self)) }.unwrap() } + /// Detaches this context's global proxy so its identity can be reused by a + /// subsequently created context. + #[inline(always)] + pub fn detach_global(&self) { + unsafe { v8__Context__DetachGlobal(self) } + } + /// Returns the microtask queue associated with this context. /// /// Returns `None` if the context has no microtask queue, which is the case diff --git a/vendor/v8-152.2.0/src/context_ext.cc b/vendor/v8-152.2.0/src/context_ext.cc new file mode 100644 index 0000000000..abd9df5735 --- /dev/null +++ b/vendor/v8-152.2.0/src/context_ext.cc @@ -0,0 +1,40 @@ +// Copyright 2026 the Moli authors. MIT license. + +#include "support.h" +#include "v8-context.h" +#include "v8-isolate.h" + +using namespace support; + +static_assert(sizeof(v8::Context::BackupIncumbentScope) == + sizeof(size_t) * 3, + "BackupIncumbentScope size mismatch"); + +extern "C" { + +void v8__Context__BackupIncumbentScope__CONSTRUCT( + uninit_t* buf, + const v8::Context& context) { + construct_in_place(buf, + ptr_to_local(&context)); +} + +void v8__Context__BackupIncumbentScope__DESTRUCT( + v8::Context::BackupIncumbentScope* self) { + self->~BackupIncumbentScope(); +} + +void v8__Context__DetachGlobal(const v8::Context& self) { + ptr_to_local(&self)->DetachGlobal(); +} + +const v8::Context* v8__Isolate__GetIncumbentContext(v8::Isolate* isolate) { + return local_to_ptr(isolate->GetIncumbentContext()); +} + +void v8__Isolate__SetFailedAccessCheckCallbackFunction( + v8::Isolate* isolate, v8::FailedAccessCheckCallback callback) { + isolate->SetFailedAccessCheckCallbackFunction(callback); +} + +} // extern "C" diff --git a/vendor/v8-152.2.0/src/isolate.rs b/vendor/v8-152.2.0/src/isolate.rs index 0832f9b1cb..ce2ef77e90 100644 --- a/vendor/v8-152.2.0/src/isolate.rs +++ b/vendor/v8-152.2.0/src/isolate.rs @@ -82,10 +82,23 @@ use std::sync::atomic::AtomicUsize; #[repr(C)] pub enum MicrotasksPolicy { Explicit = 0, - // Scoped = 1 (RAII) is omitted for now, doesn't quite map to idiomatic Rust. + Scoped = 1, Auto = 2, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(C)] +pub enum AccessType { + Get, + Set, + Has, + Delete, + Keys, +} + +pub type FailedAccessCheckCallback = + unsafe extern "C" fn(Local, AccessType, Local); + /// Memory pressure level for the MemoryPressureNotification. /// None hints V8 that there is no memory pressure. /// Moderate hints V8 to speed up incremental garbage collection at the cost @@ -819,6 +832,10 @@ unsafe extern "C" { isolate: *mut RealIsolate, callback: RawModifyCodeGenerationFromStringsCallback, ); + fn v8__Isolate__SetFailedAccessCheckCallbackFunction( + isolate: *mut RealIsolate, + callback: FailedAccessCheckCallback, + ); fn v8__Isolate__RequestInterrupt( isolate: *const RealIsolate, callback: InterruptCallback, @@ -905,6 +922,21 @@ impl UnsafeRawIsolatePtr { pub struct RealIsolate(Opaque); impl Isolate { + /// Installs the callback invoked when an object access check fails and no + /// failed-access interceptor handles the operation. + #[inline(always)] + pub fn set_failed_access_check_callback_function( + &mut self, + callback: FailedAccessCheckCallback, + ) { + unsafe { + v8__Isolate__SetFailedAccessCheckCallbackFunction( + self.as_real_ptr(), + callback, + ) + } + } + pub(crate) fn as_real_ptr(&self) -> *mut RealIsolate { self.0.as_ptr() } diff --git a/vendor/v8-152.2.0/src/lib.rs b/vendor/v8-152.2.0/src/lib.rs index d32db0fd54..49eef1337d 100644 --- a/vendor/v8-152.2.0/src/lib.rs +++ b/vendor/v8-152.2.0/src/lib.rs @@ -109,6 +109,8 @@ pub use handle::SealedLocal; pub use handle::TracedReference; pub use handle::Weak; pub use isolate::GarbageCollectionType; +pub use isolate::AccessType; +pub use isolate::FailedAccessCheckCallback; pub use isolate::HeapCodeStatistics; pub use isolate::HeapSpaceStatistics; pub use isolate::HeapStatistics; @@ -162,6 +164,7 @@ pub use property_filter::*; pub use property_handler_flags::*; pub use regexp::RegExpCreationFlags; pub use scope::AllowJavascriptExecutionScope; +pub use scope::BackupIncumbentScope; // pub use scope::CallbackScope; pub use scope::CallbackScope; pub use scope::ContextScope; diff --git a/vendor/v8-152.2.0/src/scope.rs b/vendor/v8-152.2.0/src/scope.rs index e53a7a65d3..20279a52e8 100644 --- a/vendor/v8-152.2.0/src/scope.rs +++ b/vendor/v8-152.2.0/src/scope.rs @@ -340,6 +340,12 @@ mod get_isolate_impls { } } + impl GetIsolate for Local<'_, Object> { + fn get_isolate_ptr(&self) -> *mut RealIsolate { + unsafe { raw::v8__Isolate__GetCurrent() } + } + } + impl GetIsolate for Local<'_, Message> { fn get_isolate_ptr(&self) -> *mut RealIsolate { unsafe { raw::v8__Isolate__GetCurrent() } @@ -563,6 +569,15 @@ impl<'s> PinnedRef<'s, HandleScope<'_>> { unsafe { Local::from_raw_unchecked(context_ptr) } } + /// Returns the context corresponding to the incumbent Realm in the HTML + /// specification. + pub fn get_incumbent_context(&self) -> Option> { + let context_ptr = unsafe { + raw::v8__Isolate__GetIncumbentContext(self.0.isolate.as_ptr()) + }; + unsafe { Local::from_raw(context_ptr) } + } + /// Return data that was previously attached to the isolate snapshot via /// SnapshotCreator, and removes the reference to it. If called again with /// same `index` argument, this function returns `DataError::NoData`. @@ -789,6 +804,42 @@ impl DerefMut for ContextScope<'_, '_, P> { impl sealed::Sealed for ContextScope<'_, '_, P> {} impl Scope for ContextScope<'_, '_, P> {} +/// Pushes a context onto V8's backup incumbent settings object stack. +/// +/// V8 links this object into an isolate-owned stack by its address. Pin the +/// returned `ScopeStorage` before calling `init()` and keep it alive until the +/// callback invocation completes. +pub struct BackupIncumbentScope<'s> { + raw: raw::BackupIncumbentScope, + context: Local<'s, Context>, + _pinned: PhantomPinned, +} + +impl<'s> BackupIncumbentScope<'s> { + pub fn new(context: Local<'s, Context>) -> ScopeStorage { + ScopeStorage::new(Self { + raw: unsafe { raw::BackupIncumbentScope::uninit() }, + context, + _pinned: PhantomPinned, + }) + } +} + +impl ScopeInit for BackupIncumbentScope<'_> { + fn init_stack(storage: Pin<&mut ScopeStorage>) -> Pin<&mut Self> { + let storage_mut = unsafe { storage.get_unchecked_mut() }; + let context = storage_mut.scope.context; + unsafe { + storage_mut.scope.raw.init(context); + Pin::new_unchecked(&mut storage_mut.scope) + } + } + + unsafe fn deinit(me: &mut Self) { + unsafe { me.raw.deinit() }; + } +} + mod new_context_scope { use super::{GetIsolate, Scope}; diff --git a/vendor/v8-152.2.0/src/scope/raw.rs b/vendor/v8-152.2.0/src/scope/raw.rs index 4e443c2704..84e7d26dba 100644 --- a/vendor/v8-152.2.0/src/scope/raw.rs +++ b/vendor/v8-152.2.0/src/scope/raw.rs @@ -36,6 +36,36 @@ impl Drop for ContextScope { } } +#[repr(C)] +#[derive(Debug)] +pub(super) struct BackupIncumbentScope([MaybeUninit; 3]); + +impl BackupIncumbentScope { + /// Creates uninitialized storage for V8's stack-address-sensitive scope. + /// + /// The returned value must be pinned before `init()` constructs the C++ + /// object in place. + pub unsafe fn uninit() -> Self { + Self(unsafe { MaybeUninit::uninit().assume_init() }) + } + + /// # Safety + /// + /// `self` must be pinned at its final address and initialized exactly once. + pub unsafe fn init(&mut self, context: Local) { + unsafe { + v8__Context__BackupIncumbentScope__CONSTRUCT(self, &*context); + } + } + + /// # Safety + /// + /// `self` must have been initialized by `init()` and must not have moved. + pub unsafe fn deinit(&mut self) { + unsafe { v8__Context__BackupIncumbentScope__DESTRUCT(self) }; + } +} + #[cfg(feature = "v8_enable_v8_checks")] pub const HANDLE_SCOPE_SIZE: usize = 4; #[cfg(not(feature = "v8_enable_v8_checks"))] @@ -227,6 +257,9 @@ unsafe extern "C" { pub(super) fn v8__Isolate__GetEnteredOrMicrotaskContext( isolate: *mut RealIsolate, ) -> *const Context; + pub(super) fn v8__Isolate__GetIncumbentContext( + isolate: *mut RealIsolate, + ) -> *const Context; pub(super) fn v8__Isolate__ThrowException( isolate: *mut RealIsolate, exception: *const Value, @@ -241,6 +274,13 @@ unsafe extern "C" { pub(super) fn v8__Context__Enter(this: *const Context); pub(super) fn v8__Context__Exit(this: *const Context); + pub(super) fn v8__Context__BackupIncumbentScope__CONSTRUCT( + buf: *mut BackupIncumbentScope, + context: *const Context, + ); + pub(super) fn v8__Context__BackupIncumbentScope__DESTRUCT( + this: *mut BackupIncumbentScope, + ); pub(super) fn v8__Context__GetDataFromSnapshotOnce( this: *const Context, index: usize,