diff options
author | sendilkumarn <sendilkumarn@live.com> | 2017-08-09 11:18:20 +0800 |
---|---|---|
committer | sendilkumarn <sendilkumarn@live.com> | 2017-09-09 05:56:25 +0530 |
commit | 8b33e0f60e4bb2f089f93412bf84fe17c38e714b (patch) | |
tree | 828b7208557f17a3f35f46806ebe1478a03dec53 /components/script/dom | |
parent | 2719e6570574f2f911a9bf2cc085deeadd4a9ac2 (diff) | |
download | servo-8b33e0f60e4bb2f089f93412bf84fe17c38e714b.tar.gz servo-8b33e0f60e4bb2f089f93412bf84fe17c38e714b.zip |
moving to oncecell
adding oncecell for JS references
removing option<JS<T>> to <JS<T>>
changing return types
removing get method and refactoring the function
changing getElements method
lint fixes
moving to default
simplifying return
ordering
Removing elements
linting
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/bindings/js.rs | 50 | ||||
-rwxr-xr-x | components/script/dom/htmlformelement.rs | 18 |
2 files changed, 57 insertions, 11 deletions
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index abfd9f47eff..976665e4850 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -32,6 +32,7 @@ use dom::bindings::trace::trace_reflector; use dom::node::Node; use heapsize::HeapSizeOf; use js::jsapi::{JSObject, JSTracer}; +use mitochondria::OnceCell; use script_layout_interface::TrustedNodeAddress; use script_thread::STACK_ROOTS; use std::cell::UnsafeCell; @@ -391,6 +392,55 @@ impl<T: DomObject> HeapSizeOf for MutNullableJS<T> { } } +/// A holder that allows to lazily initialize the value only once +/// `JS<T>`, using OnceCell +/// Essentially a `OnceCell<JS<T>>`. +/// +/// This should only be used as a field in other DOM objects; see warning +/// on `JS<T>`. +#[must_root] +pub struct OnceCellJS<T: DomObject> { + ptr: OnceCell<JS<T>>, +} + +impl<T: DomObject> OnceCellJS<T> { + /// Retrieve a copy of the current inner value. If it is `None`, it is + /// initialized with the result of `cb` first. + #[allow(unrooted_must_root)] + pub fn init_once<F>(&self, cb: F) -> &T + where F: FnOnce() -> Root<T> + { + debug_assert!(thread_state::get().is_script()); + &self.ptr.init_once(|| JS::from_ref(&cb())) + } +} + +impl<T: DomObject> Default for OnceCellJS<T> { + #[allow(unrooted_must_root)] + fn default() -> OnceCellJS<T> { + debug_assert!(thread_state::get().is_script()); + OnceCellJS { + ptr: OnceCell::new(), + } + } +} + +impl<T: DomObject> HeapSizeOf for OnceCellJS<T> { + fn heap_size_of_children(&self) -> usize { + // See comment on HeapSizeOf for JS<T>. + 0 + } +} + +#[allow(unrooted_must_root)] +unsafe impl<T: DomObject> JSTraceable for OnceCellJS<T> { + unsafe fn trace(&self, trc: *mut JSTracer) { + if let Some(ptr) = self.ptr.as_ref() { + ptr.trace(trc); + } + } +} + impl<T: DomObject> LayoutJS<T> { /// Returns an unsafe pointer to the interior of this JS object. This is /// the only method that be safely accessed from layout. (The fact that diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 34ce7c25ec1..c3a56954ea5 100755 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::HTMLFormElementBinding::HTMLFormElementMet use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods; use dom::bindings::codegen::Bindings::HTMLTextAreaElementBinding::HTMLTextAreaElementMethods; use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId}; -use dom::bindings::js::{JS, MutNullableJS, Root, RootedReference}; +use dom::bindings::js::{JS, OnceCellJS, Root, RootedReference}; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; @@ -66,7 +66,7 @@ pub struct GenerationId(u32); pub struct HTMLFormElement { htmlelement: HTMLElement, marked_for_reset: Cell<bool>, - elements: MutNullableJS<HTMLFormControlsCollection>, + elements: OnceCellJS<HTMLFormControlsCollection>, generation_id: Cell<GenerationId>, controls: DOMRefCell<Vec<JS<Element>>>, } @@ -168,10 +168,6 @@ impl HTMLFormElementMethods for HTMLFormElement { // https://html.spec.whatwg.org/multipage/#dom-form-elements fn Elements(&self) -> Root<HTMLFormControlsCollection> { - if let Some(elements) = self.elements.get() { - return elements; - } - #[derive(HeapSizeOf, JSTraceable)] struct ElementsFilter { form: Root<HTMLFormElement> @@ -222,11 +218,11 @@ impl HTMLFormElementMethods for HTMLFormElement { } } } - let filter = box ElementsFilter { form: Root::from_ref(self) }; - let window = window_from_node(self); - let elements = HTMLFormControlsCollection::new(&window, self.upcast(), filter); - self.elements.set(Some(&elements)); - elements + Root::from_ref(self.elements.init_once(|| { + let filter = box ElementsFilter { form: Root::from_ref(self) }; + let window = window_from_node(self); + HTMLFormControlsCollection::new(&window, self.upcast(), filter) + })) } // https://html.spec.whatwg.org/multipage/#dom-form-length |