Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upUsing OnceCell<T> from Mitochondria #18059
Conversation
highfive
commented
Aug 13, 2017
highfive
commented
Aug 13, 2017
|
| /// on `JS<T>`. | ||
| #[must_root] | ||
| pub struct OnceCellJS<T: DomObject> { | ||
| ptr: OnceCell<Option<JS<T>>>, |
This comment has been minimized.
This comment has been minimized.
|
|
||
| /// 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<F>(&self, cb: F) -> Root<T> |
This comment has been minimized.
This comment has been minimized.
| debug_assert!(thread_state::get().is_layout()); | ||
| match self.ptr.as_ref() { | ||
| Some(ptr_ref) => { | ||
| ptr::read(ptr_ref).map(|js| js.to_layout()) |
This comment has been minimized.
This comment has been minimized.
| unsafe { | ||
| match self.ptr.as_ref() { | ||
| Some(ptr_ref) => { | ||
| ptr::read(ptr_ref).map(|o| Root::from_ref(&*o)) |
This comment has been minimized.
This comment has been minimized.
| pub fn get(&self) -> Option<Root<T>> { | ||
| debug_assert!(thread_state::get().is_script()); | ||
| unsafe { | ||
| match self.ptr.as_ref() { |
This comment has been minimized.
This comment has been minimized.
| } | ||
|
|
||
| /// Set this `OnceCellJS` to the given value. If it is not already set | ||
| pub fn set(&self, val: Option<&T>) { |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
sendilkumarn
Aug 14, 2017
Author
Contributor
using init_once straight away in or_init method causes the following error
expected type `core::option::Option<T>`
found type `core::option::Option<&dom::bindings::js::JS<T>>`
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| } | ||
|
|
||
| /// Gets the current value out of this object and sets it to `None`. | ||
| pub fn take(&self) -> Option<Root<T>> { |
This comment has been minimized.
This comment has been minimized.
| } | ||
| } | ||
|
|
||
| impl<T: DomObject> PartialEq for OnceCellJS<T> { |
This comment has been minimized.
This comment has been minimized.
| #[cfg(not(debug_assertions))] | ||
| let trace_info = "for DOM object on heap"; | ||
|
|
||
| match self.ptr.as_ref().clone() { |
This comment has been minimized.
This comment has been minimized.
| @@ -603,4 +756,4 @@ unsafe impl<T: DomObject> JSTraceable for Root<T> { | |||
| unsafe fn trace(&self, _: *mut JSTracer) { | |||
| // Already traced. | |||
| } | |||
| } | |||
| } | |||
This comment has been minimized.
This comment has been minimized.
|
|
||
| /// Get a rooted value out of this object | ||
| #[allow(unrooted_must_root)] | ||
| pub fn get(&self) -> Option<Root<T>> { |
This comment has been minimized.
This comment has been minimized.
KiChjang
Aug 14, 2017
Member
I don't think this is the right return type. The whole idea behind the issue is that whenever I call the get method, I shouldn't need to worry about whether the cell is empty or not, and that it will always get the appropriate value for me.
This comment has been minimized.
This comment has been minimized.
sendilkumarn
Aug 15, 2017
Author
Contributor
That makes sense. Since MutNullableJS and MutJS returns Root<T> , I decided to return something similar. Rather here I will return Option<JS<T>>
This comment has been minimized.
This comment has been minimized.
| /// 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 unsafe fn or_init<F>(&self, cb: F) -> &JS<T> |
This comment has been minimized.
This comment has been minimized.
KiChjang
Aug 15, 2017
Member
I'm still not convinced this is an improvement over MutNullableJS<T>. In fact as it stands currently, it is an exact copy of it. Let me reiterate the goals of the issue:
Consider the Elements method in HTMLFormElement. It tries to see if the elements field is a Some; if so, it would return that inner value, and if not, it does a whole chunk of initialization for it, and finally setting that inner value into Some.
What I personally would like to see is to have that method body be reduced into simply self.elements.get(), and perhaps in the new method of the OnceCellJS that houses the list of elements, accept a closure/function that gets called whenever the get method encounters a None for its inner value.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
My comments should be addressed, and then the commits should be squashed together. Also, we can't land this as long as you don't also migrate at least one |
| #[allow(unrooted_must_root)] | ||
| unsafe impl<T: DomObject> JSTraceable for OnceCellJS<T> { | ||
| unsafe fn trace(&self, trc: *mut JSTracer) { | ||
| match self.ptr.as_ref() { |
This comment has been minimized.
This comment has been minimized.
| /// 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 unsafe fn or_init<F>(&self, cb: F) -> &T |
This comment has been minimized.
This comment has been minimized.
nox
Aug 16, 2017
Member
This is still uncorrect.
- It should not be
unsafe. Fshould beFnOnce() -> Root<T>.- The method should only call
init_oncewith a wrapper ofcbconverting theRoot<T>toJS<T>and dereferencing the returnedJS<T>to&T.
This comment has been minimized.
This comment has been minimized.
KiChjang
Aug 16, 2017
Member
I'm still confused as to why this function exists. How is this any different than MutNullableJS?
This comment has been minimized.
This comment has been minimized.
nox
Aug 16, 2017
Member
You cannot retrieve a &T from a MutNullableJS<T>. IMO the method should be named init_once just like in Mitochondria.
|
|
||
| impl<T: DomObject> OnceCellJS<T> { | ||
| /// Create a new `OnceCellJS` with value | ||
| pub fn new(initial: Option<&T>) -> OnceCellJS<T> { |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
sendilkumarn
Aug 16, 2017
Author
Contributor
which makes this function similar to Default::default() Instead, we can change the signature to new_with_value similar to mitochondria
This comment has been minimized.
This comment has been minimized.
KiChjang
Aug 16, 2017
Member
I don't really seem to see that use case at all... Why would you need to provide an initial value when the purpose is to either get it from the OnceCell or run a closure to produce a value?
|
|
||
| impl<T: DomObject> OnceCellJS<T> { | ||
| /// Create a new `OnceCellJS` with value | ||
| pub fn new() -> OnceCellJS<T> { |
This comment has been minimized.
This comment has been minimized.
nox
Aug 21, 2017
Member
Make that the impl of Default for OnceCellJS<T> and this is good to go!
Thanks for keeping up with my comments!
This comment has been minimized.
This comment has been minimized.
sendilkumarn
Aug 22, 2017
Author
Contributor
You mean change this method into default or implement default separately.
This comment has been minimized.
This comment has been minimized.
KiChjang
Aug 22, 2017
Member
Implement the Default trait on OnceCellJS, and move the method body below to be inside of fn default.
|
Am stupid, the PR should be rebased to land. >< |
|
|
| let filter = box ElementsFilter { form: Root::from_ref(self) }; | ||
| let window = window_from_node(self); | ||
| let elements = HTMLFormControlsCollection::new(&window, self.upcast(), filter); | ||
| elements |
This comment has been minimized.
This comment has been minimized.
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
|
@nox is it pending for any other thing? |
|
@bors-servo r=nox |
|
|
|
|
|
|
|
|
Using OnceCell<T> from Mitochondria <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #13402 (github issue number if applicable). <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18059) <!-- Reviewable:end -->
|
|
sendilkumarn commentedAug 13, 2017
•
edited
./mach build -ddoes not report any errors./mach test-tidydoes not report any errorsThis change is