Update rustc to revision 2cfb5acb5a2751c759627377e602bac4f88f2d19.

This commit is contained in:
Ms2ger 2015-01-02 12:45:28 +01:00 committed by Josh Matthews
parent cf616b90a2
commit 16c7060bc8
153 changed files with 2095 additions and 1298 deletions

View file

@ -33,9 +33,11 @@ use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSContext};
use libc;
use std::cell::RefCell;
use std::collections::hash_map::{HashMap, Vacant, Occupied};
use std::rc::Rc;
use std::sync::{Arc, Mutex};
local_data_key!(pub LiveReferences: LiveDOMReferences)
thread_local!(pub static LiveReferences: Rc<RefCell<Option<LiveDOMReferences>>> = Rc::new(RefCell::new(None)))
/// A safe wrapper around a raw pointer to a DOM object that can be
/// shared among tasks for use in asynchronous operations. The underlying
@ -55,24 +57,28 @@ impl<T: Reflectable> Trusted<T> {
/// be prevented from being GCed for the duration of the resulting `Trusted<T>` object's
/// lifetime.
pub fn new(cx: *mut JSContext, ptr: JSRef<T>, script_chan: Box<ScriptChan + Send>) -> Trusted<T> {
let live_references = LiveReferences.get().unwrap();
let refcount = live_references.addref(cx, &*ptr as *const T);
Trusted {
ptr: &*ptr as *const T as *const libc::c_void,
refcount: refcount,
script_chan: script_chan,
owner_thread: (&*live_references) as *const _ as *const libc::c_void,
}
LiveReferences.with(|ref r| {
let r = r.borrow();
let live_references = r.as_ref().unwrap();
let refcount = live_references.addref(cx, &*ptr as *const T);
Trusted {
ptr: &*ptr as *const T as *const libc::c_void,
refcount: refcount,
script_chan: script_chan.clone(),
owner_thread: (&*live_references) as *const _ as *const libc::c_void,
}
})
}
/// Obtain a usable DOM pointer from a pinned `Trusted<T>` value. Fails if used on
/// a different thread than the original value from which this `Trusted<T>` was
/// obtained.
pub fn to_temporary(&self) -> Temporary<T> {
assert!({
let live_references = LiveReferences.get().unwrap();
assert!(LiveReferences.with(|ref r| {
let r = r.borrow();
let live_references = r.as_ref().unwrap();
self.owner_thread == (&*live_references) as *const _ as *const libc::c_void
});
}));
unsafe {
Temporary::new(JS::from_raw(self.ptr as *const T))
}
@ -117,9 +123,11 @@ pub struct LiveDOMReferences {
impl LiveDOMReferences {
/// Set up the task-local data required for storing the outstanding DOM references.
pub fn initialize() {
LiveReferences.replace(Some(LiveDOMReferences {
table: RefCell::new(HashMap::new()),
}));
LiveReferences.with(|ref r| {
*r.borrow_mut() = Some(LiveDOMReferences {
table: RefCell::new(HashMap::new()),
})
});
}
fn addref<T: Reflectable>(&self, cx: *mut JSContext, ptr: *const T) -> Arc<Mutex<uint>> {
@ -144,30 +152,33 @@ impl LiveDOMReferences {
/// Unpin the given DOM object if its refcount is 0.
pub fn cleanup(cx: *mut JSContext, raw_reflectable: *const libc::c_void) {
let live_references = LiveReferences.get().unwrap();
let reflectable = raw_reflectable as *const Reflector;
let mut table = live_references.table.borrow_mut();
match table.entry(raw_reflectable) {
Occupied(entry) => {
if *entry.get().lock() != 0 {
// there could have been a new reference taken since
// this message was dispatched.
return;
}
LiveReferences.with(|ref r| {
let r = r.borrow();
let live_references = r.as_ref().unwrap();
let reflectable = raw_reflectable as *const Reflector;
let mut table = live_references.table.borrow_mut();
match table.entry(raw_reflectable) {
Occupied(entry) => {
if *entry.get().lock() != 0 {
// there could have been a new reference taken since
// this message was dispatched.
return;
}
unsafe {
JS_RemoveObjectRoot(cx, (*reflectable).rootable());
unsafe {
JS_RemoveObjectRoot(cx, (*reflectable).rootable());
}
let _ = entry.take();
}
Vacant(_) => {
// there could be a cleanup message dispatched, then a new
// pinned reference obtained and released before the message
// is processed, at which point there would be no matching
// hashtable entry.
info!("attempt to cleanup an unrecognized reflector");
}
let _ = entry.take();
}
Vacant(_) => {
// there could be a cleanup message dispatched, then a new
// pinned reference obtained and released before the message
// is processed, at which point there would be no matching
// hashtable entry.
info!("attempt to cleanup an unrecognized reflector");
}
}
})
}
}