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

Replace return_address usage in Rooted with a stack guard and a rooted! macro. #272

Merged
merged 2 commits into from
Jun 27, 2016

Conversation

eddyb
Copy link
Contributor

@eddyb eddyb commented Jun 26, 2016

Part of a potential solution for rust-lang/rust#34227.


This change is Reviewable

eddyb added a commit to eddyb/servo that referenced this pull request Jun 26, 2016
eddyb added a commit to eddyb/servo that referenced this pull request Jun 26, 2016
eddyb added a commit to eddyb/servo that referenced this pull request Jun 26, 2016
bors-servo pushed a commit to servo/servo that referenced this pull request Jun 26, 2016
Replace return_address usage for rooting with stack guards and convenience macros.

The existing `Rooted` and `RootedVec` users were migrated the the following two macros:
```rust
let x = Rooted::new(cx, value);
// Was changed to:
rooted!(in(cx) let x = value);
// Which expands to:
let mut __root = Rooted::new_unrooted(value);
let x = RootedGuard::new(cx, &mut __root);
```
```rust
let mut v = RootedVec::new();
v.extend(iter);
// Was changed to:
rooted_vec!(let v = iter);
// Which expands to:
let mut __root = RootableVec::new();
let v = RootedVec::new(&mut __root, iter);
```

The `rooted!` macro depends on servo/rust-mozjs#272.
These APIs based on two types, a container to be rooted and a rooting guard, allow implementing both `Rooted`-style rooting and `Traceable`-based rooting in stable Rust, without abusing `return_address`.

Such macros may have been tried before, but in 1.9 their hygiene is broken, they work only since 1.10.

Sadly, `Rooted` is a FFI type and completely exposed, so I cannot prevent anyone from creating their own, although all fields but the value get overwritten by `RootedGuard::new` anyway.
`RootableVec` OTOH is *guaranteed* to be empty when not rooted, which makes it harmless AFAICT.

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix rust-lang/rust#34227
- [x] These changes do not require tests because they are not functional changes

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11872)
<!-- Reviewable:end -->
@eddyb eddyb force-pushed the back-to-roots branch 2 times, most recently from 3ad7c45 to 3e1be4a Compare June 26, 2016 17:39
eddyb added a commit to eddyb/servo that referenced this pull request Jun 26, 2016
}
}

pub fn handle(&self) -> Handle<T> where T: Copy {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why the Copy bound here and on handle_mut?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The methods to create those types requires it.

@Ms2ger
Copy link
Contributor

Ms2ger commented Jun 27, 2016

Others should review this too, but I think this is good enough.

CC @nox @Manishearth @jdm

@nox
Copy link
Contributor

nox commented Jun 27, 2016

LGTM too.

@@ -488,6 +488,29 @@ impl<T: ToJSValConvertible> ToJSValConvertible for Vec<T> {
}
}

struct ForOfIteratorGuard<'a> {
Copy link
Member

Choose a reason for hiding this comment

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

documentation on this? (explaining why it is necessary perhaps)

@Manishearth
Copy link
Member

Overall lgtm. would like more docs.

@Manishearth
Copy link
Member

@bors-servo r+

@Ms2ger
Copy link
Contributor

Ms2ger commented Jun 27, 2016

@bors-servo r=Manishearth

@bors-servo
Copy link
Contributor

📌 Commit 3e1be4a has been approved by Manishearth

@Ms2ger
Copy link
Contributor

Ms2ger commented Jun 27, 2016

@bors-servo retry

@Ms2ger
Copy link
Contributor

Ms2ger commented Jun 27, 2016

@bors-servo clean retry

@Ms2ger Ms2ger closed this Jun 27, 2016
@Ms2ger Ms2ger reopened this Jun 27, 2016
@Ms2ger
Copy link
Contributor

Ms2ger commented Jun 27, 2016

@bors-servo r=Manishearth

@bors-servo
Copy link
Contributor

📌 Commit ae62516 has been approved by Manishearth

@bors-servo
Copy link
Contributor

⌛ Testing commit ae62516 with merge 9ddac71...

bors-servo pushed a commit that referenced this pull request Jun 27, 2016
Replace return_address usage in Rooted with a stack guard and a rooted! macro.

Part of a potential solution for rust-lang/rust#34227.

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

💔 Test failed - travis

@cbrewster
Copy link
Contributor

@bors-servo r=Manishearth

@bors-servo
Copy link
Contributor

📌 Commit 71333b8 has been approved by Manishearth

@bors-servo
Copy link
Contributor

⌛ Testing commit 71333b8 with merge 7ccfee5...

bors-servo pushed a commit that referenced this pull request Jun 27, 2016
Replace return_address usage in Rooted with a stack guard and a rooted! macro.

Part of a potential solution for rust-lang/rust#34227.

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

☀️ Test successful - travis

