From a5d7240534336850c7168ae020d918714406fd6a Mon Sep 17 00:00:00 2001 From: Tetsuharu OHZEKI Date: Sun, 11 Jan 2015 04:25:10 +0900 Subject: [PATCH 1/8] Introduce LayoutJS --- components/script/dom/bindings/DESIGN.md | 3 +- components/script/dom/bindings/js.rs | 68 ++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/components/script/dom/bindings/DESIGN.md b/components/script/dom/bindings/DESIGN.md index e47d7467609..b97bac77e68 100644 --- a/components/script/dom/bindings/DESIGN.md +++ b/components/script/dom/bindings/DESIGN.md @@ -33,8 +33,9 @@ In the `_finalize()` function the pointer of the Rusty DOM object that is contai For supporting SpiderMonkey’s exact GC rooting, we introduce [some types](https://github.com/mozilla/servo/wiki/Using-DOM-types): - `JS` is used for the DOM typed field in a DOM type structure. The GC can trace them recursively while the enclosing DOM object (maybe root) is alive. + - `LayoutJS` is specialized `JS` to use in layout. `Layout*Helper` must be implemented on this type to prevent calling methods from non layout code. - `Temporary` is used as a return value for functions returning a DOM type. They are rooted for the duration of their lifetime. But a retun value gets moved around which can break the LIFO ordering constraint. Thus we need to introduce `Root`. - `Root` contains the pointer to `JSObject` which the represented DOM type has. SpiderMonkey's conservative stack scanner scans it's pointers and marks a pointed `JSObject` as GC root. - `JSRef` is just a reference to the value rooted by `Root`. - `RootCollection` is used to dynamically check if rooting satisfies LIFO ordering, because SpiderMonkey's GC requires LIFO order (See also: [Exact Stack Rooting - Storing a GCPointer on the CStack](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting)). - - `MutHeap` is a version of `Cell` that is safe to use for internal mutability of Spidermonkey heap objects like `JSVal` and `JS` \ No newline at end of file + - `MutHeap` is a version of `Cell` that is safe to use for internal mutability of Spidermonkey heap objects like `JSVal` and `JS` diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index 3c9eba38911..2e229a28df3 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -129,8 +129,25 @@ pub struct JS { ptr: NonZero<*const T> } +impl JS { + /// Returns `LayoutJS` containing the same pointer. + fn to_layout(self) -> LayoutJS { + LayoutJS { + ptr: self.ptr.clone() + } + } +} + +/// This is specialized `JS` to use in under `layout` crate. +/// `Layout*Helpers` traits must be implemented on this. +pub struct LayoutJS { + ptr: NonZero<*const T> +} + impl Copy for JS {} +impl Copy for LayoutJS {} + impl PartialEq for JS { #[allow(unrooted_must_root)] fn eq(&self, other: &JS) -> bool { @@ -138,6 +155,13 @@ impl PartialEq for JS { } } +impl PartialEq for LayoutJS { + #[allow(unrooted_must_root)] + fn eq(&self, other: &LayoutJS) -> bool { + self.ptr == other.ptr + } +} + impl Clone for JS { #[inline] fn clone(&self) -> JS { @@ -147,6 +171,15 @@ impl Clone for JS { } } +impl Clone for LayoutJS { + #[inline] + fn clone(&self) -> LayoutJS { + LayoutJS { + ptr: self.ptr.clone() + } + } +} + impl JS { /// Create a new JS-owned value wrapped from an address known to be a `Node` pointer. pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS { @@ -198,6 +231,15 @@ impl Reflectable for JS { } } +// XXXjdm same above +impl Reflectable for LayoutJS { + fn reflector<'a>(&'a self) -> &'a Reflector { + unsafe { + (*self.unsafe_get()).reflector() + } + } +} + /// A trait to be implemented for JS-managed types that can be stored in /// mutable member fields. /// @@ -296,6 +338,12 @@ impl MutNullableJS { self.ptr.get() } + /// Retrieve a copy of the inner optional `JS` as `LayoutJS`. + /// For use by layout, which can't use safe types like Temporary. + pub unsafe fn get_inner_as_layout(&self) -> Option> { + self.get_inner().map(|js| js.to_layout()) + } + /// Retrieve a copy of the current inner value. If it is `None`, it is /// initialized with the result of `cb` first. pub fn or_init(&self, cb: F) -> Temporary @@ -313,9 +361,8 @@ impl MutNullableJS { } impl JS { - /// Returns an unsafe pointer to the interior of this object. This is the - /// only method that be safely accessed from layout. (The fact that this is - /// unsafe is what necessitates the layout wrappers.) + /// Returns an unsafe pointer to the interior of this object. + /// This should only be used by the DOM bindings. pub unsafe fn unsafe_get(&self) -> *const T { *self.ptr } @@ -328,6 +375,15 @@ impl JS { } } +impl LayoutJS { + /// Returns an unsafe pointer to the interior of this JS object without touching the borrow + /// flags. This is the only method that be safely accessed from layout. (The fact that this + /// is unsafe is what necessitates the layout wrappers.) + pub unsafe fn unsafe_get(&self) -> *const T { + *self.ptr + } +} + impl JS { /// Return `self` as a `JS` of another type. //XXXjdm It would be lovely if this could be private. @@ -341,6 +397,12 @@ impl JS { } } +impl LayoutJS { + /// Return `self` as a `LayoutJS` of another type. + pub unsafe fn transmute_copy(&self) -> LayoutJS { + mem::transmute_copy(self) + } +} /// Get an `Option>` out of an `Option>` pub trait RootedReference { From e2bd9eadd85618d9fed4734f80931964b86d134a Mon Sep 17 00:00:00 2001 From: Tetsuharu OHZEKI Date: Sun, 11 Jan 2015 04:33:33 +0900 Subject: [PATCH 2/8] LayoutJS implements Layout*Helpers instead of JS. --- .../script/dom/canvasrenderingcontext2d.rs | 4 +- components/script/dom/document.rs | 4 +- components/script/dom/element.rs | 6 +-- components/script/dom/htmlcanvaselement.rs | 6 +-- components/script/dom/htmlimageelement.rs | 4 +- components/script/dom/htmlinputelement.rs | 10 ++--- components/script/dom/htmltextareaelement.rs | 4 +- components/script/dom/node.rs | 40 +++++++++---------- 8 files changed, 39 insertions(+), 39 deletions(-) diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index a1eb1af9997..c157714b742 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding; use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods; use dom::bindings::global::{GlobalRef, GlobalField}; -use dom::bindings::js::{JS, JSRef, Temporary}; +use dom::bindings::js::{JS, JSRef, LayoutJS, Temporary}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::htmlcanvaselement::HTMLCanvasElement; @@ -50,7 +50,7 @@ pub trait LayoutCanvasRenderingContext2DHelpers { unsafe fn get_renderer(&self) -> Sender; } -impl LayoutCanvasRenderingContext2DHelpers for JS { +impl LayoutCanvasRenderingContext2DHelpers for LayoutJS { unsafe fn get_renderer(&self) -> Sender { (*self.unsafe_get()).renderer.clone() } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index d2775d3e5aa..859720a28fc 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -23,7 +23,7 @@ use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{NotSupported, InvalidCharacter}; use dom::bindings::error::Error::{HierarchyRequest, NamespaceError}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, TemporaryPushable}; +use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable}; use dom::bindings::js::{OptionalRootable, RootedReference}; use dom::bindings::utils::reflect_dom_object; use dom::bindings::utils::xml_name_type; @@ -395,7 +395,7 @@ pub trait LayoutDocumentHelpers { unsafe fn is_html_document_for_layout(&self) -> bool; } -impl LayoutDocumentHelpers for JS { +impl LayoutDocumentHelpers for LayoutJS { #[allow(unrooted_must_root)] #[inline] unsafe fn is_html_document_for_layout(&self) -> bool { diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 9b74c0cb5c9..943e4139dde 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -23,7 +23,7 @@ use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, HTMLTextA use dom::bindings::codegen::InheritTypes::{HTMLTableSectionElementDerived, NodeCast}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{NamespaceError, InvalidCharacter, Syntax}; -use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, TemporaryPushable}; +use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable}; use dom::bindings::js::{OptionalRootable, Root}; use dom::bindings::utils::xml_name_type; use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName}; @@ -376,13 +376,13 @@ pub trait LayoutElementHelpers { unsafe fn has_attr_for_layout(&self, namespace: &Namespace, name: &Atom) -> bool; } -impl LayoutElementHelpers for JS { +impl LayoutElementHelpers for LayoutJS { #[inline] unsafe fn html_element_in_html_document_for_layout(&self) -> bool { if (*self.unsafe_get()).namespace != ns!(HTML) { return false } - let node: JS = self.transmute_copy(); + let node: LayoutJS = self.transmute_copy(); node.owner_doc_for_layout().is_html_document_for_layout() } diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index a9606caf923..60ff0f88f82 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElemen use dom::bindings::codegen::InheritTypes::HTMLCanvasElementDerived; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary}; +use dom::bindings::js::{MutNullableJS, JSRef, LayoutJS, Temporary}; use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers}; use dom::document::Document; use dom::element::{Element, AttributeHandlers}; @@ -68,9 +68,9 @@ pub trait LayoutHTMLCanvasElementHelpers { unsafe fn get_canvas_height(&self) -> u32; } -impl LayoutHTMLCanvasElementHelpers for JS { +impl LayoutHTMLCanvasElementHelpers for LayoutJS { unsafe fn get_renderer(&self) -> Option> { - let context = (*self.unsafe_get()).context.get_inner(); + let context = (*self.unsafe_get()).context.get_inner_as_layout(); context.map(|cx| cx.get_renderer()) } diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index c555e5c50e4..913f69c0553 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -8,7 +8,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::HTMLImageElementBinding; use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods; use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLElementCast, HTMLImageElementDerived}; -use dom::bindings::js::{JS, JSRef, Temporary}; +use dom::bindings::js::{JSRef, LayoutJS, Temporary}; use dom::document::{Document, DocumentHelpers}; use dom::element::Element; use dom::element::AttributeHandlers; @@ -88,7 +88,7 @@ pub trait LayoutHTMLImageElementHelpers { unsafe fn image(&self) -> Option; } -impl LayoutHTMLImageElementHelpers for JS { +impl LayoutHTMLImageElementHelpers for LayoutJS { unsafe fn image(&self) -> Option { (*self.unsafe_get()).image.borrow_for_layout().clone() } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index e99bdaf3fcf..ede6ee71fb0 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -15,7 +15,7 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLInp use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLFieldSetElementDerived, EventTargetCast}; use dom::bindings::codegen::InheritTypes::KeyboardEventCast; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Comparable, JS, JSRef, Root, Temporary, OptionalRootable}; +use dom::bindings::js::{Comparable, JSRef, LayoutJS, Root, Temporary, OptionalRootable}; use dom::bindings::js::{ResultRootable, RootedReference, MutNullableJS}; use dom::document::{Document, DocumentHelpers}; use dom::element::{AttributeHandlers, Element}; @@ -140,15 +140,15 @@ pub trait RawLayoutHTMLInputElementHelpers { unsafe fn get_size_for_layout(&self) -> u32; } -impl LayoutHTMLInputElementHelpers for JS { +impl LayoutHTMLInputElementHelpers for LayoutJS { #[allow(unrooted_must_root)] unsafe fn get_value_for_layout(self) -> String { - unsafe fn get_raw_textinput_value(input: JS) -> String { + unsafe fn get_raw_textinput_value(input: LayoutJS) -> String { (*input.unsafe_get()).textinput.borrow_for_layout().get_content() } - unsafe fn get_raw_attr_value(input: JS) -> Option { - let elem: JS = input.transmute_copy(); + unsafe fn get_raw_attr_value(input: LayoutJS) -> Option { + let elem: LayoutJS = input.transmute_copy(); (*elem.unsafe_get()).get_attr_val_for_layout(&ns!(""), &atom!("value")) .map(|s| s.to_owned()) } diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index ed6a8c8f06a..7196b4ff891 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -12,7 +12,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast}; use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementDerived, HTMLFieldSetElementDerived}; use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, TextDerived}; -use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable}; +use dom::bindings::js::{JSRef, LayoutJS, Temporary, OptionalRootable}; use dom::document::{Document, DocumentHelpers}; use dom::element::{Element, AttributeHandlers}; use dom::event::Event; @@ -58,7 +58,7 @@ pub trait RawLayoutHTMLTextAreaElementHelpers { unsafe fn get_rows_for_layout(&self) -> u32; } -impl LayoutHTMLTextAreaElementHelpers for JS { +impl LayoutHTMLTextAreaElementHelpers for LayoutJS { #[allow(unrooted_must_root)] unsafe fn get_value_for_layout(self) -> String { (*self.unsafe_get()).textinput.borrow_for_layout().get_content() diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 38b6846193c..745c5a3a135 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -23,7 +23,7 @@ use dom::bindings::conversions; use dom::bindings::error::Fallible; use dom::bindings::error::Error::{NotFound, HierarchyRequest, Syntax}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, Root}; +use dom::bindings::js::{JS, JSRef, LayoutJS, RootedReference, Temporary, Root}; use dom::bindings::js::{TemporaryPushable, OptionalRootedRootable}; use dom::bindings::js::{ResultRootable, OptionalRootable, MutNullableJS}; use dom::bindings::trace::JSTraceable; @@ -914,20 +914,20 @@ pub fn from_untrusted_node_address(runtime: *mut JSRuntime, candidate: Untrusted pub trait LayoutNodeHelpers { unsafe fn type_id_for_layout(&self) -> NodeTypeId; - unsafe fn parent_node_ref(&self) -> Option>; - unsafe fn first_child_ref(&self) -> Option>; - unsafe fn last_child_ref(&self) -> Option>; - unsafe fn prev_sibling_ref(&self) -> Option>; - unsafe fn next_sibling_ref(&self) -> Option>; + unsafe fn parent_node_ref(&self) -> Option>; + unsafe fn first_child_ref(&self) -> Option>; + unsafe fn last_child_ref(&self) -> Option>; + unsafe fn prev_sibling_ref(&self) -> Option>; + unsafe fn next_sibling_ref(&self) -> Option>; - unsafe fn owner_doc_for_layout(&self) -> JS; + unsafe fn owner_doc_for_layout(&self) -> LayoutJS; unsafe fn is_element_for_layout(&self) -> bool; unsafe fn get_flag(self, flag: NodeFlags) -> bool; unsafe fn set_flag(self, flag: NodeFlags, value: bool); } -impl LayoutNodeHelpers for JS { +impl LayoutNodeHelpers for LayoutJS { #[inline] unsafe fn type_id_for_layout(&self) -> NodeTypeId { (*self.unsafe_get()).type_id @@ -939,33 +939,33 @@ impl LayoutNodeHelpers for JS { } #[inline] - unsafe fn parent_node_ref(&self) -> Option> { - (*self.unsafe_get()).parent_node.get_inner() + unsafe fn parent_node_ref(&self) -> Option> { + (*self.unsafe_get()).parent_node.get_inner_as_layout() } #[inline] - unsafe fn first_child_ref(&self) -> Option> { - (*self.unsafe_get()).first_child.get_inner() + unsafe fn first_child_ref(&self) -> Option> { + (*self.unsafe_get()).first_child.get_inner_as_layout() } #[inline] - unsafe fn last_child_ref(&self) -> Option> { - (*self.unsafe_get()).last_child.get_inner() + unsafe fn last_child_ref(&self) -> Option> { + (*self.unsafe_get()).last_child.get_inner_as_layout() } #[inline] - unsafe fn prev_sibling_ref(&self) -> Option> { - (*self.unsafe_get()).prev_sibling.get_inner() + unsafe fn prev_sibling_ref(&self) -> Option> { + (*self.unsafe_get()).prev_sibling.get_inner_as_layout() } #[inline] - unsafe fn next_sibling_ref(&self) -> Option> { - (*self.unsafe_get()).next_sibling.get_inner() + unsafe fn next_sibling_ref(&self) -> Option> { + (*self.unsafe_get()).next_sibling.get_inner_as_layout() } #[inline] - unsafe fn owner_doc_for_layout(&self) -> JS { - (*self.unsafe_get()).owner_doc.get_inner().unwrap() + unsafe fn owner_doc_for_layout(&self) -> LayoutJS { + (*self.unsafe_get()).owner_doc.get_inner_as_layout().unwrap() } #[inline] From 6b1e2bd11ca73777283ad4953e8fc07a3323eca0 Mon Sep 17 00:00:00 2001 From: Tetsuharu OHZEKI Date: Mon, 12 Jan 2015 02:17:58 +0900 Subject: [PATCH 3/8] Use LayoutJS in layout crate. --- components/layout/layout_task.rs | 6 +-- components/layout/util.rs | 8 ++-- components/layout/wrapper.rs | 70 ++++++++++++++-------------- components/script/dom/bindings/js.rs | 8 ++++ 4 files changed, 50 insertions(+), 42 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 9523585785f..b9bdc48a3ea 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -32,7 +32,7 @@ use gfx::paint_task::{PaintChan, PaintLayer}; use gfx::paint_task::Msg as PaintMsg; use layout_traits::{LayoutControlMsg, LayoutTaskFactory}; use log; -use script::dom::bindings::js::JS; +use script::dom::bindings::js::{JS, LayoutJS}; use script::dom::node::{LayoutDataRef, Node, NodeTypeId}; use script::dom::element::ElementTypeId; use script::dom::htmlelement::HTMLElementTypeId; @@ -719,8 +719,8 @@ impl LayoutTask { // FIXME: Isolate this transmutation into a "bridge" module. // FIXME(rust#16366): The following line had to be moved because of a // rustc bug. It should be in the next unsafe block. - let mut node: JS = unsafe { - JS::from_trusted_node_address(data.document_root) + let mut node: LayoutJS = unsafe { + JS::from_trusted_node_address(data.document_root).to_layout() }; let node: &mut LayoutNode = unsafe { mem::transmute(&mut node) diff --git a/components/layout/util.rs b/components/layout/util.rs index e04bbfbbd7e..984c2c44657 100644 --- a/components/layout/util.rs +++ b/components/layout/util.rs @@ -10,7 +10,7 @@ use wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; use gfx::display_list::OpaqueNode; use gfx; use libc::uintptr_t; -use script::dom::bindings::js::JS; +use script::dom::bindings::js::{JS, LayoutJS}; use script::dom::bindings::utils::Reflectable; use script::dom::node::{Node, SharedLayoutData}; use script::layout_interface::{LayoutChan, TrustedNodeAddress}; @@ -126,7 +126,7 @@ pub trait OpaqueNodeMethods { fn from_script_node(node: TrustedNodeAddress) -> Self; /// Converts a DOM node to an `OpaqueNode'. - fn from_jsmanaged(node: &JS) -> Self; + fn from_jsmanaged(node: &LayoutJS) -> Self; /// Converts this node to an `UntrustedNodeAddress`. An `UntrustedNodeAddress` is just the type /// of node that script expects to receive in a hit test. @@ -150,11 +150,11 @@ impl OpaqueNodeMethods for OpaqueNode { fn from_script_node(node: TrustedNodeAddress) -> OpaqueNode { unsafe { - OpaqueNodeMethods::from_jsmanaged(&JS::from_trusted_node_address(node)) + OpaqueNodeMethods::from_jsmanaged(&JS::from_trusted_node_address(node).to_layout()) } } - fn from_jsmanaged(node: &JS) -> OpaqueNode { + fn from_jsmanaged(node: &LayoutJS) -> OpaqueNode { unsafe { let ptr: uintptr_t = mem::transmute(node.reflector().get_jsobject()); OpaqueNode(ptr) diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 039073e8795..e05f005c380 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -12,7 +12,7 @@ //! //! 1. Layout is not allowed to mutate the DOM. //! -//! 2. Layout is not allowed to see anything with `JS` in the name, because it could hang +//! 2. Layout is not allowed to see anything with `LayoutJS` in the name, because it could hang //! onto these objects and cause use-after-free. //! //! When implementing wrapper functions, be careful that you do not touch the borrow flags, or you @@ -43,7 +43,7 @@ use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElemen use script::dom::bindings::codegen::InheritTypes::{HTMLCanvasElementCast, HTMLImageElementCast}; use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, HTMLTextAreaElementCast}; use script::dom::bindings::codegen::InheritTypes::{NodeCast, TextCast}; -use script::dom::bindings::js::JS; +use script::dom::bindings::js::{JS, LayoutJS}; use script::dom::element::{Element, ElementTypeId}; use script::dom::element::{LayoutElementHelpers, RawLayoutElementHelpers}; use script::dom::htmlelement::HTMLElementTypeId; @@ -75,15 +75,15 @@ use url::Url; /// Allows some convenience methods on generic layout nodes. pub trait TLayoutNode { /// Creates a new layout node with the same lifetime as this layout node. - unsafe fn new_with_this_lifetime(&self, node: &JS) -> Self; + unsafe fn new_with_this_lifetime(&self, node: &LayoutJS) -> Self; /// Returns the type ID of this node. Fails if this node is borrowed mutably. Returns `None` /// if this is a pseudo-element; otherwise, returns `Some`. fn type_id(&self) -> Option; - /// Returns the interior of this node as a `JS`. This is highly unsafe for layout to + /// Returns the interior of this node as a `LayoutJS`. This is highly unsafe for layout to /// call and as such is marked `unsafe`. - unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS; + unsafe fn get_jsmanaged<'a>(&'a self) -> &'a LayoutJS; /// Returns the interior of this node as a `Node`. This is highly unsafe for layout to call /// and as such is marked `unsafe`. @@ -110,8 +110,8 @@ pub trait TLayoutNode { /// FIXME(pcwalton): Don't copy URLs. fn image_url(&self) -> Option { unsafe { - match HTMLImageElementCast::to_js(self.get_jsmanaged()) { - Some(elem) => elem.image().as_ref().map(|url| (*url).clone()), + match HTMLImageElementCast::to_js(&self.get_jsmanaged().to_script()) { + Some(elem) => elem.to_layout().image().as_ref().map(|url| (*url).clone()), None => panic!("not an image!") } } @@ -119,22 +119,22 @@ pub trait TLayoutNode { fn get_renderer(&self) -> Option> { unsafe { - let canvas_element: Option> = HTMLCanvasElementCast::to_js(self.get_jsmanaged()); - canvas_element.and_then(|elem| elem.get_renderer()) + let canvas_element: Option> = HTMLCanvasElementCast::to_js(&self.get_jsmanaged().to_script()); + canvas_element.and_then(|elem| elem.to_layout().get_renderer()) } } fn get_canvas_width(&self) -> u32 { unsafe { - let canvas_element: Option> = HTMLCanvasElementCast::to_js(self.get_jsmanaged()); - canvas_element.unwrap().get_canvas_width() + let canvas_element: Option> = HTMLCanvasElementCast::to_js(&self.get_jsmanaged().to_script()); + canvas_element.unwrap().to_layout().get_canvas_width() } } fn get_canvas_height(&self) -> u32 { unsafe { - let canvas_element: Option> = HTMLCanvasElementCast::to_js(self.get_jsmanaged()); - canvas_element.unwrap().get_canvas_height() + let canvas_element: Option> = HTMLCanvasElementCast::to_js(&self.get_jsmanaged().to_script()); + canvas_element.unwrap().to_layout().get_canvas_height() } } @@ -143,7 +143,7 @@ pub trait TLayoutNode { fn iframe_pipeline_and_subpage_ids(&self) -> (PipelineId, SubpageId) { unsafe { let iframe_element: JS = - match HTMLIFrameElementCast::to_js(self.get_jsmanaged()) { + match HTMLIFrameElementCast::to_js(&self.get_jsmanaged().to_script()) { Some(elem) => elem, None => panic!("not an iframe element!") }; @@ -162,11 +162,11 @@ pub trait TLayoutNode { } /// A wrapper so that layout can access only the methods that it should have access to. Layout must -/// only ever see these and must never see instances of `JS`. +/// only ever see these and must never see instances of `LayoutJS`. #[derive(Copy)] pub struct LayoutNode<'a> { /// The wrapped node. - node: JS, + node: LayoutJS, /// Being chained to a ContravariantLifetime prevents `LayoutNode`s from escaping. pub chain: ContravariantLifetime<'a>, @@ -189,7 +189,7 @@ impl<'a> PartialEq for LayoutNode<'a> { } impl<'ln> TLayoutNode for LayoutNode<'ln> { - unsafe fn new_with_this_lifetime(&self, node: &JS) -> LayoutNode<'ln> { + unsafe fn new_with_this_lifetime(&self, node: &LayoutJS) -> LayoutNode<'ln> { LayoutNode { node: node.transmute_copy(), chain: self.chain, @@ -202,7 +202,7 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> { } } - unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS { + unsafe fn get_jsmanaged<'a>(&'a self) -> &'a LayoutJS { &self.node } @@ -214,15 +214,15 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> { fn text(&self) -> String { unsafe { - let text: Option> = TextCast::to_js(self.get_jsmanaged()); + let text: Option> = TextCast::to_js(&self.get_jsmanaged().to_script()); if let Some(text) = text { return (*text.unsafe_get()).characterdata().data_for_layout().to_owned(); } - let input: Option> = HTMLInputElementCast::to_js(self.get_jsmanaged()); + let input: Option> = HTMLInputElementCast::to_js(&self.get_jsmanaged().to_script()); if let Some(input) = input { return input.get_value_for_layout(); } - let area: Option> = HTMLTextAreaElementCast::to_js(self.get_jsmanaged()); + let area: Option> = HTMLTextAreaElementCast::to_js(&self.get_jsmanaged().to_script()); if let Some(area) = area { return area.get_value_for_layout(); } @@ -294,7 +294,7 @@ impl<'ln> LayoutNode<'ln> { } - pub unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS { + pub unsafe fn get_jsmanaged<'a>(&'a self) -> &'a LayoutJS { &self.node } @@ -371,8 +371,8 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> { #[inline] fn as_element(self) -> LayoutElement<'ln> { unsafe { - let elem: JS = match ElementCast::to_js(&self.node) { - Some(elem) => elem, + let elem: LayoutJS = match ElementCast::to_js(&self.node.to_script()) { + Some(elem) => elem.to_layout(), None => panic!("not an element") }; @@ -411,8 +411,8 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> { fn is_html_element_in_html_document(self) -> bool { unsafe { - match ElementCast::to_js(&self.node) { - Some(elem) => elem.html_element_in_html_document_for_layout(), + match ElementCast::to_js(&self.node.to_script()) { + Some(elem) => elem.to_layout().html_element_in_html_document_for_layout(), None => false } } @@ -707,7 +707,7 @@ pub struct ThreadSafeLayoutNode<'ln> { impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> { /// Creates a new layout node with the same lifetime as this layout node. - unsafe fn new_with_this_lifetime(&self, node: &JS) -> ThreadSafeLayoutNode<'ln> { + unsafe fn new_with_this_lifetime(&self, node: &LayoutJS) -> ThreadSafeLayoutNode<'ln> { ThreadSafeLayoutNode { node: LayoutNode { node: node.transmute_copy(), @@ -726,7 +726,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> { self.node.type_id() } - unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS { + unsafe fn get_jsmanaged<'a>(&'a self) -> &'a LayoutJS { self.node.get_jsmanaged() } @@ -824,7 +824,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { #[inline] pub fn as_element(&self) -> ThreadSafeLayoutElement<'ln> { unsafe { - let element = match ElementCast::to_js(self.get_jsmanaged()) { + let element = match ElementCast::to_js(&self.get_jsmanaged().to_script()) { Some(e) => e.unsafe_get(), None => panic!("not an element") }; @@ -936,7 +936,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn is_ignorable_whitespace(&self) -> bool { unsafe { - let text: JS = match TextCast::to_js(self.get_jsmanaged()) { + let text: JS = match TextCast::to_js(&self.get_jsmanaged().to_script()) { Some(text) => text, None => return false }; @@ -960,9 +960,9 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn get_input_value(&self) -> String { unsafe { - let input: Option> = HTMLInputElementCast::to_js(self.get_jsmanaged()); + let input: Option> = HTMLInputElementCast::to_js(&self.get_jsmanaged().to_script()); match input { - Some(input) => input.get_value_for_layout(), + Some(input) => input.to_layout().get_value_for_layout(), None => panic!("not an input element!") } } @@ -970,8 +970,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn get_input_size(&self) -> u32 { unsafe { - match HTMLInputElementCast::to_js(self.get_jsmanaged()) { - Some(input) => input.get_size_for_layout(), + match HTMLInputElementCast::to_js(&self.get_jsmanaged().to_script()) { + Some(input) => input.to_layout().get_size_for_layout(), None => panic!("not an input element!") } } @@ -980,7 +980,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn get_unsigned_integer_attribute(self, attribute: UnsignedIntegerAttribute) -> Option { unsafe { - let elem: Option> = ElementCast::to_js(self.get_jsmanaged()); + let elem: Option> = ElementCast::to_js(&self.get_jsmanaged().to_script()); match elem { Some(element) => { (*element.unsafe_get()).get_unsigned_integer_attribute_for_layout(attribute) diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index 2e229a28df3..f2d00c6d76f 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -144,6 +144,14 @@ pub struct LayoutJS { ptr: NonZero<*const T> } +impl LayoutJS { + pub fn to_script(self) -> JS { + JS { + ptr: self.ptr + } + } +} + impl Copy for JS {} impl Copy for LayoutJS {} From 80a4911f9c44aa544beb5d5ee6e45cbe7b166228 Mon Sep 17 00:00:00 2001 From: Tetsuharu OHZEKI Date: Sun, 25 Jan 2015 02:06:25 +0900 Subject: [PATCH 4/8] Add BarCast::to_layout_js(). --- .../script/dom/bindings/codegen/CodegenRust.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 795204466df..1983cbe41d5 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -5220,7 +5220,7 @@ class GlobalGenRoots(): descriptors = config.getDescriptors(register=True, isCallback=False) allprotos = [CGGeneric("#![allow(unused_imports)]\n"), CGGeneric("use dom::types::*;\n"), - CGGeneric("use dom::bindings::js::{JS, JSRef, Temporary};\n"), + CGGeneric("use dom::bindings::js::{JS, JSRef, LayoutJS, Temporary};\n"), CGGeneric("use dom::bindings::trace::JSTraceable;\n"), CGGeneric("use dom::bindings::utils::Reflectable;\n"), CGGeneric("use js::jsapi::JSTracer;\n\n"), @@ -5279,6 +5279,17 @@ pub trait ${castTraitName} : Sized { } } + #[inline(always)] + #[allow(unrooted_must_root)] + fn to_layout_js(base: &LayoutJS) -> Option> { + unsafe { + match (*base.unsafe_get()).${checkFn}() { + true => Some(base.transmute_copy()), + false => None + } + } + } + #[inline(always)] fn from_ref<'a, T: ${fromBound}+Reflectable>(derived: JSRef<'a, T>) -> JSRef<'a, Self> { unsafe { derived.transmute() } From 8889041c1957232fe1acabb255c131686c4a924a Mon Sep 17 00:00:00 2001 From: Tetsuharu OHZEKI Date: Sun, 25 Jan 2015 02:13:00 +0900 Subject: [PATCH 5/8] Use BarCast::to_layout_js() instead of LayoutJS.to_script(). --- components/layout/wrapper.rs | 50 ++++++++++++++-------------- components/script/dom/bindings/js.rs | 8 ----- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index e05f005c380..baaf848c68c 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -43,7 +43,7 @@ use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElemen use script::dom::bindings::codegen::InheritTypes::{HTMLCanvasElementCast, HTMLImageElementCast}; use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, HTMLTextAreaElementCast}; use script::dom::bindings::codegen::InheritTypes::{NodeCast, TextCast}; -use script::dom::bindings::js::{JS, LayoutJS}; +use script::dom::bindings::js::LayoutJS; use script::dom::element::{Element, ElementTypeId}; use script::dom::element::{LayoutElementHelpers, RawLayoutElementHelpers}; use script::dom::htmlelement::HTMLElementTypeId; @@ -110,8 +110,8 @@ pub trait TLayoutNode { /// FIXME(pcwalton): Don't copy URLs. fn image_url(&self) -> Option { unsafe { - match HTMLImageElementCast::to_js(&self.get_jsmanaged().to_script()) { - Some(elem) => elem.to_layout().image().as_ref().map(|url| (*url).clone()), + match HTMLImageElementCast::to_layout_js(self.get_jsmanaged()) { + Some(elem) => elem.image().as_ref().map(|url| (*url).clone()), None => panic!("not an image!") } } @@ -119,22 +119,22 @@ pub trait TLayoutNode { fn get_renderer(&self) -> Option> { unsafe { - let canvas_element: Option> = HTMLCanvasElementCast::to_js(&self.get_jsmanaged().to_script()); - canvas_element.and_then(|elem| elem.to_layout().get_renderer()) + let canvas_element: Option> = HTMLCanvasElementCast::to_layout_js(self.get_jsmanaged()); + canvas_element.and_then(|elem| elem.get_renderer()) } } fn get_canvas_width(&self) -> u32 { unsafe { - let canvas_element: Option> = HTMLCanvasElementCast::to_js(&self.get_jsmanaged().to_script()); - canvas_element.unwrap().to_layout().get_canvas_width() + let canvas_element: Option> = HTMLCanvasElementCast::to_layout_js(self.get_jsmanaged()); + canvas_element.unwrap().get_canvas_width() } } fn get_canvas_height(&self) -> u32 { unsafe { - let canvas_element: Option> = HTMLCanvasElementCast::to_js(&self.get_jsmanaged().to_script()); - canvas_element.unwrap().to_layout().get_canvas_height() + let canvas_element: Option> = HTMLCanvasElementCast::to_layout_js(self.get_jsmanaged()); + canvas_element.unwrap().get_canvas_height() } } @@ -142,8 +142,8 @@ pub trait TLayoutNode { /// not an iframe element, fails. fn iframe_pipeline_and_subpage_ids(&self) -> (PipelineId, SubpageId) { unsafe { - let iframe_element: JS = - match HTMLIFrameElementCast::to_js(&self.get_jsmanaged().to_script()) { + let iframe_element: LayoutJS = + match HTMLIFrameElementCast::to_layout_js(self.get_jsmanaged()) { Some(elem) => elem, None => panic!("not an iframe element!") }; @@ -214,15 +214,15 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> { fn text(&self) -> String { unsafe { - let text: Option> = TextCast::to_js(&self.get_jsmanaged().to_script()); + let text: Option> = TextCast::to_layout_js(self.get_jsmanaged()); if let Some(text) = text { return (*text.unsafe_get()).characterdata().data_for_layout().to_owned(); } - let input: Option> = HTMLInputElementCast::to_js(&self.get_jsmanaged().to_script()); + let input: Option> = HTMLInputElementCast::to_layout_js(self.get_jsmanaged()); if let Some(input) = input { return input.get_value_for_layout(); } - let area: Option> = HTMLTextAreaElementCast::to_js(&self.get_jsmanaged().to_script()); + let area: Option> = HTMLTextAreaElementCast::to_layout_js(self.get_jsmanaged()); if let Some(area) = area { return area.get_value_for_layout(); } @@ -371,8 +371,8 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> { #[inline] fn as_element(self) -> LayoutElement<'ln> { unsafe { - let elem: LayoutJS = match ElementCast::to_js(&self.node.to_script()) { - Some(elem) => elem.to_layout(), + let elem: LayoutJS = match ElementCast::to_layout_js(&self.node) { + Some(elem) => elem, None => panic!("not an element") }; @@ -411,8 +411,8 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> { fn is_html_element_in_html_document(self) -> bool { unsafe { - match ElementCast::to_js(&self.node.to_script()) { - Some(elem) => elem.to_layout().html_element_in_html_document_for_layout(), + match ElementCast::to_layout_js(&self.node) { + Some(elem) => elem.html_element_in_html_document_for_layout(), None => false } } @@ -824,7 +824,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { #[inline] pub fn as_element(&self) -> ThreadSafeLayoutElement<'ln> { unsafe { - let element = match ElementCast::to_js(&self.get_jsmanaged().to_script()) { + let element = match ElementCast::to_layout_js(self.get_jsmanaged()) { Some(e) => e.unsafe_get(), None => panic!("not an element") }; @@ -936,7 +936,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn is_ignorable_whitespace(&self) -> bool { unsafe { - let text: JS = match TextCast::to_js(&self.get_jsmanaged().to_script()) { + let text: LayoutJS = match TextCast::to_layout_js(self.get_jsmanaged()) { Some(text) => text, None => return false }; @@ -960,9 +960,9 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn get_input_value(&self) -> String { unsafe { - let input: Option> = HTMLInputElementCast::to_js(&self.get_jsmanaged().to_script()); + let input: Option> = HTMLInputElementCast::to_layout_js(self.get_jsmanaged()); match input { - Some(input) => input.to_layout().get_value_for_layout(), + Some(input) => input.get_value_for_layout(), None => panic!("not an input element!") } } @@ -970,8 +970,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn get_input_size(&self) -> u32 { unsafe { - match HTMLInputElementCast::to_js(&self.get_jsmanaged().to_script()) { - Some(input) => input.to_layout().get_size_for_layout(), + match HTMLInputElementCast::to_layout_js(self.get_jsmanaged()) { + Some(input) => input.get_size_for_layout(), None => panic!("not an input element!") } } @@ -980,7 +980,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { pub fn get_unsigned_integer_attribute(self, attribute: UnsignedIntegerAttribute) -> Option { unsafe { - let elem: Option> = ElementCast::to_js(&self.get_jsmanaged().to_script()); + let elem: Option> = ElementCast::to_layout_js(self.get_jsmanaged()); match elem { Some(element) => { (*element.unsafe_get()).get_unsigned_integer_attribute_for_layout(attribute) diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index f2d00c6d76f..2e229a28df3 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -144,14 +144,6 @@ pub struct LayoutJS { ptr: NonZero<*const T> } -impl LayoutJS { - pub fn to_script(self) -> JS { - JS { - ptr: self.ptr - } - } -} - impl Copy for JS {} impl Copy for LayoutJS {} From 9f57fa17d0e5b188b4c33145c659f2abf2315a22 Mon Sep 17 00:00:00 2001 From: Tetsuharu OHZEKI Date: Sun, 25 Jan 2015 02:57:38 +0900 Subject: [PATCH 6/8] Add LayoutJS::from_trusted_node_address() --- components/layout/layout_task.rs | 4 ++-- components/layout/util.rs | 4 ++-- components/script/dom/bindings/js.rs | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index b9bdc48a3ea..285e3889bf3 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -32,7 +32,7 @@ use gfx::paint_task::{PaintChan, PaintLayer}; use gfx::paint_task::Msg as PaintMsg; use layout_traits::{LayoutControlMsg, LayoutTaskFactory}; use log; -use script::dom::bindings::js::{JS, LayoutJS}; +use script::dom::bindings::js::LayoutJS; use script::dom::node::{LayoutDataRef, Node, NodeTypeId}; use script::dom::element::ElementTypeId; use script::dom::htmlelement::HTMLElementTypeId; @@ -720,7 +720,7 @@ impl LayoutTask { // FIXME(rust#16366): The following line had to be moved because of a // rustc bug. It should be in the next unsafe block. let mut node: LayoutJS = unsafe { - JS::from_trusted_node_address(data.document_root).to_layout() + LayoutJS::from_trusted_node_address(data.document_root) }; let node: &mut LayoutNode = unsafe { mem::transmute(&mut node) diff --git a/components/layout/util.rs b/components/layout/util.rs index 984c2c44657..f7692fc3cda 100644 --- a/components/layout/util.rs +++ b/components/layout/util.rs @@ -10,7 +10,7 @@ use wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; use gfx::display_list::OpaqueNode; use gfx; use libc::uintptr_t; -use script::dom::bindings::js::{JS, LayoutJS}; +use script::dom::bindings::js::LayoutJS; use script::dom::bindings::utils::Reflectable; use script::dom::node::{Node, SharedLayoutData}; use script::layout_interface::{LayoutChan, TrustedNodeAddress}; @@ -150,7 +150,7 @@ impl OpaqueNodeMethods for OpaqueNode { fn from_script_node(node: TrustedNodeAddress) -> OpaqueNode { unsafe { - OpaqueNodeMethods::from_jsmanaged(&JS::from_trusted_node_address(node).to_layout()) + OpaqueNodeMethods::from_jsmanaged(&LayoutJS::from_trusted_node_address(node)) } } diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index 2e229a28df3..3b74bd65194 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -191,6 +191,16 @@ impl JS { } } +impl LayoutJS { + /// Create a new JS-owned value wrapped from an address known to be a `Node` pointer. + pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> LayoutJS { + let TrustedNodeAddress(addr) = inner; + LayoutJS { + ptr: NonZero::new(addr as *const Node) + } + } +} + impl JS { /// Create a new JS-owned value wrapped from a raw Rust pointer. pub unsafe fn from_raw(raw: *const T) -> JS { From b7443bef83efd28e97f8184016824b0c176c0821 Mon Sep 17 00:00:00 2001 From: Tetsuharu OHZEKI Date: Sat, 31 Jan 2015 17:19:04 +0900 Subject: [PATCH 7/8] Remove JS.transmute(). --- components/script/dom/bindings/js.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index 3b74bd65194..ee2bf53e238 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -395,12 +395,6 @@ impl LayoutJS { } impl JS { - /// Return `self` as a `JS` of another type. - //XXXjdm It would be lovely if this could be private. - pub unsafe fn transmute(self) -> JS { - mem::transmute(self) - } - /// Return `self` as a `JS` of another type. pub unsafe fn transmute_copy(&self) -> JS { mem::transmute_copy(self) From 2cca095481efb0a62de6d4584b589d89ffab35c0 Mon Sep 17 00:00:00 2001 From: Tetsuharu OHZEKI Date: Sat, 31 Jan 2015 18:17:15 +0900 Subject: [PATCH 8/8] Add LayoutJS.get_jsobject(). --- components/layout/util.rs | 5 ++--- components/script/dom/bindings/js.rs | 16 +++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/components/layout/util.rs b/components/layout/util.rs index f7692fc3cda..270c796781e 100644 --- a/components/layout/util.rs +++ b/components/layout/util.rs @@ -11,7 +11,6 @@ use gfx::display_list::OpaqueNode; use gfx; use libc::uintptr_t; use script::dom::bindings::js::LayoutJS; -use script::dom::bindings::utils::Reflectable; use script::dom::node::{Node, SharedLayoutData}; use script::layout_interface::{LayoutChan, TrustedNodeAddress}; use script_traits::UntrustedNodeAddress; @@ -143,7 +142,7 @@ impl OpaqueNodeMethods for OpaqueNode { fn from_thread_safe_layout_node(node: &ThreadSafeLayoutNode) -> OpaqueNode { unsafe { let abstract_node = node.get_jsmanaged(); - let ptr: uintptr_t = abstract_node.reflector().get_jsobject() as uintptr_t; + let ptr: uintptr_t = abstract_node.get_jsobject() as uintptr_t; OpaqueNode(ptr) } } @@ -156,7 +155,7 @@ impl OpaqueNodeMethods for OpaqueNode { fn from_jsmanaged(node: &LayoutJS) -> OpaqueNode { unsafe { - let ptr: uintptr_t = mem::transmute(node.reflector().get_jsobject()); + let ptr: uintptr_t = node.get_jsobject() as uintptr_t; OpaqueNode(ptr) } } diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index ee2bf53e238..f062eb8cf64 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -144,6 +144,13 @@ pub struct LayoutJS { ptr: NonZero<*const T> } +impl LayoutJS { + /// Get the reflector. + pub unsafe fn get_jsobject(&self) -> *mut JSObject { + (**self.ptr).reflector().get_jsobject() + } +} + impl Copy for JS {} impl Copy for LayoutJS {} @@ -241,15 +248,6 @@ impl Reflectable for JS { } } -// XXXjdm same above -impl Reflectable for LayoutJS { - fn reflector<'a>(&'a self) -> &'a Reflector { - unsafe { - (*self.unsafe_get()).reflector() - } - } -} - /// A trait to be implemented for JS-managed types that can be stored in /// mutable member fields. ///