Skip to content
This repository was archived by the owner on Nov 12, 2022. It is now read-only.

Add lifetimes for Handle and MutableHandle #393

Merged
merged 16 commits into from
Mar 27, 2018
Merged

Conversation

marmistrz
Copy link
Contributor

@marmistrz marmistrz commented Mar 4, 2018

Servo compiled fine for me with the following patch set.

Since the From trait consumes the object, I created a raw method for MutableHandle. This is not ideal, since into() would be more idiomatic. Is there anything better I could do or should I just leave it as it is?

There are two questions marked with // REVIEW since I'm not sure if the explicit lifetimes are the same what compiler inferred.

Closes #153.


This change is Reviewable

@jdm
Copy link
Member

jdm commented Mar 5, 2018

This will require some updates to the unit tests, too.

Copy link
Member

@jdm jdm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exciting work! There are some cases where it's really easy to create 'static lifetimes that I'd like to see if we could avoid, though.

@@ -180,7 +181,7 @@ fn clamp_to<D>(d: f64) -> D
// https://heycam.github.io/webidl/#es-void
impl ToJSValConvertible for () {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should modify the ToJSValConvertible trait to accept a lifetime argument and use it for the rval argument.

}
// REVIEW: is this equivalent to?
// pub fn handle(&self) -> Handle<T>
pub fn handle(&'a self) -> Handle<'a, T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it is equivalent. Let's use the explicit form.

src/rust.rs Outdated
RawMutableHandle::from_marked_location(ptr).into()
}

pub fn handle(&self) -> RawHandle<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably return a non-raw handle from this API.

src/rust.rs Outdated
@@ -853,9 +984,9 @@ impl<T: GCMethods + Copy> Heap<T> {
self.ptr.get()
}

pub fn handle(&self) -> Handle<T> {
pub fn handle(&self) -> RawHandle<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely return a non-raw Handle here, and return a MutableHandle from handle_mut that is not using the 'static lifetime.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that it's not using the 'static lifetime now? I'm not so sure of it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not even sure which code is being referred to any more. I believe that any code with a &self argument that returns a Handle will have the lifetime inferred to match the self argument, but it would be valuable to write that out explicitly.

src/rust.rs Outdated
}
}
}

impl<'a> HandleValue<'a> {
pub fn null() -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's be explicit and use HandleValue<'static'> for these methods.

src/rust.rs Outdated
}
}

impl<'a, T> From<RawMutableHandle<T>> for MutableHandle<'a, T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How important are the From<Raw> impls for the safe handles? It makes me uncomfortable that we can create safe handles with 'static lifetimes from arbitrary handles that do not actually have static lifetimes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed.

Handle { ptr: ptr }
}

pub unsafe fn from_marked_location(ptr: *const T) -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this used outside of this crate? If we could avoid making it public, that would be useful.

@marmistrz
Copy link
Contributor Author

Honestly, I don't really have an idea what we could test here. That's just mimicking the Handle's behavior, all the checks are done by the compiler.

@jdm
Copy link
Member

jdm commented Mar 8, 2018

We could write some compile_fail doctests that demonstrate that handle values with lifetimes can't outlive the objects from which they were obtained.

@bors-servo
Copy link
Contributor

☔ The latest upstream changes (presumably #394) made this pull request unmergeable. Please resolve the merge conflicts.

@jdm
Copy link
Member

jdm commented Mar 8, 2018

Oh, and to be clear when I said "updates to the unit tests", I was specifically referring to the fact that they do not compile any longer according to TravisCI :)

marmistrz added a commit to marmistrz/servo that referenced this pull request Mar 8, 2018
@jdm
Copy link
Member

jdm commented Mar 12, 2018

The changes here look good to me as long as we can make Servo build with them before merging them.

@bors-servo
Copy link
Contributor

