Upgrade rust.

This commit is contained in:
Ms2ger 2014-03-21 11:51:25 +01:00
parent 7ece5f92db
commit 31eee791dd
102 changed files with 724 additions and 839 deletions

View file

@ -29,7 +29,6 @@ use layout_interface::{Reflow, ReflowDocumentDamage, ReflowForDisplay, ReflowGoa
use layout_interface::ContentChangedDocumentDamage;
use layout_interface;
use extra::url::Url;
use geom::point::Point2D;
use geom::size::Size2D;
use js::global::DEBUG_FNS;
@ -51,11 +50,12 @@ use servo_util::task::send_on_failure;
use servo_util::namespace::Null;
use std::cast;
use std::cell::{RefCell, Ref, RefMut};
use std::comm::{Port, Chan, Empty, Disconnected, Data};
use std::comm::{channel, Sender, Receiver, Empty, Disconnected, Data};
use std::mem::replace;
use std::ptr;
use std::rc::Rc;
use std::task;
use url::Url;
use serialize::{Encoder, Encodable};
@ -91,7 +91,7 @@ pub struct NewLayoutInfo {
/// Encapsulates external communication with the script task.
#[deriving(Clone)]
pub struct ScriptChan(Chan<ScriptMsg>);
pub struct ScriptChan(Sender<ScriptMsg>);
impl<S: Encoder> Encodable<S> for ScriptChan {
fn encode(&self, _s: &mut S) {
@ -100,8 +100,8 @@ impl<S: Encoder> Encodable<S> for ScriptChan {
impl ScriptChan {
/// Creates a new script chan.
pub fn new() -> (Port<ScriptMsg>, ScriptChan) {
let (port, chan) = Chan::new();
pub fn new() -> (Receiver<ScriptMsg>, ScriptChan) {
let (chan, port) = channel();
(port, ScriptChan(chan))
}
}
@ -121,7 +121,7 @@ pub struct Page {
layout_chan: LayoutChan,
/// The port that we will use to join layout. If this is `None`, then layout is not running.
layout_join_port: RefCell<Option<Port<()>>>,
layout_join_port: RefCell<Option<Receiver<()>>>,
/// What parts of the document are dirty, if any.
damage: RefCell<Option<DocumentDamage>>,
@ -149,7 +149,7 @@ pub struct Page {
impl<S: Encoder> Encodable<S> for Page {
fn encode(&self, s: &mut S) {
let fragment_node = self.fragment_node.borrow();
fragment_node.get().encode(s);
fragment_node.encode(s);
}
}
@ -188,7 +188,7 @@ impl PageTree {
}
fn page<'a>(&'a self) -> &'a Page {
self.page.borrow()
&*self.page
}
pub fn find<'a> (&'a mut self, id: PipelineId) -> Option<&'a mut PageTree> {
@ -276,8 +276,7 @@ impl Page {
/// Adds the given damage.
pub fn damage(&self, level: DocumentDamageLevel) {
let frame = self.frame();
let root = match *frame.get() {
let root = match *self.frame() {
None => return,
Some(ref frame) => frame.document.get().GetDocumentElement()
};
@ -285,8 +284,8 @@ impl Page {
None => {},
Some(root) => {
let root: JS<Node> = NodeCast::from(&root);
let mut damage = self.damage.borrow_mut();
match *damage.get() {
let mut damage = *self.damage.borrow_mut();
match damage {
None => {}
Some(ref mut damage) => {
// FIXME(pcwalton): This is wrong. We should trace up to the nearest ancestor.
@ -296,7 +295,7 @@ impl Page {
}
}
*damage.get() = Some(DocumentDamage {
*self.damage.borrow_mut() = Some(DocumentDamage {
root: root.to_trusted_node_address(),
level: level,
})
@ -305,16 +304,15 @@ impl Page {
}
pub fn get_url(&self) -> Url {
let url = self.url();
url.get().get_ref().ref0().clone()
self.url().get_ref().ref0().clone()
}
/// Sends a ping to layout and waits for the response. The response will arrive when the
/// layout task has finished any pending request messages.
pub fn join_layout(&self) {
let mut layout_join_port = self.layout_join_port.borrow_mut();
if layout_join_port.get().is_some() {
let join_port = replace(layout_join_port.get(), None);
if layout_join_port.is_some() {
let join_port = replace(&mut *layout_join_port, None);
match join_port {
Some(ref join_port) => {
match join_port.try_recv() {
@ -338,7 +336,7 @@ impl Page {
/// Sends the given query to layout.
pub fn query_layout<T: Send>(&self,
query: LayoutQuery,
response_port: Port<T>)
response_port: Receiver<T>)
-> T {
self.join_layout();
let LayoutChan(ref chan) = self.layout_chan;
@ -357,8 +355,7 @@ impl Page {
goal: ReflowGoal,
script_chan: ScriptChan,
compositor: &ScriptListener) {
let frame = self.frame();
let root = match *frame.get() {
let root = match *self.frame() {
None => return,
Some(ref frame) => {
frame.document.get().GetDocumentElement()
@ -377,12 +374,12 @@ impl Page {
compositor.set_ready_state(PerformingLayout);
// Layout will let us know when it's done.
let (join_port, join_chan) = Chan::new();
let (join_chan, join_port) = channel();
let mut layout_join_port = self.layout_join_port.borrow_mut();
*layout_join_port.get() = Some(join_port);
*layout_join_port = Some(join_port);
let mut last_reflow_id = self.last_reflow_id.borrow_mut();
*last_reflow_id.get() += 1;
*last_reflow_id += 1;
let root: JS<Node> = NodeCast::from(&root);
let mut damage = self.damage.borrow_mut();
@ -393,11 +390,11 @@ impl Page {
document_root: root.to_trusted_node_address(),
url: self.get_url(),
goal: goal,
window_size: *window_size.get(),
window_size: *window_size,
script_chan: script_chan,
script_join_chan: join_chan,
damage: replace(damage.get(), None).unwrap(),
id: *last_reflow_id.get(),
damage: replace(&mut *damage, None).unwrap(),
id: *last_reflow_id,
};
let LayoutChan(ref chan) = self.layout_chan;
@ -414,8 +411,8 @@ impl Page {
// Note that the order that these variables are initialized is _not_ arbitrary. Switching
// them around can -- and likely will -- lead to things breaking.
js_context.borrow().set_default_options_and_version();
js_context.borrow().set_logging_error_reporter();
js_context.set_default_options_and_version();
js_context.set_logging_error_reporter();
let compartment = match js_context.new_compartment_with_global(global) {
Ok(c) => c,
@ -423,11 +420,11 @@ impl Page {
};
unsafe {
JS_InhibitGC(js_context.borrow().ptr);
JS_InhibitGC(js_context.deref().ptr);
}
let mut js_info = self.mut_js_info();
*js_info.get() = Some(JSPageInfo {
*js_info = Some(JSPageInfo {
dom_static: GlobalStaticData(),
js_compartment: compartment,
js_context: js_context,
@ -467,7 +464,7 @@ pub struct ScriptTask {
resource_task: ResourceTask,
/// The port on which the script task receives messages (load URL, exit, etc.)
port: Port<ScriptMsg>,
port: Receiver<ScriptMsg>,
/// A channel to hand out when some other task needs to be able to respond to a message from
/// the script task.
chan: ScriptChan,
@ -488,7 +485,7 @@ impl ScriptTask {
pub fn new(id: PipelineId,
compositor: ~ScriptListener,
layout_chan: LayoutChan,
port: Port<ScriptMsg>,
port: Receiver<ScriptMsg>,
chan: ScriptChan,
constellation_chan: ConstellationChan,
resource_task: ResourceTask,
@ -525,7 +522,7 @@ impl ScriptTask {
id: PipelineId,
compositor: ~C,
layout_chan: LayoutChan,
port: Port<ScriptMsg>,
port: Receiver<ScriptMsg>,
chan: ScriptChan,
constellation_chan: ConstellationChan,
failure_msg: Failure,
@ -545,7 +542,7 @@ impl ScriptTask {
resource_task,
image_cache_task,
window_size);
script_task.borrow().start();
script_task.start();
});
}
@ -557,13 +554,12 @@ impl ScriptTask {
{
let mut page_tree = self.page_tree.borrow_mut();
for page in page_tree.get().iter() {
for page in page_tree.iter() {
// Only process a resize if layout is idle.
let page = page.borrow();
let layout_join_port = page.layout_join_port.borrow();
if layout_join_port.get().is_none() {
if layout_join_port.is_none() {
let mut resize_event = page.resize_event.borrow_mut();
match resize_event.get().take() {
match resize_event.take() {
Some(size) => resizes.push((page.id, size)),
None => ()
}
@ -585,9 +581,9 @@ impl ScriptTask {
match event {
ResizeMsg(id, size) => {
let mut page_tree = self.page_tree.borrow_mut();
let page = page_tree.get().find(id).expect("resize sent to nonexistent pipeline").page();
let page = page_tree.find(id).expect("resize sent to nonexistent pipeline").page();
let mut resize_event = page.resize_event.borrow_mut();
*resize_event.get() = Some(size);
*resize_event = Some(size);
}
_ => {
sequential.push(event);
@ -629,12 +625,12 @@ impl ScriptTask {
} = new_layout_info;
let mut page_tree = self.page_tree.borrow_mut();
let parent_page_tree = page_tree.get().find(old_id).expect("ScriptTask: received a layout
let parent_page_tree = page_tree.find(old_id).expect("ScriptTask: received a layout
whose parent has a PipelineId which does not correspond to a pipeline in the script
task's page tree. This is a bug.");
let new_page_tree = {
let window_size = parent_page_tree.page().window_size.borrow();
PageTree::new(new_id, layout_chan, *window_size.get())
PageTree::new(new_id, layout_chan, *window_size)
};
parent_page_tree.inner.push(new_page_tree);
}
@ -642,10 +638,10 @@ impl ScriptTask {
/// Handles a timer that fired.
fn handle_fire_timer_msg(&self, id: PipelineId, timer_data: ~TimerData) {
let mut page_tree = self.page_tree.borrow_mut();
let page = page_tree.get().find(id).expect("ScriptTask: received fire timer msg for a
let page = page_tree.find(id).expect("ScriptTask: received fire timer msg for a
pipeline ID not associated with this script task. This is a bug.").page();
let frame = page.frame();
let mut window = frame.get().get_ref().window.clone();
let mut window = frame.get_ref().window.clone();
let timer_handle = window.get_mut().active_timers.pop(&timer_data.handle);
if timer_handle.is_none() {
@ -656,12 +652,12 @@ impl ScriptTask {
let this_value = if timer_data.args.len() > 0 {
fail!("NYI")
} else {
js_info.get().get_ref().js_compartment.borrow().global_obj
js_info.get_ref().js_compartment.global_obj
};
// TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`.
let rval = NullValue();
let cx = js_info.get().get_ref().js_context.borrow().ptr;
let cx = js_info.get_ref().js_context.deref().ptr;
with_gc_enabled(cx, || {
unsafe {
JS_CallFunctionValue(cx, this_value, timer_data.funval, 0, ptr::null(), &rval);
@ -673,13 +669,13 @@ impl ScriptTask {
fn handle_reflow_complete_msg(&self, pipeline_id: PipelineId, reflow_id: uint) {
debug!("Script: Reflow {:?} complete for {:?}", reflow_id, pipeline_id);
let mut page_tree = self.page_tree.borrow_mut();
let page = page_tree.get().find(pipeline_id).expect(
let page = page_tree.find(pipeline_id).expect(
"ScriptTask: received a load message for a layout channel that is not associated \
with this script task. This is a bug.").page();
let last_reflow_id = page.last_reflow_id.borrow();
if *last_reflow_id.get() == reflow_id {
if *last_reflow_id == reflow_id {
let mut layout_join_port = page.layout_join_port.borrow_mut();
*layout_join_port.get() = None;
*layout_join_port = None;
}
self.compositor.set_ready_state(FinishedLoading);
}
@ -694,14 +690,14 @@ impl ScriptTask {
/// Window was resized, but this script was not active, so don't reflow yet
fn handle_resize_inactive_msg(&self, id: PipelineId, new_size: Size2D<uint>) {
let mut page_tree = self.page_tree.borrow_mut();
let page = page_tree.get().find(id).expect("Received resize message for PipelineId not associated
let page = page_tree.find(id).expect("Received resize message for PipelineId not associated
with a page in the page tree. This is a bug.").page();
let mut window_size = page.window_size.borrow_mut();
*window_size.get() = new_size;
*window_size = new_size;
let mut page_url = page.mut_url();
let last_loaded_url = replace(page_url.get(), None);
let last_loaded_url = replace(&mut *page_url, None);
for url in last_loaded_url.iter() {
*page_url.get() = Some((url.ref0().clone(), true));
*page_url = Some((url.ref0().clone(), true));
}
}
@ -724,22 +720,20 @@ impl ScriptTask {
fn handle_exit_pipeline_msg(&self, id: PipelineId) -> bool {
// If root is being exited, shut down all pages
let mut page_tree = self.page_tree.borrow_mut();
if page_tree.get().page().id == id {
for page in page_tree.get().iter() {
let page = page.borrow();
if page_tree.page().id == id {
for page in page_tree.iter() {
debug!("shutting down layout for root page {:?}", page.id);
shut_down_layout(page)
shut_down_layout(&*page)
}
return true
}
// otherwise find just the matching page and exit all sub-pages
match page_tree.get().remove(id) {
match page_tree.remove(id) {
Some(ref mut page_tree) => {
for page in page_tree.iter() {
let page = page.borrow();
debug!("shutting down layout for page {:?}", page.id);
shut_down_layout(page)
shut_down_layout(&*page)
}
false
}
@ -757,18 +751,18 @@ impl ScriptTask {
debug!("ScriptTask: loading {:?} on page {:?}", url, pipeline_id);
let mut page_tree = self.page_tree.borrow_mut();
let page_tree = page_tree.get().find(pipeline_id).expect("ScriptTask: received a load
let page_tree = page_tree.find(pipeline_id).expect("ScriptTask: received a load
message for a layout channel that is not associated with this script task. This
is a bug.");
let page = page_tree.page();
{
let mut page_url = page.mut_url();
let last_loaded_url = replace(page_url.get(), None);
let last_loaded_url = replace(&mut *page_url, None);
for loaded in last_loaded_url.iter() {
let (ref loaded, needs_reflow) = *loaded;
if *loaded == url {
*page_url.get() = Some((loaded.clone(), false));
*page_url = Some((loaded.clone(), false));
if needs_reflow {
page.damage(ContentChangedDocumentDamage);
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor);
@ -780,7 +774,7 @@ impl ScriptTask {
let cx = self.js_runtime.cx();
// Create the window and document objects.
let window = Window::new(cx.borrow().ptr,
let window = Window::new(cx.deref().ptr,
page_tree.page.clone(),
self.chan.clone(),
self.compositor.dup(),
@ -789,7 +783,7 @@ impl ScriptTask {
{
let mut js_info = page.mut_js_info();
RegisterBindings::Register(js_info.get().get_mut_ref());
RegisterBindings::Register(js_info.get_mut_ref());
}
self.compositor.set_ready_state(Loading);
@ -809,7 +803,7 @@ impl ScriptTask {
{
// Create the root frame.
let mut frame = page.mut_frame();
*frame.get() = Some(Frame {
*frame = Some(Frame {
document: document.clone(),
window: window.clone(),
});
@ -857,7 +851,7 @@ impl ScriptTask {
{
// No more reflow required
let mut page_url = page.mut_url();
*page_url.get() = Some((url.clone(), false));
*page_url = Some((url.clone(), false));
}
// Receive the JavaScript scripts.
@ -868,11 +862,10 @@ impl ScriptTask {
// Define debug functions.
let cx = {
let js_info = page.js_info();
let js_info = js_info.get().get_ref();
let compartment = js_info.js_compartment.borrow();
assert!(compartment.define_functions(DEBUG_FNS).is_ok());
let js_info = js_info.get_ref();
assert!(js_info.js_compartment.define_functions(DEBUG_FNS).is_ok());
js_info.js_context.borrow().ptr
js_info.js_context.deref().ptr
};
// Evaluate every script in the document.
@ -880,15 +873,15 @@ impl ScriptTask {
with_gc_enabled(cx, || {
let (cx, global_obj) = {
let js_info = page.js_info();
(js_info.get().get_ref().js_context.clone(),
js_info.get().get_ref().js_compartment.borrow().global_obj)
(js_info.get_ref().js_context.clone(),
js_info.get_ref().js_compartment.global_obj)
};
//FIXME: this should have some kind of error handling, or explicitly
// drop an exception on the floor.
assert!(cx.borrow().evaluate_script(global_obj,
file.data.clone(),
file.url.to_str(),
1).is_ok());
assert!(cx.evaluate_script(global_obj,
file.data.clone(),
file.url.to_str(),
1).is_ok());
});
}
@ -903,7 +896,7 @@ impl ScriptTask {
let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event);
let mut fragment_node = page.fragment_node.borrow_mut();
*fragment_node.get() = fragment.map_or(None, |fragid| self.find_fragment_node(page, fragid));
*fragment_node = fragment.map_or(None, |fragid| self.find_fragment_node(page, fragid));
let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(LoadCompleteMsg(page.id, url));
@ -911,7 +904,7 @@ impl ScriptTask {
fn find_fragment_node(&self, page: &Page, fragid: ~str) -> Option<JS<Element>> {
let frame = page.frame();
let document = frame.get().get_ref().document.clone();
let document = frame.get_ref().document.clone();
match document.get().GetElementById(fragid.to_owned()) {
Some(node) => Some(node),
None => {
@ -928,7 +921,7 @@ impl ScriptTask {
}
fn scroll_fragment_point(&self, pipeline_id: PipelineId, page: &Page, node: JS<Element>) {
let (port, chan) = Chan::new();
let (chan, port) = channel();
let node: JS<Node> = NodeCast::from(&node);
let ContentBoxResponse(rect) =
page.query_layout(ContentBoxQuery(node.to_trusted_node_address(), chan), port);
@ -946,7 +939,7 @@ impl ScriptTask {
/// TODO: Actually perform DOM event dispatch.
fn handle_event(&self, pipeline_id: PipelineId, event: Event_) {
let mut page_tree = self.page_tree.borrow_mut();
let page = page_tree.get().find(pipeline_id).expect("ScriptTask: received an event
let page = page_tree.find(pipeline_id).expect("ScriptTask: received an event
message for a layout channel that is not associated with this script task. This
is a bug.").page();
@ -956,25 +949,25 @@ impl ScriptTask {
{
let mut window_size = page.window_size.borrow_mut();
*window_size.get() = Size2D(new_width, new_height);
*window_size = Size2D(new_width, new_height);
}
{
let frame = page.frame();
if frame.get().is_some() {
if frame.is_some() {
page.damage(ReflowDocumentDamage);
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor)
}
}
let mut fragment_node = page.fragment_node.borrow_mut();
match fragment_node.get().take() {
match fragment_node.take() {
Some(node) => self.scroll_fragment_point(pipeline_id, page, node),
None => {}
}
let frame = page.frame();
match *frame.get() {
match *frame {
Some(ref frame) => {
// http://dev.w3.org/csswg/cssom-view/#resizing-viewports
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize
@ -997,7 +990,7 @@ impl ScriptTask {
debug!("script got reflow event");
let frame = page.frame();
if frame.get().is_some() {
if frame.is_some() {
page.damage(MatchSelectorsDocumentDamage);
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor)
}
@ -1007,18 +1000,18 @@ impl ScriptTask {
debug!("ClickEvent: clicked at {:?}", point);
let frame = page.frame();
let document = frame.get().get_ref().document.clone();
let document = frame.get_ref().document.clone();
let root = document.get().GetDocumentElement();
if root.is_none() {
return;
}
let (port, chan) = Chan::new();
let (chan, port) = channel();
let root: JS<Node> = NodeCast::from(&root.unwrap());
match page.query_layout(HitTestQuery(root.to_trusted_node_address(), point, chan), port) {
Ok(HitTestResponse(node_address)) => {
debug!("node address is {:?}", node_address);
let mut node: JS<Node> =
NodeHelpers::from_untrusted_node_address(self.js_runtime.borrow().ptr,
NodeHelpers::from_untrusted_node_address(self.js_runtime.deref().ptr,
node_address);
debug!("clicked on {:s}", node.debug_str());
@ -1045,21 +1038,21 @@ impl ScriptTask {
MouseUpEvent(..) => {}
MouseMoveEvent(point) => {
let frame = page.frame();
let document = frame.get().get_ref().document.clone();
let document = frame.get_ref().document.clone();
let root = document.get().GetDocumentElement();
if root.is_none() {
return;
}
let root: JS<Node> = NodeCast::from(&root.unwrap());
let (port, chan) = Chan::new();
let (chan, port) = channel();
match page.query_layout(MouseOverQuery(root.to_trusted_node_address(), point, chan), port) {
Ok(MouseOverResponse(node_address)) => {
let mut target_list: ~[JS<Node>] = ~[];
let mut target_compare = false;
let mut mouse_over_targets = self.mouse_over_targets.borrow_mut();
match *mouse_over_targets.get() {
let mouse_over_targets = &mut *self.mouse_over_targets.borrow_mut();
match *mouse_over_targets {
Some(ref mut mouse_over_targets) => {
for node in mouse_over_targets.mut_iter() {
node.set_hover_state(false);
@ -1071,7 +1064,7 @@ impl ScriptTask {
for node_address in node_address.iter() {
let mut node: JS<Node> =
NodeHelpers::from_untrusted_node_address(
self.js_runtime.borrow().ptr, *node_address);
self.js_runtime.deref().ptr, *node_address);
// Traverse node generations until a node that is an element is
// found.
while !node.is_element() {
@ -1084,7 +1077,7 @@ impl ScriptTask {
if node.is_element() {
node.set_hover_state(true);
match *mouse_over_targets.get() {
match *mouse_over_targets {
Some(ref mouse_over_targets) => {
if !target_compare {
target_compare = !mouse_over_targets.contains(&node);
@ -1095,7 +1088,7 @@ impl ScriptTask {
target_list.push(node);
}
}
match *mouse_over_targets.get() {
match *mouse_over_targets {
Some(ref mouse_over_targets) => {
if mouse_over_targets.len() != target_list.len() {
target_compare = true;
@ -1105,11 +1098,11 @@ impl ScriptTask {
}
if target_compare {
if mouse_over_targets.get().is_some() {
if mouse_over_targets.is_some() {
page.damage(MatchSelectorsDocumentDamage);
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor);
}
*mouse_over_targets.get() = Some(target_list);
*mouse_over_targets = Some(target_list);
}
},
Err(()) => {},
@ -1146,7 +1139,7 @@ fn shut_down_layout(page: &Page) {
page.join_layout();
// Tell the layout task to begin shutting down.
let (response_port, response_chan) = Chan::new();
let (response_chan, response_port) = channel();
let LayoutChan(ref chan) = page.layout_chan;
chan.send(layout_interface::PrepareToExitMsg(response_chan));
response_port.recv();
@ -1156,12 +1149,12 @@ fn shut_down_layout(page: &Page) {
let mut js_info = page.mut_js_info();
unsafe {
JS_AllowGC(js_info.get().get_ref().js_context.borrow().ptr);
JS_AllowGC(js_info.get_ref().js_context.deref().ptr);
}
let mut frame = page.mut_frame();
*frame.get() = None;
*js_info.get() = None;
*frame = None;
*js_info = None;
// Destroy the layout task. If there were node leaks, layout will now crash safely.
chan.send(layout_interface::ExitNowMsg);