@bors-servo bors-servo merged commit 71333b8 into servo:master Jun 27, 2016
@eddyb eddyb deleted the back-to-roots branch June 27, 2016 18:24
eddyb added a commit to eddyb/servo that referenced this pull request Jun 27, 2016
eddyb added a commit to eddyb/servo that referenced this pull request Jun 27, 2016
eddyb added a commit to eddyb/servo that referenced this pull request Jun 28, 2016
let kind = T::rootKind() as usize;
let root = Rooted::<T> {
impl<T> Rooted<T> {
pub fn new_unrooted(initial: T) -> Rooted<T> {
Copy link
Contributor

Choose a reason for hiding this comment

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

My gut reaction to seeing an unrooted "Rooted<T>" is terror: it means you could pass around references to Rooted<T> (what would be [Mutable]Handle<T> in js/) that are not in fact rooted.

Is there any way we could use the type system to differentiate between things that are actually rooted vs those that are not (hashtag session types?), or maybe even just rename these types? It seems to me that Rooted<T> is really Rootable<T> and RootedGuard<T> is the real Rooted<T>.

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 cannot create a Handle safely from it. A reference to Rooted means nothing by itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would love to use better names but Rooted is an FFI type (which is required because it's a node in a linked list) so we cannot do too much about it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we move the initial assignment to RootedGuard::new()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I suppose so? But what do you put there in Rooted::new_unrooted?

Copy link
Contributor

Choose a reason for hiding this comment

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

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 trait seems like a good choice to have as a bound in the struct itself.
Alright, other changes suggested on IRC were to have struct Rootable<T>(Rooted<T>); which could only be created empty and not accessed, and it's what RootedGuard would accept.

Copy link
Contributor

Choose a reason for hiding this comment

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

You can do the wrapper that cannot be accessed and fill it with initial.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

However, that wrapper would cause issues with ForOfIterator, although that's internal to rust-mozjs and perhaps could be accommodated for with a pub(crate) unsafe method.

bors-servo pushed a commit to servo/servo that referenced this pull request Jul 4, 2016
Replace return_address usage for rooting with stack guards and convenience macros.

The existing `Rooted` and `RootedVec` users were migrated the the following two macros:
```rust
let x = Rooted::new(cx, value);
// Was changed to:
rooted!(in(cx) let x = value);
// Which expands to:
let mut __root = Rooted::new_unrooted(value);
let x = RootedGuard::new(cx, &mut __root);
```
```rust
let mut v = RootedVec::new();
v.extend(iterator);
// Was changed to:
rooted_vec!(let v <- iterator);
// Which expands to:
let mut __root = RootableVec::new();
let v = RootedVec::new(&mut __root, iterator);
```

The `rooted!` macro depends on servo/rust-mozjs#272.
These APIs based on two types, a container to be rooted and a rooting guard, allow implementing both `Rooted`-style rooting and `Traceable`-based rooting in stable Rust, without abusing `return_address`.

Such macros may have been tried before, but in 1.9 their hygiene is broken, they work only since 1.10.

Sadly, `Rooted` is a FFI type and completely exposed, so I cannot prevent anyone from creating their own, although all fields but the value get overwritten by `RootedGuard::new` anyway.
`RootableVec` OTOH is *guaranteed* to be empty when not rooted, which makes it harmless AFAICT.

By fixing rust-lang/rust#34227, this PR enables Servo to build with `-Zorbit`.

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix rust-lang/rust#34227
- [x] These changes do not require tests because they are not functional changes

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11872)
<!-- Reviewable:end -->
bors-servo pushed a commit to servo/servo that referenced this pull request Jul 4, 2016
Replace return_address usage for rooting with stack guards and convenience macros.

The existing `Rooted` and `RootedVec` users were migrated the the following two macros:
```rust
let x = Rooted::new(cx, value);
// Was changed to:
rooted!(in(cx) let x = value);
// Which expands to:
let mut __root = Rooted::new_unrooted(value);
let x = RootedGuard::new(cx, &mut __root);
```
```rust
let mut v = RootedVec::new();
v.extend(iterator);
// Was changed to:
rooted_vec!(let v <- iterator);
// Which expands to:
let mut __root = RootableVec::new();
let v = RootedVec::new(&mut __root, iterator);
```

The `rooted!` macro depends on servo/rust-mozjs#272.
These APIs based on two types, a container to be rooted and a rooting guard, allow implementing both `Rooted`-style rooting and `Traceable`-based rooting in stable Rust, without abusing `return_address`.

Such macros may have been tried before, but in 1.9 their hygiene is broken, they work only since 1.10.

Sadly, `Rooted` is a FFI type and completely exposed, so I cannot prevent anyone from creating their own, although all fields but the value get overwritten by `RootedGuard::new` anyway.
`RootableVec` OTOH is *guaranteed* to be empty when not rooted, which makes it harmless AFAICT.

By fixing rust-lang/rust#34227, this PR enables Servo to build with `-Zorbit`.

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix rust-lang/rust#34227
- [x] These changes do not require tests because they are not functional changes

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11872)
<!-- Reviewable:end -->
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this pull request Oct 1, 2019
…tack guards and convenience macros (from eddyb:back-to-roots); r=Ms2ger

The existing `Rooted` and `RootedVec` users were migrated the the following two macros:
```rust
let x = Rooted::new(cx, value);
// Was changed to:
rooted!(in(cx) let x = value);
// Which expands to:
let mut __root = Rooted::new_unrooted(value);
let x = RootedGuard::new(cx, &mut __root);
```
```rust
let mut v = RootedVec::new();
v.extend(iterator);
// Was changed to:
rooted_vec!(let v <- iterator);
// Which expands to:
let mut __root = RootableVec::new();
let v = RootedVec::new(&mut __root, iterator);
```

The `rooted!` macro depends on servo/rust-mozjs#272.
These APIs based on two types, a container to be rooted and a rooting guard, allow implementing both `Rooted`-style rooting and `Traceable`-based rooting in stable Rust, without abusing `return_address`.

Such macros may have been tried before, but in 1.9 their hygiene is broken, they work only since 1.10.

Sadly, `Rooted` is a FFI type and completely exposed, so I cannot prevent anyone from creating their own, although all fields but the value get overwritten by `RootedGuard::new` anyway.
`RootableVec` OTOH is *guaranteed* to be empty when not rooted, which makes it harmless AFAICT.

By fixing rust-lang/rust#34227, this PR enables Servo to build with `-Zorbit`.

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix rust-lang/rust#34227
- [x] These changes do not require tests because they are not functional changes

Source-Repo: https://github.com/servo/servo
Source-Revision: 80cb0cf8214fd52d2884724614c40cb278ee7575

UltraBlame original commit: 70db9045abfa70e0440944258f92294eb298000c
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this pull request Oct 1, 2019
…tack guards and convenience macros (from eddyb:back-to-roots); r=Ms2ger

The existing `Rooted` and `RootedVec` users were migrated the the following two macros:
```rust
let x = Rooted::new(cx, value);
// Was changed to:
rooted!(in(cx) let x = value);
// Which expands to:
let mut __root = Rooted::new_unrooted(value);
let x = RootedGuard::new(cx, &mut __root);
```
```rust
let mut v = RootedVec::new();
v.extend(iterator);
// Was changed to:
rooted_vec!(let v <- iterator);
// Which expands to:
let mut __root = RootableVec::new();
let v = RootedVec::new(&mut __root, iterator);
```

The `rooted!` macro depends on servo/rust-mozjs#272.
These APIs based on two types, a container to be rooted and a rooting guard, allow implementing both `Rooted`-style rooting and `Traceable`-based rooting in stable Rust, without abusing `return_address`.

Such macros may have been tried before, but in 1.9 their hygiene is broken, they work only since 1.10.

Sadly, `Rooted` is a FFI type and completely exposed, so I cannot prevent anyone from creating their own, although all fields but the value get overwritten by `RootedGuard::new` anyway.
`RootableVec` OTOH is *guaranteed* to be empty when not rooted, which makes it harmless AFAICT.

By fixing rust-lang/rust#34227, this PR enables Servo to build with `-Zorbit`.

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix rust-lang/rust#34227
- [x] These changes do not require tests because they are not functional changes

Source-Repo: https://github.com/servo/servo
Source-Revision: 80cb0cf8214fd52d2884724614c40cb278ee7575

UltraBlame original commit: 70db9045abfa70e0440944258f92294eb298000c
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this pull request Oct 1, 2019
…tack guards and convenience macros (from eddyb:back-to-roots); r=Ms2ger

The existing `Rooted` and `RootedVec` users were migrated the the following two macros:
```rust
let x = Rooted::new(cx, value);
// Was changed to:
rooted!(in(cx) let x = value);
// Which expands to:
let mut __root = Rooted::new_unrooted(value);
let x = RootedGuard::new(cx, &mut __root);
```
```rust
let mut v = RootedVec::new();
v.extend(iterator);
// Was changed to:
rooted_vec!(let v <- iterator);
// Which expands to:
let mut __root = RootableVec::new();
let v = RootedVec::new(&mut __root, iterator);
```

The `rooted!` macro depends on servo/rust-mozjs#272.
These APIs based on two types, a container to be rooted and a rooting guard, allow implementing both `Rooted`-style rooting and `Traceable`-based rooting in stable Rust, without abusing `return_address`.

Such macros may have been tried before, but in 1.9 their hygiene is broken, they work only since 1.10.

Sadly, `Rooted` is a FFI type and completely exposed, so I cannot prevent anyone from creating their own, although all fields but the value get overwritten by `RootedGuard::new` anyway.
`RootableVec` OTOH is *guaranteed* to be empty when not rooted, which makes it harmless AFAICT.

By fixing rust-lang/rust#34227, this PR enables Servo to build with `-Zorbit`.

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix rust-lang/rust#34227
- [x] These changes do not require tests because they are not functional changes

Source-Repo: https://github.com/servo/servo
Source-Revision: 80cb0cf8214fd52d2884724614c40cb278ee7575

UltraBlame original commit: 70db9045abfa70e0440944258f92294eb298000c
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.

None yet

7 participants