/
githubmirror
/
servo
Обзор
Документация
Войти
/
githubmirror
/
servo
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
components/script_bindings/wrap.rs
141 строка
5 KB
Sam
script: Stop using an unforgeable holder for global objects with unforgeable properties (#46930)
02 авг 2026, 16:54
Не верифицирован
02 авг 2026, 16:54
aaacc0e
Код
Авторство
О чём код?
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::ffi::c_void; use std::ptr; use js::JSCLASS_IS_GLOBAL; use js::context::JSContext; use js::gc::{HandleObject, MutableHandleObject}; use js::glue::SetProxyReservedSlot; use js::jsapi::{JS_SetReservedSlot, JSAutoRealm, JSClass, JSObject}; use js::jsval::{PrivateValue, UndefinedValue}; use js::rust::wrappers2::{ JS_InitializePropertiesFromCompatibleNativeObject, JS_NewObjectWithGivenProto, JS_WrapObject, NewProxyObject, }; use js::rust::{Handle, get_context_realm, get_object_class, get_object_realm}; use crate::codegen::PrototypeList; use crate::conversions::DOM_OBJECT_SLOT; use crate::import::module::JS_GetReservedSlot; use crate::proxyhandler::ensure_expando_object; use crate::root::{DomRoot, MaybeUnreflectedDom, Root}; use crate::utils::DOM_PROTO_UNFORGEABLE_HOLDER_SLOT; use crate::{DomObject, DomTypes, MutDomObject}; type ProtoObjectFn = fn(&mut js::context::JSContext, HandleObject, MutableHandleObject); /// TODO: unforgeable is missing pub(crate) struct WrapConfig { pub(crate) is_maybe_cross_origin_object: bool, pub(crate) is_proxy: bool, pub(crate) proxy_handler: Option<*const c_void>, pub(crate) prototype_id: PrototypeList::ID, pub(crate) class: Option<&'static JSClass>, // this function has to be more general because we do not have the correct type for globalscope. pub(crate) proto_object_fn: ProtoObjectFn, pub(crate) has_legacy_unforgeable_members: bool, } #[cfg_attr(crown, allow(crown::unrooted_must_root))] pub(crate) unsafe fn wrap<T: MutDomObject, D: DomTypes>( cx: &mut JSContext, scope: &D::GlobalScope, given_proto: Option<js::rust::Handle<*mut JSObject>>, raw: Root<MaybeUnreflectedDom<T>>, config: WrapConfig, ) -> DomRoot<T> { unsafe { let scope = scope.reflector().get_jsobject(); assert!(!scope.get().is_null()); assert!(((*get_object_class(scope.get())).flags & JSCLASS_IS_GLOBAL) != 0); let _ac = JSAutoRealm::new(cx.raw_cx(), scope.get()); rooted!(&in(cx) let mut canonical_proto = ptr::null_mut::<JSObject>()); (config.proto_object_fn)(cx, scope, canonical_proto.handle_mut()); assert!(!canonical_proto.is_null()); rooted!(&in(cx) let mut obj = ptr::null_mut::<JSObject>()); if config.is_proxy { let handler: *const libc::c_void = config.proxy_handler.unwrap(); if config.is_maybe_cross_origin_object { obj.set(NewProxyObject( cx, handler, Handle::undefined(), ptr::null_mut(), ptr::null(), true, )); } else { obj.set(NewProxyObject( cx, handler, Handle::undefined(), canonical_proto.get(), ptr::null(), false, )); }; assert!(!obj.is_null()); SetProxyReservedSlot( obj.get(), 0, &PrivateValue(raw.as_ptr() as *const libc::c_void), ); } else { rooted!(&in(cx) let mut proto = ptr::null_mut::<JSObject>()); if let Some(given) = given_proto { proto.set(*given); if get_context_realm(cx.raw_cx()) != get_object_realm(*given) { assert!(JS_WrapObject(cx, proto.handle_mut())); } } else { proto.set(*canonical_proto); } obj.set(JS_NewObjectWithGivenProto( cx, config.class.unwrap(), proto.handle(), )); assert!(!obj.is_null()); JS_SetReservedSlot( obj.get(), DOM_OBJECT_SLOT, &PrivateValue(raw.as_ptr() as *const libc::c_void), ); }; let root = raw.reflect_with(obj.get()); root.reflector().set_proto_id(config.prototype_id as u16); // From here on we copy the legacy unforgeable properties to instance which was originally in a different function. if config.has_legacy_unforgeable_members { rooted!(&in(cx) let mut expando = ptr::null_mut::<JSObject>()); if config.is_proxy { ensure_expando_object(cx, obj.handle(), expando.handle_mut()); } let copy_fn = JS_InitializePropertiesFromCompatibleNativeObject; let mut slot = UndefinedValue(); JS_GetReservedSlot( canonical_proto.get(), DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, &mut slot, ); rooted!(&in(cx) let mut unforgeable_holder = ptr::null_mut::<JSObject>()); unforgeable_holder.handle_mut().set(slot.to_object()); if config.is_proxy { assert!(copy_fn(cx, expando.handle(), unforgeable_holder.handle())); } else { assert!(copy_fn(cx, obj.handle(), unforgeable_holder.handle())); } } DomRoot::from_ref(&*root) } }