-
Notifications
You must be signed in to change notification settings - Fork 117
Add lifetimes for Handle and MutableHandle #393
Conversation
This will require some updates to the unit tests, too. |
There was a problem hiding this 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) { |
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
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. |
We could write some compile_fail doctests that demonstrate that handle values with lifetimes can't outlive the objects from which they were obtained. |
☔ The latest upstream changes (presumably #394) made this pull request unmergeable. Please resolve the merge conflicts. |
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 :) |
The changes here look good to me as long as we can make Servo build with them before merging them. |
☔ The latest upstream changes (presumably #397) made this pull request unmergeable. Please resolve the merge conflicts. |
src/generate_jsapi_wrappers.sh
Outdated
@@ -0,0 +1,17 @@ | |||
#!/bin/sh | |||
# This is one big heuristic but seems to work well enough |
There was a problem hiding this comment.
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.
@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. |
src/conversions.rs
Outdated
@@ -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) { |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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"); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
?
There was a problem hiding this comment.
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.
@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 |
☔ The latest upstream changes (presumably #404) made this pull request unmergeable. Please resolve the merge conflicts. |
Hmm, Unbox seems to be a platform-specific function for some reason:
|
@bors-servo r+ |
📌 Commit 709357f has been approved by |
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 -->
☀️ Test successful - status-appveyor, status-travis |
They were introduced by servo#393 and meant to be removed once the questions had been answered - but they ended up merged.
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 -->
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.
Servo compiled fine for me with the following patch set.
Since the
From
trait consumes the object, I created araw
method forMutableHandle
. This is not ideal, sinceinto()
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