mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
auto merge of #4526 : servo/servo/deref-1, r=Manishearth
This is a start towards fixing #3868. Not all callers have been fixed yet, so the `Deref` implementation remains for now.
This commit is contained in:
commit
141b5d038f
71 changed files with 592 additions and 568 deletions
|
@ -147,7 +147,7 @@ impl CallSetup {
|
|||
pub fn new<T: CallbackContainer>(callback: T, handling: ExceptionHandling) -> CallSetup {
|
||||
let global = global_object_for_js_object(callback.callback());
|
||||
let global = global.root();
|
||||
let cx = global.root_ref().get_cx();
|
||||
let cx = global.r().get_cx();
|
||||
CallSetup {
|
||||
cx: cx,
|
||||
_handling: handling
|
||||
|
|
|
@ -2199,7 +2199,7 @@ class CGCallGenerator(CGThing):
|
|||
if static:
|
||||
call = CGWrapper(call, pre="%s::" % descriptorProvider.interface.identifier.name)
|
||||
else:
|
||||
call = CGWrapper(call, pre="%s." % object)
|
||||
call = CGWrapper(call, pre="%s.r()." % object)
|
||||
call = CGList([call, CGWrapper(args, pre="(", post=")")])
|
||||
|
||||
self.cgRoot.append(CGList([
|
||||
|
@ -2214,7 +2214,7 @@ class CGCallGenerator(CGThing):
|
|||
if static:
|
||||
glob = ""
|
||||
else:
|
||||
glob = " let global = global_object_for_js_object(this.reflector().get_jsobject());\n"\
|
||||
glob = " let global = global_object_for_js_object(this.r().reflector().get_jsobject());\n"\
|
||||
" let global = global.root();\n"
|
||||
|
||||
self.cgRoot.append(CGGeneric(
|
||||
|
@ -2222,7 +2222,7 @@ class CGCallGenerator(CGThing):
|
|||
" Ok(result) => result,\n"
|
||||
" Err(e) => {\n"
|
||||
"%s"
|
||||
" throw_dom_exception(cx, global.root_ref(), e);\n"
|
||||
" throw_dom_exception(cx, global.r(), e);\n"
|
||||
" return%s;\n"
|
||||
" },\n"
|
||||
"};" % (glob, errorResult)))
|
||||
|
@ -2307,7 +2307,7 @@ class CGPerSignatureCall(CGThing):
|
|||
def process(arg, i):
|
||||
argVal = "arg" + str(i)
|
||||
if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback():
|
||||
argVal += ".root_ref()"
|
||||
argVal += ".r()"
|
||||
return argVal
|
||||
return [(a, process(a, i)) for (i, a) in enumerate(self.arguments)]
|
||||
|
||||
|
@ -3540,7 +3540,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
|
|||
def process(arg):
|
||||
argVal = arg.identifier.name
|
||||
if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback():
|
||||
argVal += ".root_ref()"
|
||||
argVal += ".r()"
|
||||
return argVal
|
||||
args = [(a, process(a)) for a in self.arguments]
|
||||
if self.idlNode.isGetter():
|
||||
|
@ -4014,7 +4014,7 @@ let global = global_object_for_js_object(JS_CALLEE(cx, vp).to_object());
|
|||
let global = global.root();
|
||||
""")
|
||||
nativeName = MakeNativeName(self._ctor.identifier.name)
|
||||
callGenerator = CGMethodCall(["&global.root_ref()"], nativeName, True,
|
||||
callGenerator = CGMethodCall(["&global.r()"], nativeName, True,
|
||||
self.descriptor, self._ctor)
|
||||
return CGList([preamble, callGenerator])
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ class Descriptor(DescriptorProvider):
|
|||
self.needsRooting = True
|
||||
self.returnType = "Temporary<%s>" % ifaceName
|
||||
self.argumentType = "JSRef<%s>" % ifaceName
|
||||
self.memberType = "Root<'a, 'b, %s>" % ifaceName
|
||||
self.memberType = "Root<%s>" % ifaceName
|
||||
self.nativeType = "JS<%s>" % ifaceName
|
||||
|
||||
self.concreteType = ifaceName
|
||||
|
|
|
@ -471,9 +471,9 @@ impl<T: Reflectable+IDLInterface> FromJSValConvertible<()> for JS<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, T: Reflectable> ToJSValConvertible for Root<'a, 'b, T> {
|
||||
impl<T: Reflectable> ToJSValConvertible for Root<T> {
|
||||
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
|
||||
self.reflector().to_jsval(cx)
|
||||
self.r().reflector().to_jsval(cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,9 @@ pub enum GlobalRef<'a> {
|
|||
}
|
||||
|
||||
/// A stack-based rooted reference to a global object.
|
||||
pub enum GlobalRoot<'a, 'b> {
|
||||
Window(Root<'a, 'b, window::Window>),
|
||||
Worker(Root<'a, 'b, WorkerGlobalScope>),
|
||||
pub enum GlobalRoot {
|
||||
Window(Root<window::Window>),
|
||||
Worker(Root<WorkerGlobalScope>),
|
||||
}
|
||||
|
||||
/// A traced reference to a global object, for use in fields of traced Rust
|
||||
|
@ -98,13 +98,13 @@ impl<'a> Reflectable for GlobalRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> GlobalRoot<'a, 'b> {
|
||||
impl GlobalRoot {
|
||||
/// Obtain a safe reference to the global object that cannot outlive the
|
||||
/// lifetime of this root.
|
||||
pub fn root_ref<'c>(&'c self) -> GlobalRef<'c> {
|
||||
pub fn r<'c>(&'c self) -> GlobalRef<'c> {
|
||||
match *self {
|
||||
GlobalRoot::Window(ref window) => GlobalRef::Window(window.root_ref()),
|
||||
GlobalRoot::Worker(ref worker) => GlobalRef::Worker(worker.root_ref()),
|
||||
GlobalRoot::Window(ref window) => GlobalRef::Window(window.r()),
|
||||
GlobalRoot::Worker(ref worker) => GlobalRef::Worker(worker.r()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,11 +31,11 @@
|
|||
//! Both `Temporary<T>` and `JS<T>` do not allow access to their inner value without explicitly
|
||||
//! creating a stack-based root via the `root` method. This returns a `Root<T>`, which causes
|
||||
//! the JS-owned value to be uncollectable for the duration of the `Root` object's lifetime.
|
||||
//! A `JSRef<T>` can be obtained from a `Root<T>` either by dereferencing the `Root<T>` (`*rooted`)
|
||||
//! or explicitly calling the `root_ref` method. These `JSRef<T>` values are not allowed to
|
||||
//! outlive their originating `Root<T>`, to ensure that all interactions with the enclosed value
|
||||
//! only occur when said value is uncollectable, and will cause static lifetime errors if
|
||||
//! misused.
|
||||
//! A `JSRef<T>` can be obtained from a `Root<T>` by calling the `r` method. (Dereferencing the
|
||||
//! object is still supported, but as it is unsafe, this is deprecated.) These `JSRef<T>` values
|
||||
//! are not allowed to outlive their originating `Root<T>`, to ensure that all interactions with
|
||||
//! the enclosed value only occur when said value is uncollectable, and will cause static lifetime
|
||||
//! errors if misused.
|
||||
//!
|
||||
//! Other miscellaneous helper traits:
|
||||
//!
|
||||
|
@ -91,7 +91,7 @@ impl<T: Reflectable> Temporary<T> {
|
|||
}
|
||||
|
||||
/// Create a stack-bounded root for this value.
|
||||
pub fn root<'a, 'b>(self) -> Root<'a, 'b, T> {
|
||||
pub fn root(self) -> Root<T> {
|
||||
let collection = StackRoots.get().unwrap();
|
||||
unsafe {
|
||||
Root::new(&**collection, &self.inner)
|
||||
|
@ -150,7 +150,7 @@ impl<T: Reflectable> JS<T> {
|
|||
|
||||
|
||||
/// Root this JS-owned value to prevent its collection as garbage.
|
||||
pub fn root<'a, 'b>(&self) -> Root<'a, 'b, T> {
|
||||
pub fn root(&self) -> Root<T> {
|
||||
let collection = StackRoots.get().unwrap();
|
||||
unsafe {
|
||||
Root::new(&**collection, self)
|
||||
|
@ -307,23 +307,23 @@ impl<From, To> JS<From> {
|
|||
|
||||
/// Get an `Option<JSRef<T>>` out of an `Option<Root<T>>`
|
||||
pub trait RootedReference<T> {
|
||||
fn root_ref<'a>(&'a self) -> Option<JSRef<'a, T>>;
|
||||
fn r<'a>(&'a self) -> Option<JSRef<'a, T>>;
|
||||
}
|
||||
|
||||
impl<'a, 'b, T: Reflectable> RootedReference<T> for Option<Root<'a, 'b, T>> {
|
||||
fn root_ref<'a>(&'a self) -> Option<JSRef<'a, T>> {
|
||||
self.as_ref().map(|root| root.root_ref())
|
||||
impl<T: Reflectable> RootedReference<T> for Option<Root<T>> {
|
||||
fn r<'a>(&'a self) -> Option<JSRef<'a, T>> {
|
||||
self.as_ref().map(|root| root.r())
|
||||
}
|
||||
}
|
||||
|
||||
/// Get an `Option<Option<JSRef<T>>>` out of an `Option<Option<Root<T>>>`
|
||||
pub trait OptionalRootedReference<T> {
|
||||
fn root_ref<'a>(&'a self) -> Option<Option<JSRef<'a, T>>>;
|
||||
fn r<'a>(&'a self) -> Option<Option<JSRef<'a, T>>>;
|
||||
}
|
||||
|
||||
impl<'a, 'b, T: Reflectable> OptionalRootedReference<T> for Option<Option<Root<'a, 'b, T>>> {
|
||||
fn root_ref<'a>(&'a self) -> Option<Option<JSRef<'a, T>>> {
|
||||
self.as_ref().map(|inner| inner.root_ref())
|
||||
impl<T: Reflectable> OptionalRootedReference<T> for Option<Option<Root<T>>> {
|
||||
fn r<'a>(&'a self) -> Option<Option<JSRef<'a, T>>> {
|
||||
self.as_ref().map(|inner| inner.r())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,11 +367,11 @@ impl<T: Assignable<U>, U: Reflectable> OptionalSettable<T> for Cell<Option<JS<U>
|
|||
|
||||
/// Root a rootable `Option` type (used for `Option<Temporary<T>>`)
|
||||
pub trait OptionalRootable<T> {
|
||||
fn root<'a, 'b>(self) -> Option<Root<'a, 'b, T>>;
|
||||
fn root(self) -> Option<Root<T>>;
|
||||
}
|
||||
|
||||
impl<T: Reflectable> OptionalRootable<T> for Option<Temporary<T>> {
|
||||
fn root<'a, 'b>(self) -> Option<Root<'a, 'b, T>> {
|
||||
fn root(self) -> Option<Root<T>> {
|
||||
self.map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
@ -389,22 +389,22 @@ impl<'a, T: Reflectable> OptionalUnrootable<T> for Option<JSRef<'a, T>> {
|
|||
|
||||
/// Root a rootable `Option` type (used for `Option<JS<T>>`)
|
||||
pub trait OptionalRootedRootable<T> {
|
||||
fn root<'a, 'b>(&self) -> Option<Root<'a, 'b, T>>;
|
||||
fn root(&self) -> Option<Root<T>>;
|
||||
}
|
||||
|
||||
impl<T: Reflectable> OptionalRootedRootable<T> for Option<JS<T>> {
|
||||
fn root<'a, 'b>(&self) -> Option<Root<'a, 'b, T>> {
|
||||
fn root(&self) -> Option<Root<T>> {
|
||||
self.as_ref().map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
||||
/// Root a rootable `Option<Option>` type (used for `Option<Option<JS<T>>>`)
|
||||
pub trait OptionalOptionalRootedRootable<T> {
|
||||
fn root<'a, 'b>(&self) -> Option<Option<Root<'a, 'b, T>>>;
|
||||
fn root(&self) -> Option<Option<Root<T>>>;
|
||||
}
|
||||
|
||||
impl<T: Reflectable> OptionalOptionalRootedRootable<T> for Option<Option<JS<T>>> {
|
||||
fn root<'a, 'b>(&self) -> Option<Option<Root<'a, 'b, T>>> {
|
||||
fn root(&self) -> Option<Option<Root<T>>> {
|
||||
self.as_ref().map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
@ -412,17 +412,17 @@ impl<T: Reflectable> OptionalOptionalRootedRootable<T> for Option<Option<JS<T>>>
|
|||
|
||||
/// Root a rootable `Result` type (any of `Temporary<T>` or `JS<T>`)
|
||||
pub trait ResultRootable<T,U> {
|
||||
fn root<'a, 'b>(self) -> Result<Root<'a, 'b, T>, U>;
|
||||
fn root(self) -> Result<Root<T>, U>;
|
||||
}
|
||||
|
||||
impl<T: Reflectable, U> ResultRootable<T, U> for Result<Temporary<T>, U> {
|
||||
fn root<'a, 'b>(self) -> Result<Root<'a, 'b, T>, U> {
|
||||
fn root(self) -> Result<Root<T>, U> {
|
||||
self.map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable, U> ResultRootable<T, U> for Result<JS<T>, U> {
|
||||
fn root<'a, 'b>(self) -> Result<Root<'a, 'b, T>, U> {
|
||||
fn root(self) -> Result<Root<T>, U> {
|
||||
self.map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
@ -459,7 +459,7 @@ impl RootCollection {
|
|||
}
|
||||
|
||||
/// Track a stack-based root to ensure LIFO root ordering
|
||||
fn root<'a, 'b, T: Reflectable>(&self, untracked: &Root<'a, 'b, T>) {
|
||||
fn root<'b, T: Reflectable>(&self, untracked: &Root<T>) {
|
||||
unsafe {
|
||||
let roots = self.roots.get();
|
||||
(*roots).push(untracked.js_ptr);
|
||||
|
@ -468,7 +468,7 @@ impl RootCollection {
|
|||
}
|
||||
|
||||
/// Stop tracking a stack-based root, asserting if LIFO root ordering has been violated
|
||||
fn unroot<'a, 'b, T: Reflectable>(&self, rooted: &Root<'a, 'b, T>) {
|
||||
fn unroot<'b, T: Reflectable>(&self, rooted: &Root<T>) {
|
||||
unsafe {
|
||||
let roots = self.roots.get();
|
||||
debug!("unrooting {} (expecting {}",
|
||||
|
@ -485,20 +485,20 @@ impl RootCollection {
|
|||
/// for the same JS value. `Root`s cannot outlive the associated `RootCollection` object.
|
||||
/// Attempts to transfer ownership of a `Root` via moving will trigger dynamic unrooting
|
||||
/// failures due to incorrect ordering.
|
||||
pub struct Root<'a, 'b, T> {
|
||||
pub struct Root<T> {
|
||||
/// List that ensures correct dynamic root ordering
|
||||
root_list: &'a RootCollection,
|
||||
root_list: &'static RootCollection,
|
||||
/// Reference to rooted value that must not outlive this container
|
||||
jsref: JSRef<'b, T>,
|
||||
jsref: JSRef<'static, T>,
|
||||
/// On-stack JS pointer to assuage conservative stack scanner
|
||||
js_ptr: *mut JSObject,
|
||||
}
|
||||
|
||||
impl<'b, 'a: 'b, T: Reflectable> Root<'a, 'b, T> {
|
||||
impl<T: Reflectable> Root<T> {
|
||||
/// Create a new stack-bounded root for the provided JS-owned value.
|
||||
/// It cannot not outlive its associated `RootCollection`, and it contains a `JSRef`
|
||||
/// which cannot outlive this new `Root`.
|
||||
fn new(roots: &'a RootCollection, unrooted: &JS<T>) -> Root<'a, 'b, T> {
|
||||
fn new(roots: &'static RootCollection, unrooted: &JS<T>) -> Root<T> {
|
||||
let root = Root {
|
||||
root_list: roots,
|
||||
jsref: JSRef {
|
||||
|
@ -513,19 +513,22 @@ impl<'b, 'a: 'b, T: Reflectable> Root<'a, 'b, T> {
|
|||
|
||||
/// Obtain a safe reference to the wrapped JS owned-value that cannot outlive
|
||||
/// the lifetime of this root.
|
||||
pub fn root_ref<'b>(&'b self) -> JSRef<'b,T> {
|
||||
self.jsref.clone()
|
||||
pub fn r<'b>(&'b self) -> JSRef<'b, T> {
|
||||
JSRef {
|
||||
ptr: self.jsref.ptr,
|
||||
chain: ContravariantLifetime,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<'b, 'a: 'b, T: Reflectable> Drop for Root<'a, 'b, T> {
|
||||
impl<T: Reflectable> Drop for Root<T> {
|
||||
fn drop(&mut self) {
|
||||
self.root_list.unroot(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, 'a: 'b, T: Reflectable> Deref<JSRef<'b, T>> for Root<'a, 'b, T> {
|
||||
impl<'b, T: Reflectable> Deref<JSRef<'b, T>> for Root<T> {
|
||||
fn deref<'c>(&'c self) -> &'c JSRef<'b, T> {
|
||||
&self.jsref
|
||||
}
|
||||
|
|
|
@ -552,7 +552,7 @@ pub extern fn outerize_global(_cx: *mut JSContext, obj: JSHandleObject) -> *mut
|
|||
debug!("outerizing");
|
||||
let obj = *obj.unnamed_field1;
|
||||
let win: Root<window::Window> = unwrap_jsmanaged(obj).unwrap().root();
|
||||
win.browser_context().as_ref().unwrap().window_proxy()
|
||||
win.r().browser_context().as_ref().unwrap().window_proxy()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue