servo: Merge #11522 - Remove all uses of &Root<T> (from nox:root-ref); r=jdm
authorAnthony Ramine <n.oxyde@gmail.com>
Wed, 01 Jun 2016 07:36:47 -0500
changeset 338975 dd747f278fc40be1e92f81225d036982fd0a5da1
parent 338974 97bab307c0ad6fab34b6c4b91efed7ec439c256a
child 338976 3bb9e01e7c7b993fa829903af97c2ac16a2bc3a3
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
servo: Merge #11522 - Remove all uses of &Root<T> (from nox:root-ref); r=jdm Source-Repo: https://github.com/servo/servo Source-Revision: 2be5f7211377a9609aad962be443308bef247df1
servo/components/script/dom/bindings/js.rs
servo/components/script/dom/bindings/trace.rs
servo/components/script/dom/canvasrenderingcontext2d.rs
servo/components/script/dom/document.rs
servo/components/script/dom/domrectlist.rs
servo/components/script/dom/filelist.rs
servo/components/script/dom/formdata.rs
servo/components/script/dom/htmlcanvaselement.rs
servo/components/script/dom/htmltableelement.rs
servo/components/script/dom/node.rs
servo/components/script/dom/nodelist.rs
servo/components/script/dom/performance.rs
servo/components/script/dom/radionodelist.rs
servo/components/script/dom/xmlhttprequest.rs
--- a/servo/components/script/dom/bindings/js.rs
+++ b/servo/components/script/dom/bindings/js.rs
@@ -71,25 +71,16 @@ impl<T> JS<T> {
         debug_assert!(thread_state::get().is_layout());
         LayoutJS {
             ptr: self.ptr.clone(),
         }
     }
 }
 
 impl<T: Reflectable> JS<T> {
-    /// Create a JS<T> from a Root<T>
-    /// XXX Not a great API. Should be a call on Root<T> instead
-    #[allow(unrooted_must_root)]
-    pub fn from_rooted(root: &Root<T>) -> JS<T> {
-        debug_assert!(thread_state::get().is_script());
-        JS {
-            ptr: unsafe { NonZero::new(&**root) },
-        }
-    }
     /// Create a JS<T> from a &T
     #[allow(unrooted_must_root)]
     pub fn from_ref(obj: &T) -> JS<T> {
         debug_assert!(thread_state::get().is_script());
         JS {
             ptr: unsafe { NonZero::new(&*obj) },
         }
     }
@@ -499,37 +490,34 @@ impl RootCollection {
     pub fn new() -> RootCollection {
         debug_assert!(thread_state::get().is_script());
         RootCollection {
             roots: UnsafeCell::new(vec![]),
         }
     }
 
     /// Start tracking a stack-based root
-    fn root(&self, untracked_reflector: *const Reflector) {
+    unsafe fn root(&self, untracked_reflector: *const Reflector) {
         debug_assert!(thread_state::get().is_script());
-        unsafe {
-            let mut roots = &mut *self.roots.get();
-            roots.push(untracked_reflector);
-            assert!(!(*untracked_reflector).get_jsobject().is_null())
-        }
+        let mut roots = &mut *self.roots.get();
+        roots.push(untracked_reflector);
+        assert!(!(*untracked_reflector).get_jsobject().is_null())
     }
 
-    /// Stop tracking a stack-based root, asserting if the reflector isn't found
-    fn unroot<T: Reflectable>(&self, rooted: &Root<T>) {
+    /// Stop tracking a stack-based reflector, asserting if it isn't found.
+    unsafe fn unroot(&self, tracked_reflector: *const Reflector) {
+        assert!(!tracked_reflector.is_null());
+        assert!(!(*tracked_reflector).get_jsobject().is_null());
         debug_assert!(thread_state::get().is_script());
-        unsafe {
-            let mut roots = &mut *self.roots.get();
-            let old_reflector = &*rooted.reflector();
-            match roots.iter().rposition(|r| *r == old_reflector) {
-                Some(idx) => {
-                    roots.remove(idx);
-                },
-                None => panic!("Can't remove a root that was never rooted!"),
-            }
+        let mut roots = &mut *self.roots.get();
+        match roots.iter().rposition(|r| *r == tracked_reflector) {
+            Some(idx) => {
+                roots.remove(idx);
+            },
+            None => panic!("Can't remove a root that was never rooted!"),
         }
     }
 }
 
 /// SM Callback that traces the rooted reflectors
 pub unsafe fn trace_roots(tracer: *mut JSTracer) {
     debug!("tracing stack roots");
     STACK_ROOTS.with(|ref collection| {
@@ -608,26 +596,26 @@ impl<T: Reflectable> Deref for Root<T> {
     type Target = T;
     fn deref(&self) -> &T {
         debug_assert!(thread_state::get().is_script());
         unsafe { &**self.ptr.deref() }
     }
 }
 
 impl<T: Reflectable> PartialEq for Root<T> {
-    fn eq(&self, other: &Root<T>) -> bool {
+    fn eq(&self, other: &Self) -> bool {
         self.ptr == other.ptr
     }
 }
 
 impl<T: Reflectable> Clone for Root<T> {
     fn clone(&self) -> Root<T> {
         Root::from_ref(&*self)
     }
 }
 
 impl<T: Reflectable> Drop for Root<T> {
     fn drop(&mut self) {
         unsafe {
-            (*self.root_list).unroot(self);
+            (*self.root_list).unroot(self.reflector());
         }
     }
 }
--- a/servo/components/script/dom/bindings/trace.rs
+++ b/servo/components/script/dom/bindings/trace.rs
@@ -535,17 +535,17 @@ impl<T: JSTraceable> DerefMut for Rooted
 impl<A: JSTraceable + Reflectable> FromIterator<Root<A>> for RootedVec<JS<A>> {
     #[allow(moved_no_move)]
     fn from_iter<T>(iterable: T) -> RootedVec<JS<A>>
         where T: IntoIterator<Item = Root<A>>
     {
         let mut vec = unsafe {
             RootedVec::new_with_destination_address(return_address() as *const libc::c_void)
         };
-        vec.extend(iterable.into_iter().map(|item| JS::from_rooted(&item)));
+        vec.extend(iterable.into_iter().map(|item| JS::from_ref(&*item)));
         vec
     }
 }
 
 /// SM Callback that traces the rooted traceables
 pub unsafe fn trace_traceables(tracer: *mut JSTracer) {
     debug!("tracing stack-rooted traceables");
     ROOTED_TRACEABLES.with(|ref traceables| {
--- a/servo/components/script/dom/canvasrenderingcontext2d.rs
+++ b/servo/components/script/dom/canvasrenderingcontext2d.rs
@@ -991,24 +991,24 @@ impl CanvasRenderingContext2DMethods for
                     self.ipc_renderer
                         .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(
                                     FillOrStrokeStyle::Color(rgba))))
                         .unwrap()
                 }
             }
             StringOrCanvasGradientOrCanvasPattern::CanvasGradient(gradient) => {
                 self.state.borrow_mut().fill_style =
-                    CanvasFillOrStrokeStyle::Gradient(JS::from_rooted(&gradient));
+                    CanvasFillOrStrokeStyle::Gradient(JS::from_ref(&*gradient));
                 let msg = CanvasMsg::Canvas2d(
                     Canvas2dMsg::SetFillStyle(gradient.to_fill_or_stroke_style()));
                 self.ipc_renderer.send(msg).unwrap();
             }
             StringOrCanvasGradientOrCanvasPattern::CanvasPattern(pattern) => {
                 self.state.borrow_mut().fill_style =
-                    CanvasFillOrStrokeStyle::Pattern(JS::from_rooted(&pattern));
+                    CanvasFillOrStrokeStyle::Pattern(JS::from_ref(&*pattern));
                 let msg = CanvasMsg::Canvas2d(
                     Canvas2dMsg::SetFillStyle(pattern.to_fill_or_stroke_style()));
                 self.ipc_renderer.send(msg).unwrap();
                 if !pattern.origin_is_clean() {
                     self.set_origin_unclean();
                 }
             }
         }
--- a/servo/components/script/dom/document.rs
+++ b/servo/components/script/dom/document.rs
@@ -978,23 +978,23 @@ impl Document {
                                client_x,
                                client_y,
                                page_x,
                                page_y);
 
         match event_type {
             TouchEventType::Down => {
                 // Add a new touch point
-                self.active_touch_points.borrow_mut().push(JS::from_rooted(&touch));
+                self.active_touch_points.borrow_mut().push(JS::from_ref(&*touch));
             }
             TouchEventType::Move => {
                 // Replace an existing touch point
                 let mut active_touch_points = self.active_touch_points.borrow_mut();
                 match active_touch_points.iter_mut().find(|t| t.Identifier() == identifier) {
-                    Some(t) => *t = JS::from_rooted(&touch),
+                    Some(t) => *t = JS::from_ref(&*touch),
                     None => warn!("Got a touchmove event for a non-active touch point"),
                 }
             }
             TouchEventType::Up |
             TouchEventType::Cancel => {
                 // Remove an existing touch point
                 let mut active_touch_points = self.active_touch_points.borrow_mut();
                 match active_touch_points.iter().position(|t| t.Identifier() == identifier) {
@@ -1005,17 +1005,17 @@ impl Document {
                 }
             }
         }
 
         let mut touches = RootedVec::new();
         touches.extend(self.active_touch_points.borrow().iter().cloned());
 
         let mut changed_touches = RootedVec::new();
-        changed_touches.push(JS::from_rooted(&touch));
+        changed_touches.push(JS::from_ref(&*touch));
 
         let mut target_touches = RootedVec::new();
         target_touches.extend(self.active_touch_points
                                   .borrow()
                                   .iter()
                                   .filter(|t| t.Target() == target)
                                   .cloned());
 
@@ -1770,17 +1770,17 @@ impl Document {
                         if let Some(node) = node.downcast::<HTMLStyleElement>() {
                             node.get_stylesheet()
                         } else if let Some(node) = node.downcast::<HTMLLinkElement>() {
                             node.get_stylesheet()
                         } else if let Some(node) = node.downcast::<HTMLMetaElement>() {
                             node.get_stylesheet()
                         } else {
                             None
-                        }.map(|stylesheet| (JS::from_rooted(&node), stylesheet))
+                        }.map(|stylesheet| (JS::from_ref(&*node), stylesheet))
                     })
                     .collect());
             };
         }
         self.stylesheets.borrow().as_ref().unwrap().iter()
                         .map(|&(_, ref stylesheet)| stylesheet.clone())
                         .collect()
     }
@@ -1993,17 +1993,17 @@ impl DocumentMethods for Document {
             Vacant(entry) => {
                 let mut tag_copy = tag_name;
                 tag_copy.make_ascii_lowercase();
                 let ascii_lower_tag = Atom::from(tag_copy);
                 let result = HTMLCollection::by_atomic_tag_name(&self.window,
                                                                 self.upcast(),
                                                                 tag_atom,
                                                                 ascii_lower_tag);
-                entry.insert(JS::from_rooted(&result));
+                entry.insert(JS::from_ref(&*result));
                 result
             }
         }
     }
 
     // https://dom.spec.whatwg.org/#dom-document-getelementsbytagnamens
     fn GetElementsByTagNameNS(&self,
                               maybe_ns: Option<DOMString>,
@@ -2011,34 +2011,34 @@ impl DocumentMethods for Document {
                               -> Root<HTMLCollection> {
         let ns = namespace_from_domstring(maybe_ns);
         let local = Atom::from(tag_name);
         let qname = QualName::new(ns, local);
         match self.tagns_map.borrow_mut().entry(qname.clone()) {
             Occupied(entry) => Root::from_ref(entry.get()),
             Vacant(entry) => {
                 let result = HTMLCollection::by_qual_tag_name(&self.window, self.upcast(), qname);
-                entry.insert(JS::from_rooted(&result));
+                entry.insert(JS::from_ref(&*result));
                 result
             }
         }
     }
 
     // https://dom.spec.whatwg.org/#dom-document-getelementsbyclassname
     fn GetElementsByClassName(&self, classes: DOMString) -> Root<HTMLCollection> {
         let class_atoms: Vec<Atom> = split_html_space_chars(&classes)
                                          .map(Atom::from)
                                          .collect();
         match self.classes_map.borrow_mut().entry(class_atoms.clone()) {
             Occupied(entry) => Root::from_ref(entry.get()),
             Vacant(entry) => {
                 let result = HTMLCollection::by_atomic_class_name(&self.window,
                                                                   self.upcast(),
                                                                   class_atoms);
-                entry.insert(JS::from_rooted(&result));
+                entry.insert(JS::from_ref(&*result));
                 result
             }
         }
     }
 
     // https://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid
     fn GetElementById(&self, id: DOMString) -> Option<Root<Element>> {
         self.get_element_by_id(&Atom::from(id))
--- a/servo/components/script/dom/domrectlist.rs
+++ b/servo/components/script/dom/domrectlist.rs
@@ -17,17 +17,17 @@ pub struct DOMRectList {
 }
 
 impl DOMRectList {
     fn new_inherited<T>(rects: T) -> DOMRectList
         where T: Iterator<Item = Root<DOMRect>>
     {
         DOMRectList {
             reflector_: Reflector::new(),
-            rects: rects.map(|r| JS::from_rooted(&r)).collect(),
+            rects: rects.map(|r| JS::from_ref(&*r)).collect(),
         }
     }
 
     pub fn new<T>(window: &Window, rects: T) -> Root<DOMRectList>
         where T: Iterator<Item = Root<DOMRect>>
     {
         reflect_dom_object(box DOMRectList::new_inherited(rects),
                            GlobalRef::Window(window),
--- a/servo/components/script/dom/filelist.rs
+++ b/servo/components/script/dom/filelist.rs
@@ -23,17 +23,17 @@ impl FileList {
         FileList {
             reflector_: Reflector::new(),
             list: files
         }
     }
 
     #[allow(unrooted_must_root)]
     pub fn new(window: &Window, files: Vec<Root<File>>) -> Root<FileList> {
-        reflect_dom_object(box FileList::new_inherited(files.iter().map(|r| JS::from_rooted(&r)).collect()),
+        reflect_dom_object(box FileList::new_inherited(files.iter().map(|r| JS::from_ref(&**r)).collect()),
                            GlobalRef::Window(window),
                            FileListBinding::Wrap)
     }
 }
 
 impl FileListMethods for FileList {
     // https://w3c.github.io/FileAPI/#dfn-length
     fn Length(&self) -> u32 {
--- a/servo/components/script/dom/formdata.rs
+++ b/servo/components/script/dom/formdata.rs
@@ -61,17 +61,17 @@ impl FormDataMethods for FormData {
             Occupied(entry) => entry.into_mut().push(FormDatum::StringData(value.0)),
             Vacant  (entry) => { entry.insert(vec!(FormDatum::StringData(value.0))); }
         }
     }
 
     #[allow(unrooted_must_root)]
     // https://xhr.spec.whatwg.org/#dom-formdata-append
     fn Append_(&self, name: USVString, value: &Blob, filename: Option<USVString>) {
-        let blob = FormDatum::BlobData(JS::from_rooted(&self.get_file_or_blob(value, filename)));
+        let blob = FormDatum::BlobData(JS::from_ref(&*self.get_file_or_blob(value, filename)));
         let mut data = self.data.borrow_mut();
         match data.entry(Atom::from(name.0)) {
             Occupied(entry) => entry.into_mut().push(blob),
             Vacant(entry) => {
                 entry.insert(vec!(blob));
             }
         }
     }
@@ -108,17 +108,17 @@ impl FormDataMethods for FormData {
         self.data.borrow().contains_key(&Atom::from(name.0))
     }
 
     #[allow(unrooted_must_root)]
     // https://xhr.spec.whatwg.org/#dom-formdata-set
     fn Set(&self, name: USVString, value: BlobOrUSVString) {
         let val = match value {
             BlobOrUSVString::USVString(s) => FormDatum::StringData(s.0),
-            BlobOrUSVString::Blob(b) => FormDatum::BlobData(JS::from_rooted(&b))
+            BlobOrUSVString::Blob(b) => FormDatum::BlobData(JS::from_ref(&*b))
         };
         self.data.borrow_mut().insert(Atom::from(name.0), vec!(val));
     }
 }
 
 
 impl FormData {
     fn get_file_or_blob(&self, blob: &Blob, filename: Option<USVString>) -> Root<Blob> {
--- a/servo/components/script/dom/htmlcanvaselement.rs
+++ b/servo/components/script/dom/htmlcanvaselement.rs
@@ -140,17 +140,17 @@ impl HTMLCanvasElement {
         })
     }
 
     pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
         if self.context.borrow().is_none() {
             let window = window_from_node(self);
             let size = self.get_size();
             let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
-            *self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
+            *self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_ref(&*context)));
         }
 
         match *self.context.borrow().as_ref().unwrap() {
             CanvasContext::Context2d(ref context) => Some(Root::from_ref(&*context)),
             _   => None,
         }
     }
 
@@ -170,17 +170,17 @@ impl HTMLCanvasElement {
                     return None;
                 }
             } else {
                 GLContextAttributes::default()
             };
 
             let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
 
-            *self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
+            *self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_ref(&*ctx)));
         }
 
         if let Some(CanvasContext::WebGL(ref context)) = *self.context.borrow() {
             Some(Root::from_ref(&*context))
         } else {
             None
         }
     }
--- a/servo/components/script/dom/htmltableelement.rs
+++ b/servo/components/script/dom/htmltableelement.rs
@@ -138,17 +138,17 @@ impl HTMLTableElementMethods for HTMLTab
                         || self.sections.iter().any(|ref section| section.is_parent_of(elem.upcast())))
             }
         }
 
         let filter = TableRowFilter {
             sections: self.upcast::<Node>()
                           .children()
                           .filter_map(|ref node|
-                                node.downcast::<HTMLTableSectionElement>().map(|_| JS::from_rooted(node)))
+                                node.downcast::<HTMLTableSectionElement>().map(|_| JS::from_ref(&**node)))
                           .collect()
         };
         HTMLCollection::new(window_from_node(self).r(), self.upcast(), box filter)
     }
 
     // https://html.spec.whatwg.org/multipage/#dom-table-caption
     fn GetCaption(&self) -> Option<Root<HTMLTableCaptionElement>> {
         self.upcast::<Node>().children().filter_map(Root::downcast).next()
--- a/servo/components/script/dom/node.rs
+++ b/servo/components/script/dom/node.rs
@@ -1512,17 +1512,17 @@ impl Node {
                 let index = child.index();
                 // Steps 2.1-2.
                 parent.ranges.increase_above(parent, index, count);
             }
         }
         let mut new_nodes = RootedVec::new();
         let new_nodes = if let NodeTypeId::DocumentFragment = node.type_id() {
             // Step 3.
-            new_nodes.extend(node.children().map(|kid| JS::from_rooted(&kid)));
+            new_nodes.extend(node.children().map(|kid| JS::from_ref(&*kid)));
             // Step 4: mutation observers.
             // Step 5.
             for kid in new_nodes.r() {
                 Node::remove(*kid, node, SuppressObserver::Suppressed);
             }
             vtable_for(&node).children_changed(&ChildrenMutation::replace_all(new_nodes.r(), &[]));
             new_nodes.r()
         } else {
@@ -1558,17 +1558,17 @@ impl Node {
             Node::adopt(node, &*parent.owner_doc());
         }
         // Step 2.
         let removed_nodes = parent.children().collect::<RootedVec<_>>();
         // Step 3.
         let mut added_nodes = RootedVec::new();
         let added_nodes = if let Some(node) = node.as_ref() {
             if let NodeTypeId::DocumentFragment = node.type_id() {
-                added_nodes.extend(node.children().map(|child| JS::from_rooted(&child)));
+                added_nodes.extend(node.children().map(|child| JS::from_ref(&*child)));
                 added_nodes.r()
             } else {
                 ref_slice(node)
             }
         } else {
             &[] as &[&Node]
         };
         // Step 4.
@@ -2101,17 +2101,17 @@ impl NodeMethods for Node {
             Some(child)
         } else {
             None
         };
 
         // Step 12.
         let mut nodes = RootedVec::new();
         let nodes = if node.type_id() == NodeTypeId::DocumentFragment {
-            nodes.extend(node.children().map(|node| JS::from_rooted(&node)));
+            nodes.extend(node.children().map(|node| JS::from_ref(&*node)));
             nodes.r()
         } else {
             ref_slice(&node)
         };
 
         // Step 13.
         Node::insert(node, self, reference_child, SuppressObserver::Suppressed);
 
--- a/servo/components/script/dom/nodelist.rs
+++ b/servo/components/script/dom/nodelist.rs
@@ -38,17 +38,17 @@ impl NodeList {
     #[allow(unrooted_must_root)]
     pub fn new(window: &Window, list_type: NodeListType) -> Root<NodeList> {
         reflect_dom_object(box NodeList::new_inherited(list_type),
                            GlobalRef::Window(window), NodeListBinding::Wrap)
     }
 
     pub fn new_simple_list<T>(window: &Window, iter: T) -> Root<NodeList>
                               where T: Iterator<Item=Root<Node>> {
-        NodeList::new(window, NodeListType::Simple(iter.map(|r| JS::from_rooted(&r)).collect()))
+        NodeList::new(window, NodeListType::Simple(iter.map(|r| JS::from_ref(&*r)).collect()))
     }
 
     pub fn new_child_list(window: &Window, node: &Node) -> Root<NodeList> {
         NodeList::new(window, NodeListType::Children(ChildrenList::new(node)))
     }
 
     pub fn empty(window: &Window) -> Root<NodeList> {
         NodeList::new(window, NodeListType::Simple(vec![]))
--- a/servo/components/script/dom/performance.rs
+++ b/servo/components/script/dom/performance.rs
@@ -21,17 +21,17 @@ pub struct Performance {
 }
 
 impl Performance {
     fn new_inherited(window: &Window,
                      navigation_start: u64,
                      navigation_start_precise: f64) -> Performance {
         Performance {
             reflector_: Reflector::new(),
-            timing: JS::from_rooted(&PerformanceTiming::new(window,
+            timing: JS::from_ref(&*PerformanceTiming::new(window,
                                                             navigation_start,
                                                             navigation_start_precise)),
         }
     }
 
     pub fn new(window: &Window,
                navigation_start: u64,
                navigation_start_precise: f64) -> Root<Performance> {
--- a/servo/components/script/dom/radionodelist.rs
+++ b/servo/components/script/dom/radionodelist.rs
@@ -33,17 +33,17 @@ impl RadioNodeList {
     pub fn new(window: &Window, list_type: NodeListType) -> Root<RadioNodeList> {
         reflect_dom_object(box RadioNodeList::new_inherited(list_type),
                            GlobalRef::Window(window),
                            RadioNodeListBinding::Wrap)
     }
 
     pub fn new_simple_list<T>(window: &Window, iter: T) -> Root<RadioNodeList>
                               where T: Iterator<Item=Root<Node>> {
-        RadioNodeList::new(window, NodeListType::Simple(iter.map(|r| JS::from_rooted(&r)).collect()))
+        RadioNodeList::new(window, NodeListType::Simple(iter.map(|r| JS::from_ref(&*r)).collect()))
     }
 
     pub fn empty(window: &Window) -> Root<RadioNodeList> {
         RadioNodeList::new(window, NodeListType::Simple(vec![]))
     }
 
     // FIXME: This shouldn't need to be implemented here since NodeList (the parent of
     // RadioNodeList) implements Length
--- a/servo/components/script/dom/xmlhttprequest.rs
+++ b/servo/components/script/dom/xmlhttprequest.rs
@@ -152,17 +152,17 @@ pub struct XMLHttpRequest {
 
 impl XMLHttpRequest {
     fn new_inherited(global: GlobalRef) -> XMLHttpRequest {
         XMLHttpRequest {
             eventtarget: XMLHttpRequestEventTarget::new_inherited(),
             ready_state: Cell::new(XMLHttpRequestState::Unsent),
             timeout: Cell::new(0u32),
             with_credentials: Cell::new(false),
-            upload: JS::from_rooted(&XMLHttpRequestUpload::new(global)),
+            upload: JS::from_ref(&*XMLHttpRequestUpload::new(global)),
             response_url: DOMRefCell::new(String::from("")),
             status: Cell::new(0),
             status_text: DOMRefCell::new(ByteString::new(vec!())),
             response: DOMRefCell::new(ByteString::new(vec!())),
             response_type: Cell::new(XMLHttpRequestResponseType::_empty),
             response_xml: Default::default(),
             response_blob: Default::default(),
             response_json: MutHeapJSVal::new(),