aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authoryvt <i@yvt.jp>2021-07-13 23:08:23 +0900
committeryvt <i@yvt.jp>2021-07-13 23:08:23 +0900
commitf884506dfbced3daa115317de8090c99b9d3f34b (patch)
treed8b5b175a45d307c0255bdf20fb0d68b7be29f19 /components/script/dom
parentb77ee8721b9cede9acaa0a6064a36491ed9083f2 (diff)
downloadservo-f884506dfbced3daa115317de8090c99b9d3f34b.tar.gz
servo-f884506dfbced3daa115317de8090c99b9d3f34b.zip
refactor(script): auto ref-count `ServoJSPrincipals`
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/bindings/interface.rs2
-rw-r--r--components/script/dom/bindings/principals.rs96
2 files changed, 86 insertions, 12 deletions
diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs
index 2b4fcd67f3a..e22b897ac6e 100644
--- a/components/script/dom/bindings/interface.rs
+++ b/components/script/dom/bindings/interface.rs
@@ -155,7 +155,7 @@ pub unsafe fn create_global_object(
rval.set(JS_NewGlobalObject(
*cx,
class,
- principal.0,
+ principal.as_raw(),
OnNewGlobalHookOption::DontFireOnNewGlobalHook,
&*options,
));
diff --git a/components/script/dom/bindings/principals.rs b/components/script/dom/bindings/principals.rs
index 010fb28b39f..afaf02c74fe 100644
--- a/components/script/dom/bindings/principals.rs
+++ b/components/script/dom/bindings/principals.rs
@@ -1,23 +1,97 @@
-use js::glue::{
- CreateRustJSPrincipals, DestroyRustJSPrincipals, GetRustJSPrincipalsPrivate,
- JSPrincipalsCallbacks,
+use js::{
+ glue::{
+ CreateRustJSPrincipals, DestroyRustJSPrincipals, GetRustJSPrincipalsPrivate,
+ JSPrincipalsCallbacks,
+ },
+ jsapi::{JSPrincipals, JS_DropPrincipals, JS_HoldPrincipals},
+ rust::Runtime,
};
-use js::jsapi::JSPrincipals;
use servo_url::MutableOrigin;
+use std::{marker::PhantomData, ops::Deref, ptr::NonNull};
-// TODO: RAII ref-counting
-pub struct ServoJSPrincipals(pub *mut JSPrincipals);
+/// An owned reference to Servo's `JSPrincipals` instance.
+#[repr(transparent)]
+pub struct ServoJSPrincipals(NonNull<JSPrincipals>);
impl ServoJSPrincipals {
pub fn new(origin: &MutableOrigin) -> Self {
- let private: Box<MutableOrigin> = Box::new(origin.clone());
- Self(unsafe { CreateRustJSPrincipals(&PRINCIPALS_CALLBACKS, Box::into_raw(private) as _) })
+ unsafe {
+ let private: Box<MutableOrigin> = Box::new(origin.clone());
+ let raw = CreateRustJSPrincipals(&PRINCIPALS_CALLBACKS, Box::into_raw(private) as _);
+ // The created `JSPrincipals` object has an initial reference
+ // count of zero, so the following code will set it to one
+ Self::from_raw_nonnull(NonNull::new_unchecked(raw))
+ }
}
+ /// Construct `Self` from a raw `*mut JSPrincipals`, incrementing its
+ /// reference count.
+ #[inline]
+ pub unsafe fn from_raw_nonnull(raw: NonNull<JSPrincipals>) -> Self {
+ JS_HoldPrincipals(raw.as_ptr());
+ Self(raw)
+ }
+
+ #[inline]
pub unsafe fn origin(&self) -> MutableOrigin {
- let origin = GetRustJSPrincipalsPrivate(self.0) as *mut MutableOrigin;
+ let origin = GetRustJSPrincipalsPrivate(self.0.as_ptr()) as *mut MutableOrigin;
(*origin).clone()
}
+
+ #[inline]
+ pub fn as_raw_nonnull(&self) -> NonNull<JSPrincipals> {
+ self.0
+ }
+
+ #[inline]
+ pub fn as_raw(&self) -> *mut JSPrincipals {
+ self.0.as_ptr()
+ }
+}
+
+impl Clone for ServoJSPrincipals {
+ #[inline]
+ fn clone(&self) -> Self {
+ unsafe { Self::from_raw_nonnull(self.as_raw_nonnull()) }
+ }
+}
+
+impl Drop for ServoJSPrincipals {
+ #[inline]
+ fn drop(&mut self) {
+ unsafe { JS_DropPrincipals(Runtime::get(), self.as_raw()) };
+ }
+}
+
+/// A borrowed reference to Servo's `JSPrincipals` instance.
+#[derive(Clone, Copy)]
+pub struct ServoJSPrincipalsRef<'a>(NonNull<JSPrincipals>, PhantomData<&'a ()>);
+
+impl ServoJSPrincipalsRef<'_> {
+ /// Construct `Self` from a raw `NonNull<JSPrincipals>`.
+ #[inline]
+ pub unsafe fn from_raw_nonnull(raw: NonNull<JSPrincipals>) -> Self {
+ Self(raw, PhantomData)
+ }
+
+ /// Construct `Self` from a raw `*mut JSPrincipals`.
+ ///
+ /// # Safety
+ ///
+ /// The behavior is undefined if `raw` is null.
+ #[inline]
+ pub unsafe fn from_raw_unchecked(raw: *mut JSPrincipals) -> Self {
+ Self::from_raw_nonnull(NonNull::new_unchecked(raw))
+ }
+}
+
+impl Deref for ServoJSPrincipalsRef<'_> {
+ type Target = ServoJSPrincipals;
+
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*(&self.0 as *const NonNull<JSPrincipals> as *const ServoJSPrincipals) }
+ }
}
pub unsafe extern "C" fn destroy_servo_jsprincipal(principals: *mut JSPrincipals) {
@@ -36,8 +110,8 @@ unsafe extern "C" fn principals_is_system_or_addon_principal(_: *mut JSPrincipal
//TODO is same_origin_domain equivalent to subsumes for our purposes
pub unsafe extern "C" fn subsumes(obj: *mut JSPrincipals, other: *mut JSPrincipals) -> bool {
- let obj = ServoJSPrincipals(obj);
- let other = ServoJSPrincipals(other);
+ let obj = ServoJSPrincipalsRef::from_raw_unchecked(obj);
+ let other = ServoJSPrincipalsRef::from_raw_unchecked(other);
let obj_origin = obj.origin();
let other_origin = other.origin();
obj_origin.same_origin_domain(&other_origin)