-
Notifications
You must be signed in to change notification settings - Fork 321
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use correct lifetime for TryCatch::exception()/message() return value (…
…#380) According to v8.h, "the returned handle is valid until this TryCatch block has been destroyed". This is incorrect, as can be demonstrated with the test below. In practice the return value lives no longer and no shorter than the active HandleScope at the time these methods are called. An issue has been opened about this in the V8 bug tracker: https://bugs.chromium.org/p/v8/issues/detail?id=10537. ```rust fn try_catch_bad_lifetimes() { let _setup_guard = setup(); let mut isolate = v8::Isolate::new(Default::default()); let mut hs = v8::HandleScope::new(&mut isolate); let scope = hs.enter(); let context = v8::Context::new(scope); let mut cs = v8::ContextScope::new(scope, context); let scope = cs.enter(); let caught_msg_2 = { let mut try_catch = v8::TryCatch::new(scope); let try_catch = try_catch.enter(); let caught_msg_1 = { let mut hs = v8::HandleScope::new(scope); let scope = hs.enter(); // Throw exception #1. let msg_1 = v8::String::new(scope, "BOOM!").unwrap(); let exc_1 = v8::Exception::type_error(scope, msg_1); scope.isolate().throw_exception(exc_1); // Catch exception #1. let caught_msg_1 = try_catch.message().unwrap(); let caught_str_1 = caught_msg_1.get(scope).to_rust_string_lossy(scope); assert!(caught_str_1.contains("BOOM")); // Move `caught_msg_1` out of the HandleScope it was created in. // The borrow checker allows this because `caught_msg_1`'s // lifetime is contrained to not outlive the TryCatch, but it is // allowed to outlive the HandleScope that was active when the // exception was caught. caught_msg_1 }; // Next line crashes. let caught_str_1 = caught_msg_1.get(scope).to_rust_string_lossy(scope); assert!(caught_str_1.contains("BOOM")); // Throws exception #2. let msg_2 = v8::String::new(scope, "DANG!").unwrap(); let exc_2 = v8::Exception::type_error(scope, msg_2); scope.isolate().throw_exception(exc_2); // Catch exception #2. let caught_msg_2 = try_catch.message().unwrap(); let caught_str_2 = caught_msg_2.get(scope).to_rust_string_lossy(scope); assert!(caught_str_2.contains("DANG")); // Move `caught_msg_2` out of the extent of the TryCatch, but still // within the extent of its HandleScope. This is unnecessarily // rejected at compile time. caught_msg_2 }; let caught_str_2 = caught_msg_2.get(scope).to_rust_string_lossy(scope); assert!(caught_str_2.contains("DANG")); } ```
- Loading branch information
1 parent
3fb278e
commit 56c3d9f
Showing
6 changed files
with
92 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
error[E0597]: `try_catch` does not live long enough | ||
error[E0597]: `hs` does not live long enough | ||
--> $DIR/try_catch_exception_lifetime.rs:11:14 | ||
| | ||
9 | let _exception = { | ||
| ---------- borrow later stored here | ||
10 | let mut try_catch = v8::TryCatch::new(hs); | ||
11 | let tc = try_catch.enter(); | ||
| ^^^^^^^^^ borrowed value does not live long enough | ||
12 | tc.exception().unwrap() | ||
10 | let mut hs = v8::HandleScope::new(&mut isolate); | ||
11 | let hs = hs.enter(); | ||
| ^^ borrowed value does not live long enough | ||
12 | try_catch.exception(hs).unwrap() | ||
13 | }; | ||
| - `try_catch` dropped here while still borrowed | ||
| - `hs` dropped here while still borrowed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
error[E0597]: `try_catch` does not live long enough | ||
error[E0597]: `hs` does not live long enough | ||
--> $DIR/try_catch_message_lifetime.rs:11:14 | ||
| | ||
9 | let _message = { | ||
| -------- borrow later stored here | ||
10 | let mut try_catch = v8::TryCatch::new(hs); | ||
11 | let tc = try_catch.enter(); | ||
| ^^^^^^^^^ borrowed value does not live long enough | ||
12 | tc.message().unwrap() | ||
9 | let _exception = { | ||
| ---------- borrow later stored here | ||
10 | let mut hs = v8::HandleScope::new(&mut isolate); | ||
11 | let hs = hs.enter(); | ||
| ^^ borrowed value does not live long enough | ||
12 | try_catch.message(hs).unwrap() | ||
13 | }; | ||
| - `try_catch` dropped here while still borrowed | ||
| - `hs` dropped here while still borrowed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters