diff options
author | bors-servo <metajack+bors@gmail.com> | 2015-02-05 10:51:50 -0700 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2015-02-05 10:51:50 -0700 |
commit | d439c0d16d6ea1449d207858705d124e191ecc13 (patch) | |
tree | 5aaffe4591852c1496668af22dc7cd229b41259a /components/script | |
parent | a938bdf9711e5e54d78b74c9446980f76b576958 (diff) | |
parent | 4036206734efb924ea555b0a368692378221b54c (diff) | |
download | servo-d439c0d16d6ea1449d207858705d124e191ecc13.tar.gz servo-d439c0d16d6ea1449d207858705d124e191ecc13.zip |
auto merge of #4850 : Ms2ger/servo/root-deref, r=jdm
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/bindings/js.rs | 27 | ||||
-rw-r--r-- | components/script/dom/browsercontext.rs | 2 | ||||
-rw-r--r-- | components/script/dom/document.rs | 2 | ||||
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 1 | ||||
-rw-r--r-- | components/script/dom/node.rs | 55 | ||||
-rw-r--r-- | components/script/dom/treewalker.rs | 36 | ||||
-rw-r--r-- | components/script/dom/urlsearchparams.rs | 3 | ||||
-rw-r--r-- | components/script/script_task.rs | 14 |
8 files changed, 73 insertions, 67 deletions
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index 02a6c430421..216c38604ab 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -584,7 +584,7 @@ pub struct Root<T> { /// List that ensures correct dynamic root ordering root_list: &'static RootCollection, /// Reference to rooted value that must not outlive this container - jsref: JSRef<'static, T>, + ptr: NonZero<*const T>, /// On-stack JS pointer to assuage conservative stack scanner js_ptr: *mut JSObject, } @@ -596,10 +596,7 @@ impl<T: Reflectable> Root<T> { fn new(roots: &'static RootCollection, unrooted: &JS<T>) -> Root<T> { let root = Root { root_list: roots, - jsref: JSRef { - ptr: unrooted.ptr.clone(), - chain: ContravariantLifetime, - }, + ptr: unrooted.ptr, js_ptr: unrooted.reflector().get_jsobject(), }; roots.root(&root); @@ -610,7 +607,18 @@ impl<T: Reflectable> Root<T> { /// the lifetime of this root. pub fn r<'b>(&'b self) -> JSRef<'b, T> { JSRef { - ptr: self.jsref.ptr, + ptr: self.ptr, + chain: ContravariantLifetime, + } + } + + /// Obtain an unsafe reference to the wrapped JS owned-value that can + /// outlive the lifetime of this root. + /// + /// DO NOT CALL. + pub fn get_unsound_ref_forever<'b>(&self) -> JSRef<'b, T> { + JSRef { + ptr: self.ptr, chain: ContravariantLifetime, } } @@ -623,13 +631,6 @@ impl<T: Reflectable> Drop for Root<T> { } } -impl<'b, T: Reflectable> Deref for Root<T> { - type Target = JSRef<'b, T>; - fn deref<'c>(&'c self) -> &'c JSRef<'b, T> { - &self.jsref - } -} - impl<'a, T: Reflectable> Deref for JSRef<'a, T> { type Target = T; fn deref<'b>(&'b self) -> &'b T { diff --git a/components/script/dom/browsercontext.rs b/components/script/dom/browsercontext.rs index f7572d6d6a7..1f3f38dbf77 100644 --- a/components/script/dom/browsercontext.rs +++ b/components/script/dom/browsercontext.rs @@ -64,7 +64,7 @@ impl BrowserContext { pub fn parent(&self) -> Option<Temporary<Window>> { self.parent.map(|p| { - p.root().browser_context().as_ref().unwrap().active_window() + p.root().r().browser_context().as_ref().unwrap().active_window() }) } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 3734527bc09..682d2dcd9aa 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1015,6 +1015,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { return Err(Security); } let window = self.window.root(); + let window = window.r(); let page = window.page(); let (tx, rx) = channel(); let _ = page.resource_task.send(GetCookiesForUrl(url, tx, NonHTTP)); @@ -1030,6 +1031,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { return Err(Security); } let window = self.window.root(); + let window = window.r(); let page = window.page(); let _ = page.resource_task.send(SetCookiesForUrl(url, cookie, NonHTTP)); Ok(()) diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 871413f1077..bb310607b1b 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -170,6 +170,7 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { fn GetContentWindow(self) -> Option<Temporary<Window>> { self.subpage_id.get().and_then(|subpage_id| { let window = window_from_node(self).root(); + let window = window.r(); let children = window.page().children.borrow(); let child = children.iter().find(|child| { child.subpage_id.unwrap() == subpage_id diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index cdd52e78855..860f03753e8 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -723,7 +723,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { fn following_siblings(self) -> NodeChildrenIterator<'a> { NodeChildrenIterator { - current: self.next_sibling().root().map(|next| next.clone()), + current: self.next_sibling().root().map(|next| next.get_unsound_ref_forever()), } } @@ -797,7 +797,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { fn ancestors(self) -> AncestorIterator<'a> { AncestorIterator { - current: self.parent_node.get().map(|node| (*node.root()).clone()), + current: self.parent_node.get().map(|node| node.root().get_unsound_ref_forever()), } } @@ -821,7 +821,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> { fn children(self) -> NodeChildrenIterator<'a> { NodeChildrenIterator { - current: self.first_child.get().map(|node| (*node.root()).clone()), + current: self.first_child.get().map(|node| node.root().get_unsound_ref_forever()), } } @@ -1035,7 +1035,7 @@ impl<'a> Iterator for NodeChildrenIterator<'a> { fn next(&mut self) -> Option<JSRef<'a, Node>> { let node = self.current; - self.current = node.and_then(|node| node.next_sibling().map(|node| *node.root())); + self.current = node.and_then(|node| node.next_sibling().map(|node| node.root().get_unsound_ref_forever())); node } } @@ -1063,7 +1063,7 @@ impl<'a> Iterator for AncestorIterator<'a> { fn next(&mut self) -> Option<JSRef<'a, Node>> { let node = self.current; - self.current = node.and_then(|node| node.parent_node().map(|node| *node.root())); + self.current = node.and_then(|node| node.parent_node().map(|node| node.root().get_unsound_ref_forever())); node } } @@ -1089,7 +1089,7 @@ impl<'a> Iterator for TreeIterator<'a> { fn next(&mut self) -> Option<JSRef<'a, Node>> { let ret = self.stack.pop(); ret.map(|node| { - self.stack.extend(node.rev_children().map(|c| *c.root())) + self.stack.extend(node.rev_children().map(|c| c.root().get_unsound_ref_forever())) }); ret } @@ -1124,7 +1124,7 @@ impl NodeIterator { match ElementCast::to_ref(node) { Some(element) if skip(element) => None, - _ => node.first_child().map(|child| (*child.root()).clone()), + _ => node.first_child().map(|child| child.root().get_unsound_ref_forever()), } } } @@ -1138,33 +1138,34 @@ impl<'a> Iterator for NodeIterator { if self.include_start { Some(self.start_node) } else { - self.next_child(*self.start_node.root()) + self.next_child(self.start_node.root().r()) .map(|child| JS::from_rooted(child)) } }, Some(node) => { - match self.next_child(*node) { + match self.next_child(node.r()) { Some(child) => { self.depth += 1; Some(JS::from_rooted(child)) }, - None if JS::from_rooted(*node) == self.start_node => None, + None if JS::from_rooted(node.r()) == self.start_node => None, None => { - match node.next_sibling().root() { - Some(sibling) => Some(JS::from_rooted(*sibling)), + match node.r().next_sibling().root() { + Some(sibling) => Some(JS::from_rooted(sibling.r())), None => { - let mut candidate = node.clone(); + let mut candidate = node.get_unsound_ref_forever(); while candidate.next_sibling().is_none() { - candidate = (*candidate.parent_node() - .expect("Got to root without reaching start node") - .root()).clone(); + candidate = candidate.parent_node() + .expect("Got to root without reaching start node") + .root() + .get_unsound_ref_forever(); self.depth -= 1; if JS::from_rooted(candidate) == self.start_node { break; } } if JS::from_rooted(candidate) != self.start_node { - candidate.next_sibling().map(|node| JS::from_rooted(*node.root())) + candidate.next_sibling().map(|node| JS::from_rooted(node.root().r())) } else { None } @@ -1174,7 +1175,7 @@ impl<'a> Iterator for NodeIterator { } } }; - self.current_node.map(|node| (*node.root()).clone()) + self.current_node.map(|node| node.root().get_unsound_ref_forever()) } } @@ -1380,13 +1381,13 @@ impl Node { // Step 7-8. let reference_child = match child { - Some(child) if child.clone() == node => node.next_sibling().map(|node| (*node.root()).clone()), + Some(child) if child.clone() == node => node.next_sibling().map(|node| node.root().get_unsound_ref_forever()), _ => child }; // Step 9. let document = document_from_node(parent).root(); - Node::adopt(node, *document); + Node::adopt(node, document.r()); // Step 10. Node::insert(node, parent, reference_child, SuppressObserver::Unsuppressed); @@ -1970,9 +1971,9 @@ impl<'a> NodeMethods for JSRef<'a, Node> { } // Step 7-8. - let next_sibling = child.next_sibling().map(|node| (*node.root()).clone()); + let next_sibling = child.next_sibling().map(|node| node.root().get_unsound_ref_forever()); let reference_child = match next_sibling { - Some(sibling) if sibling == node => node.next_sibling().map(|node| (*node.root()).clone()), + Some(sibling) if sibling == node => node.next_sibling().map(|node| node.root().get_unsound_ref_forever()), _ => next_sibling }; @@ -2240,7 +2241,7 @@ impl<'a> style::node::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> { this.parent_node() } - parent_node(self).map(|node| *node.root()) + parent_node(self).map(|node| node.root().get_unsound_ref_forever()) } fn first_child(self) -> Option<JSRef<'a, Node>> { @@ -2250,7 +2251,7 @@ impl<'a> style::node::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> { this.first_child() } - first_child(self).map(|node| *node.root()) + first_child(self).map(|node| node.root().get_unsound_ref_forever()) } fn last_child(self) -> Option<JSRef<'a, Node>> { @@ -2260,7 +2261,7 @@ impl<'a> style::node::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> { this.last_child() } - last_child(self).map(|node| *node.root()) + last_child(self).map(|node| node.root().get_unsound_ref_forever()) } fn prev_sibling(self) -> Option<JSRef<'a, Node>> { @@ -2270,7 +2271,7 @@ impl<'a> style::node::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> { this.prev_sibling() } - prev_sibling(self).map(|node| *node.root()) + prev_sibling(self).map(|node| node.root().get_unsound_ref_forever()) } fn next_sibling(self) -> Option<JSRef<'a, Node>> { @@ -2280,7 +2281,7 @@ impl<'a> style::node::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> { this.next_sibling() } - next_sibling(self).map(|node| *node.root()) + next_sibling(self).map(|node| node.root().get_unsound_ref_forever()) } fn is_document(self) -> bool { diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs index d7dab56949d..25045e50c85 100644 --- a/components/script/dom/treewalker.rs +++ b/components/script/dom/treewalker.rs @@ -154,7 +154,7 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { // "1. Let node be the value of the currentNode attribute." // "2. Set node to node's first child if type is first, and node's last child if type is last." let cur = self.current_node.get().root(); - let mut node_op: Option<JSRef<Node>> = next_child(*cur).map(|node| node.root().clone()); + let mut node_op: Option<JSRef<Node>> = next_child(cur.r()).map(|node| node.root().get_unsound_ref_forever()); // 3. Main: While node is not null, run these substeps: 'main: loop { @@ -177,7 +177,7 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { match next_child(node) { // "2. If child is not null, set node to child and goto Main." Some(child) => { - node_op = Some(child.root().clone()); + node_op = Some(child.root().get_unsound_ref_forever()); continue 'main }, None => {} @@ -196,12 +196,12 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { // "2. If sibling is not null, // set node to sibling and goto Main." Some(sibling) => { - node_op = Some(sibling.root().clone()); + node_op = Some(sibling.root().get_unsound_ref_forever()); continue 'main }, None => { // "3. Let parent be node's parent." - match node.parent_node().map(|p| p.root().clone()) { + match node.parent_node().map(|p| p.root().get_unsound_ref_forever()) { // "4. If parent is null, parent is root, // or parent is currentNode attribute's value, // return null." @@ -234,7 +234,7 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { { // "To **traverse siblings** of type *type* run these steps:" // "1. Let node be the value of the currentNode attribute." - let mut node = self.current_node.get().root().clone(); + let mut node = self.current_node.get().root().get_unsound_ref_forever(); // "2. If node is root, return null." if self.is_root_node(node) { return Ok(None) @@ -247,7 +247,7 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { // "2. While sibling is not null, run these subsubsteps:" while sibling_op.is_some() { // "1. Set node to sibling." - node = sibling_op.unwrap().root().clone(); + node = sibling_op.unwrap().root().get_unsound_ref_forever(); // "2. Filter node and let result be the return value." let result = self.accept_node(node); // "3. If result is FILTER_ACCEPT, then set the currentNode @@ -273,7 +273,7 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { } } // "3. Set node to its parent." - match node.parent_node().map(|p| p.root().clone()) { + match node.parent_node().map(|p| p.root().get_unsound_ref_forever()) { // "4. If node is null or is root, return null." None => return Ok(None), Some(n) if self.is_root_node(n) => return Ok(None), @@ -305,7 +305,7 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { // This can happen if the user set the current node to somewhere // outside of the tree rooted at the original root. return None, - Some(n) => candidate = n.root().clone() + Some(n) => candidate = n.root().get_unsound_ref_forever() } } if self.is_root_node(candidate) { @@ -362,13 +362,13 @@ impl<'a> TreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { // http://dom.spec.whatwg.org/#dom-treewalker-parentnode fn parent_node(self) -> Fallible<Option<Temporary<Node>>> { // "1. Let node be the value of the currentNode attribute." - let mut node = self.current_node.get().root().clone(); + let mut node = self.current_node.get().root().get_unsound_ref_forever(); // "2. While node is not null and is not root, run these substeps:" while !self.is_root_node(node) { // "1. Let node be node's parent." match node.parent_node() { Some(n) => { - node = n.root().clone(); + node = n.root().get_unsound_ref_forever(); // "2. If node is not null and filtering node returns FILTER_ACCEPT, // then set the currentNode attribute to node, return node." match self.accept_node(node) { @@ -418,7 +418,7 @@ impl<'a> TreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { // http://dom.spec.whatwg.org/#dom-treewalker-previousnode fn prev_node(self) -> Fallible<Option<Temporary<Node>>> { // "1. Let node be the value of the currentNode attribute." - let mut node = self.current_node.get().root().clone(); + let mut node = self.current_node.get().root().get_unsound_ref_forever(); // "2. While node is not root, run these substeps:" while !self.is_root_node(node) { // "1. Let sibling be the previous sibling of node." @@ -426,7 +426,7 @@ impl<'a> TreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { // "2. While sibling is not null, run these subsubsteps:" while sibling_op.is_some() { // "1. Set node to sibling." - node = sibling_op.unwrap().root().clone(); + node = sibling_op.unwrap().root().get_unsound_ref_forever(); // "2. Filter node and let result be the return value." // "3. While result is not FILTER_REJECT and node has a child, // set node to its last child and then filter node and @@ -438,7 +438,7 @@ impl<'a> TreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { Err(e) => return Err(e), Ok(NodeFilterConstants::FILTER_REJECT) => break, _ if node.first_child().is_some() => - node = node.last_child().unwrap().root().clone(), + node = node.last_child().unwrap().root().get_unsound_ref_forever(), Ok(NodeFilterConstants::FILTER_ACCEPT) => { self.current_node.set(JS::from_rooted(node)); return Ok(Some(Temporary::from_rooted(node))) @@ -459,7 +459,7 @@ impl<'a> TreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { // This can happen if the user set the current node to somewhere // outside of the tree rooted at the original root. return Ok(None), - Some(n) => node = n.root().clone() + Some(n) => node = n.root().get_unsound_ref_forever() } // "5. Filter node and if the return value is FILTER_ACCEPT, then // set the currentNode attribute to node and return node." @@ -479,7 +479,7 @@ impl<'a> TreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { // http://dom.spec.whatwg.org/#dom-treewalker-nextnode fn next_node(self) -> Fallible<Option<Temporary<Node>>> { // "1. Let node be the value of the currentNode attribute." - let mut node = self.current_node.get().root().clone(); + let mut node = self.current_node.get().root().get_unsound_ref_forever(); // "2. Let result be FILTER_ACCEPT." let mut result = Ok(NodeFilterConstants::FILTER_ACCEPT); // "3. Run these substeps:" @@ -494,7 +494,7 @@ impl<'a> TreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { None => break, Some (child) => { // "1. Set node to its first child." - node = child.root().clone(); + node = child.root().get_unsound_ref_forever(); // "2. Filter node and set result to the return value." result = self.accept_node(node); // "3. If result is FILTER_ACCEPT, then @@ -516,7 +516,7 @@ impl<'a> TreeWalkerHelpers<'a> for JSRef<'a, TreeWalker> { match self.first_following_node_not_following_root(node) { None => return Ok(None), Some(n) => { - node = n.root().clone(); + node = n.root().get_unsound_ref_forever(); // "3. Filter node and set result to the return value." result = self.accept_node(node); // "4. If result is FILTER_ACCEPT, then @@ -541,7 +541,7 @@ impl<'a> Iterator for JSRef<'a, TreeWalker> { fn next(&mut self) -> Option<JSRef<'a, Node>> { match self.next_node() { - Ok(node) => node.map(|n| n.root().clone()), + Ok(node) => node.map(|n| n.root().get_unsound_ref_forever()), Err(_) => // The Err path happens only when a JavaScript // NodeFilter throws an exception. This iterator diff --git a/components/script/dom/urlsearchparams.rs b/components/script/dom/urlsearchparams.rs index e2a46b3e866..b76504f4137 100644 --- a/components/script/dom/urlsearchparams.rs +++ b/components/script/dom/urlsearchparams.rs @@ -51,12 +51,13 @@ impl URLSearchParams { }, Some(eURLSearchParams(u)) => { let u = u.root(); + let usp = usp.r(); let mut map = usp.data.borrow_mut(); *map = u.r().data.borrow().clone(); }, None => {} } - Ok(Temporary::from_rooted(*usp)) + Ok(Temporary::from_rooted(usp.r())) } } diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 287b6c61adf..50dc0538e0d 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -16,7 +16,7 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, NodeCas use dom::bindings::conversions::FromJSValConvertible; use dom::bindings::conversions::StringificationBehavior; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable}; +use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, RootedReference}; use dom::bindings::js::{RootCollection, RootCollectionPtr}; use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference}; use dom::bindings::structuredclone::StructuredCloneData; @@ -772,7 +772,7 @@ impl ScriptTask { // denies access to most properties (per // https://github.com/servo/servo/issues/3939#issuecomment-62287025). borrowed_page.find(pid).and_then(|page| { - Some(*page.frame.borrow().as_ref().unwrap().window.root()) + Some(page.frame.borrow().as_ref().unwrap().window.root()) }) }); @@ -853,9 +853,9 @@ impl ScriptTask { IsHTMLDocument::HTMLDocument, None, DocumentSource::FromParser).root(); if let Some(tm) = last_modified { - document.set_last_modified(dom_last_modified(&tm)); + document.r().set_last_modified(dom_last_modified(&tm)); } - window.r().init_browser_context(document.r(), parent_window); + window.r().init_browser_context(document.r(), parent_window.r()); { @@ -1252,9 +1252,9 @@ impl ScriptTask { for node_address in node_address.iter() { let temp_node = - node::from_untrusted_node_address(self.js_runtime.ptr, *node_address); + node::from_untrusted_node_address(self.js_runtime.ptr, *node_address).root(); - let maybe_node = temp_node.root().ancestors().find(|node| node.is_element()); + let maybe_node = temp_node.r().ancestors().find(|node| node.is_element()); match maybe_node { Some(node) => { node.set_hover_state(true); @@ -1406,7 +1406,7 @@ impl DocumentProgressHandler { EventCancelable::NotCancelable).root(); let wintarget: JSRef<EventTarget> = EventTargetCast::from_ref(window.r()); let doctarget: JSRef<EventTarget> = EventTargetCast::from_ref(document.r()); - event.set_trusted(true); + event.r().set_trusted(true); let _ = wintarget.dispatch_event_with_target(doctarget, event.r()); } } |