Wrap executions of Rust code called from JS in catch_unwind. Propagate the interrupted panic to the origin of the JS execution via TLS before resuming. Fix #6462.

This commit is contained in:
Josh Matthews 2016-06-20 13:25:42 -04:00
parent a74ce64539
commit b8853554db
4 changed files with 58 additions and 11 deletions

View file

@ -19,7 +19,8 @@ use js::jsapi::{JSObject, RuntimeOptionsRef, SetPreserveWrapperCallback};
use js::rust::Runtime;
use profile_traits::mem::{Report, ReportKind, ReportsChan};
use script_thread::{Runnable, STACK_ROOTS, trace_thread};
use std::cell::Cell;
use std::any::Any;
use std::cell::{RefCell, Cell};
use std::io::{Write, stdout};
use std::marker::PhantomData;
use std::os;
@ -321,6 +322,21 @@ pub fn get_reports(cx: *mut JSContext, path_seg: String) -> Vec<Report> {
reports
}
thread_local!(static PANIC_RESULT: RefCell<Option<Box<Any + Send>>> = RefCell::new(None));
pub fn store_panic_result(error: Box<Any + Send>) {
PANIC_RESULT.with(|result| {
assert!(result.borrow().is_none());
*result.borrow_mut() = Some(error);
});
}
pub fn maybe_take_panic_result() -> Option<Box<Any + Send>> {
PANIC_RESULT.with(|result| {
result.borrow_mut().take()
})
}
thread_local!(static GC_CYCLE_START: Cell<Option<Tm>> = Cell::new(None));
thread_local!(static GC_SLICE_START: Cell<Option<Tm>> = Cell::new(None));