☔ The latest upstream changes (presumably #397) made this pull request unmergeable. Please resolve the merge conflicts.

@@ -0,0 +1,17 @@
#!/bin/sh
# This is one big heuristic but seems to work well enough
Copy link
Member

@jdm jdm Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a clever solution! Let's add documentation like the following:

The script extracts a list of all the JSAPI functions that accept FFI Handle and MutableHandle arguments.

@marmistrz
Copy link
Contributor Author

@jdm Could some macros guru to review my macro? The macro rule duplication here is atrocious but I don't know if the macro system allows for anything more than copy paste.

@@ -238,7 +239,7 @@ unsafe fn convert_int_from_jsval<T, M>(cx: *mut JSContext, value: HandleValue,
// https://heycam.github.io/webidl/#es-boolean
impl ToJSValConvertible for bool {
#[inline]
unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) {
unsafe fn to_jsval(&self, _cx: *mut JSContext, mut rval: MutableHandleValue) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: double space.

src/rust.rs Outdated
wrap!(@inner $saved <> ($($acc,)* $arg,) <> $($rest)*);
};
(@inner ($func_name:ident ($($args:tt)*) -> $outtype:ty) <> ($($argexprs:expr,)*) <> ) => {
pub unsafe fn $func_name($($args)*) -> $outtype {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add #[inline] here.

src/rust.rs Outdated
use libc::FILE;
use super::{Handle, HandleId, HandleObject, HandleValue};
use super::{MutableHandle, MutableHandleObject, MutableHandleValue};
include!("jsapi_wrappers.rs");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file in this PR is called jsapi_wrappers.in. Is something missing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that was fixed while merging upstream :)

src/rust.rs Outdated
wrap!(pub fn $func_name($($args)*) -> ());
}
}
pub mod wrappers {
Copy link
Member

@jdm jdm Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add documentation like:

Wrappers for JSAPI methods that accept FFI Handle and MutableHandle arguments. The new methods are identical except that they accept Handle and MutableHandle arguments that include lifetimes instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean:

Wrappers for JSAPI methods that accept lifetimed Handle and MutableHandle arguments.
?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment scrolls horizontally, so keep reading.

@nox
Copy link
Contributor

nox commented Mar 23, 2018

@marmistrz AFAICT skimming through that macro, the only way to require less clauses is to unconditionally transform all arguments, as opposed to just the ones with MutableHandle etc. This would require a trait implemented for all arguments found in invocations of wrap!. I think this is good enough for now.

@bors-servo
Copy link
Contributor

☔ The latest upstream changes (presumably #404) made this pull request unmergeable. Please resolve the merge conflicts.

@jdm
Copy link
Member

jdm commented Mar 23, 2018

Hmm, Unbox seems to be a platform-specific function for some reason:

error[E0425]: cannot find function `Unbox` in module `jsapi`
    --> src\rust.rs:1680:23
     |
1680 |         wrap!(@inner ($func_name ($($args)*) -> $outtype) <> () <> $($args)* ,);
     |                       ^^^^^^^^^^ not found in `jsapi`
     | 
    ::: src\jsapi_wrappers.in:3:1
     |
3    | wrap!(pub fn Unbox(cx: *mut JSContext, obj: HandleObject, vp: MutableHandleValue) -> bool);
     | ------------------------------------------------------------------------------------------- in this macro invocation
help: possible candidate is found in another module, you can import it into scope
     |
1693 |     use rust::wrappers::Unbox;
     |

@jdm
Copy link
Member

jdm commented Mar 27, 2018

@bors-servo r+

@bors-servo
Copy link
Contributor

📌 Commit 709357f has been approved by jdm

@bors-servo
Copy link
Contributor

⌛ Testing commit 709357f with merge 03db1ae...

bors-servo pushed a commit that referenced this pull request Mar 27, 2018
Add lifetimes for Handle and MutableHandle

Servo compiled fine for me with the following patch set.

Since the `From` trait consumes the object, I created a `raw` method for `MutableHandle`. This is not ideal, since `into()` would be more idiomatic. Is there anything better I could do or should I just leave it as it is?

There are two questions marked with `// REVIEW` since I'm not sure if the explicit lifetimes are the same what compiler inferred.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-mozjs/393)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

☀️ Test successful - status-appveyor, status-travis
Approved by: jdm
Pushing 03db1ae to master...

@bors-servo bors-servo merged commit 709357f into servo:master Mar 27, 2018
marmistrz added a commit to marmistrz/servo that referenced this pull request Mar 28, 2018
marmistrz added a commit to marmistrz/rust-mozjs that referenced this pull request Apr 5, 2018
marmistrz added a commit to marmistrz/rust-mozjs that referenced this pull request Apr 5, 2018
They were introduced by servo#393 and meant to be removed once the questions
had been answered - but they ended up merged.
bors-servo pushed a commit that referenced this pull request Apr 5, 2018
Remove stray comments asking for review :)

They were introduced by #393 and meant to be removed once the questions
had been answered - but they ended up merged.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-mozjs/421)
<!-- Reviewable:end -->
marmistrz added a commit to marmistrz/rust-mozjs that referenced this pull request Apr 11, 2018
Our current wrappers held in rust::wrappers accept the Handles by
consume/Copy. This was introduced in servo#393 to make it feasible to migrate
the API calls on the Servo side in finite time. This, in particular,
requires unsafe code in the implementation of MutableHandle.

This change introduces a second set of wrappers, which will now borrow
MutableHandles instead of relying on impl Copy for MutableHandle. The
Servo code should gradually move to the new wrappers,
rust::jsapi_wrapped, so that we can eventually remove rust::wrappers.
Moggers pushed a commit to Moggers/servo that referenced this pull request Jun 13, 2018
thomaskrause pushed a commit to korpling/graphannis-malloc_size_of that referenced this pull request Oct 11, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants