servo: Feed the HTML/CSS parsers with the ResourceTask

Source-Repo: https://github.com/servo/servo
Source-Revision: 6430d74ecea417ea3c65a62881792192e56482dc
This commit is contained in:
Brian Anderson 2012-07-27 19:16:04 -07:00
Родитель d42a90907a
Коммит a16038af5d
6 изменённых файлов: 86 добавлений и 42 удалений

Просмотреть файл

@ -131,7 +131,7 @@ class Content<S:Sink send copy> {
// Note: we can parse the next document in parallel // Note: we can parse the next document in parallel
// with any previous documents. // with any previous documents.
let stream = spawn_html_lexer_task(copy url, self.resource_task); let stream = spawn_html_lexer_task(copy url, self.resource_task);
let (root, style_port, js_port) = build_dom(self.scope, stream, url); let (root, style_port, js_port) = build_dom(self.scope, stream, url, self.resource_task);
let css_rules = style_port.recv(); let css_rules = style_port.recv();
let js_scripts = js_port.recv(); let js_scripts = js_port.recv();

Просмотреть файл

@ -184,12 +184,16 @@ impl parser_methods of parser_methods for TokenReader {
some(list){ copy list } some(list){ copy list }
none { ret none; } none { ret none; }
}; };
#debug("sel_list: %?", sel_list);
// Get the description to be applied to the selector // Get the description to be applied to the selector
let desc_list = alt self.parse_description() { let desc_list = alt self.parse_description() {
some(list) { copy list } some(list) { copy list }
none { ret none; } none { ret none; }
}; };
#debug("desc_list: %?", desc_list);
ret some(~(sel_list, desc_list)); ret some(~(sel_list, desc_list));
} }

Просмотреть файл

@ -10,6 +10,8 @@ import pipes::{port, chan};
import lexer_util::*; import lexer_util::*;
import std::net::url::url; import std::net::url::url;
import resource::resource_task::{ResourceTask, ProgressMsg, Load};
import result::ok;
enum ParserState { enum ParserState {
CssElement, CssElement,
@ -225,13 +227,20 @@ impl css_methods of css_methods for CssLexer {
} }
} }
fn parser(reader: io::reader, state : ParserState) -> CssLexer { fn parser(input_port: comm::port<ProgressMsg>, state : ParserState) -> CssLexer {
ret { input_state: {mut lookahead: none, reader: reader}, mut parser_state: state }; ret {
input_state: {
mut lookahead: none,
mut buffer: ~[],
input_port: input_port,
mut eof: false
},
mut parser_state: state
};
} }
fn lex_css_from_bytes(-content : ~[u8], result_chan : chan<Token>) { fn lex_css_from_bytes(+input_port: comm::port<ProgressMsg>, result_chan : chan<Token>) {
let reader = io::bytes_reader(content); let lexer = parser(input_port, CssElement);
let lexer = parser(reader, CssElement);
loop { loop {
let token = lexer.parse_css(); let token = lexer.parse_css();
@ -245,32 +254,31 @@ fn lex_css_from_bytes(-content : ~[u8], result_chan : chan<Token>) {
} }
} }
fn spawn_css_lexer_from_string(-content : ~str) -> port<Token> { fn spawn_css_lexer_from_string(-content : ~str) -> pipes::port<Token> {
let (result_chan, result_port) = pipes::stream(); let (result_chan, result_port) = pipes::stream();
task::spawn(|| lex_css_from_bytes(str::bytes(content), result_chan)); do task::spawn {
let input_port = comm::port();
let chan = input_port.chan();
input_port.send(Payload(str::bytes(content)));
input_port.send(Done(ok(())));
lex_css_from_bytes(input_port, result_chan);
}
ret result_port; ret result_port;
} }
#[warn(no_non_implicitly_copyable_typarams)] #[warn(no_non_implicitly_copyable_typarams)]
fn spawn_css_lexer_task(-url: url) -> pipes::port<Token> { fn spawn_css_lexer_task(-url: url, resource_task: ResourceTask) -> pipes::port<Token> {
let (result_chan, result_port) = pipes::stream(); let (result_chan, result_port) = pipes::stream();
task::spawn(|| { task::spawn(|| {
assert url.path.ends_with(".css"); assert url.path.ends_with(".css");
let file_try = io::read_whole_file(url.path); let input_port = port();
resource_task.send(Load(url, input_port.chan()));
// Check if the given css file existed, if it does, parse it, lex_css_from_bytes(input_port, result_chan);
// otherwise just send an eof.
if file_try.is_ok() {
#debug["Lexing css sheet %?", url.path];
let file_data = file_try.get();
lex_css_from_bytes(file_data, result_chan);
} else {
#debug["Failed to open css sheet %?", url.path];
result_chan.send(Eof);
}
}); });
ret result_port; ret result_port;

Просмотреть файл

@ -13,7 +13,7 @@ import parser::Token;
import dom::style::Stylesheet; import dom::style::Stylesheet;
import vec::{push, push_all_move, flat_map}; import vec::{push, push_all_move, flat_map};
import std::net::url::url; import std::net::url::url;
import resource::resource_task::ResourceTask;
import dvec::extensions; import dvec::extensions;
enum CSSMessage { enum CSSMessage {
@ -95,7 +95,8 @@ spawned, collates them, and sends them to the given result channel.
* `from_parent` - A port on which to receive new links. * `from_parent` - A port on which to receive new links.
"] "]
fn css_link_listener(to_parent : comm::chan<Stylesheet>, from_parent : comm::port<CSSMessage>) { fn css_link_listener(to_parent : comm::chan<Stylesheet>, from_parent : comm::port<CSSMessage>,
resource_task: ResourceTask) {
let mut result_vec = ~[]; let mut result_vec = ~[];
loop { loop {
@ -104,7 +105,7 @@ fn css_link_listener(to_parent : comm::chan<Stylesheet>, from_parent : comm::por
let result_port = comm::port(); let result_port = comm::port();
let result_chan = comm::chan(result_port); let result_chan = comm::chan(result_port);
task::spawn(|| { task::spawn(|| {
let css_stream = css_lexer::spawn_css_lexer_task(copy url); let css_stream = css_lexer::spawn_css_lexer_task(copy url, resource_task);
let mut css_rules = css_builder::build_stylesheet(css_stream); let mut css_rules = css_builder::build_stylesheet(css_stream);
result_chan.send(css_rules); result_chan.send(css_rules);
}); });
@ -153,7 +154,8 @@ fn js_script_listener(to_parent : comm::chan<~[~[u8]]>, from_parent : comm::port
} }
#[warn(no_non_implicitly_copyable_typarams)] #[warn(no_non_implicitly_copyable_typarams)]
fn build_dom(scope: NodeScope, stream: comm::port<Token>, url: url) -> (Node, comm::port<Stylesheet>, comm::port<~[~[u8]]>) { fn build_dom(scope: NodeScope, stream: comm::port<Token>, url: url,
resource_task: ResourceTask) -> (Node, comm::port<Stylesheet>, comm::port<~[~[u8]]>) {
// The current reference node. // The current reference node.
let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement))); let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement)));
// We will spawn a separate task to parse any css that is // We will spawn a separate task to parse any css that is
@ -164,7 +166,7 @@ fn build_dom(scope: NodeScope, stream: comm::port<Token>, url: url) -> (Node, co
let style_port = comm::port(); let style_port = comm::port();
let child_chan = comm::chan(style_port); let child_chan = comm::chan(style_port);
let style_chan = task::spawn_listener(|child_port| { let style_chan = task::spawn_listener(|child_port| {
css_link_listener(child_chan, child_port); css_link_listener(child_chan, child_port, resource_task);
}); });
let js_port = comm::port(); let js_port = comm::port();

Просмотреть файл

@ -5,7 +5,7 @@ import str::from_bytes;
import vec::push; import vec::push;
import lexer_util::*; import lexer_util::*;
import resource::resource_task; import resource::resource_task;
import resource_task::{ResourceTask}; import resource_task::{ResourceTask, ProgressMsg, Load};
import std::net::url::url; import std::net::url::url;
enum Token { enum Token {
@ -166,8 +166,16 @@ impl html_methods of html_methods for HtmlLexer {
} }
} }
fn lexer(reader: io::reader, state : ParseState) -> HtmlLexer { fn lexer(+input_port: port<resource_task::ProgressMsg>, state : ParseState) -> HtmlLexer {
ret { input_state: {mut lookahead: none, reader: reader}, mut parser_state: state }; ret {
input_state: {
mut lookahead: none,
mut buffer: ~[],
input_port: input_port,
mut eof: false
},
mut parser_state: state
};
} }
#[warn(no_non_implicitly_copyable_typarams)] #[warn(no_non_implicitly_copyable_typarams)]
@ -177,10 +185,10 @@ fn spawn_html_lexer_task(-url: url, resource_task: ResourceTask) -> port<Token>
task::spawn(|| { task::spawn(|| {
assert url.path.ends_with(~".html"); assert url.path.ends_with(~".html");
let file_data = io::read_whole_file(url.path).get(); let input_port = port();
let reader = io::bytes_reader(file_data); resource_task.send(Load(url, input_port.chan()));
let lexer = lexer(reader, NormalHtml); let lexer = lexer(input_port, NormalHtml);
loop { loop {
let token = lexer.parse_html(); let token = lexer.parse_html();

Просмотреть файл

@ -3,6 +3,8 @@
import option::is_none; import option::is_none;
import str::from_bytes; import str::from_bytes;
import vec::push; import vec::push;
import comm::{port, methods};
import resource::resource_task::{ProgressMsg, Payload, Done};
enum CharOrEof { enum CharOrEof {
CoeChar(u8), CoeChar(u8),
@ -11,7 +13,9 @@ enum CharOrEof {
type InputState = { type InputState = {
mut lookahead: option<CharOrEof>, mut lookahead: option<CharOrEof>,
reader: io::reader mut buffer: ~[u8],
input_port: port<ProgressMsg>,
mut eof: bool
}; };
trait u8_methods { trait u8_methods {
@ -43,18 +47,36 @@ trait util_methods {
impl util_methods of util_methods for InputState { impl util_methods of util_methods for InputState {
fn get() -> CharOrEof { fn get() -> CharOrEof {
alt copy self.lookahead { alt copy self.lookahead {
some(coe) { some(coe) {
let rv = coe; let rv = coe;
self.lookahead = none; self.lookahead = none;
ret rv; ret rv;
} }
none { none {
/* fall through */ /* fall through */
} }
} }
if self.reader.eof() { ret CoeEof; } // FIXME: Lots of copies here
ret CoeChar(self.reader.read_byte() as u8);
if self.buffer.len() > 0 {
ret CoeChar(vec::shift(self.buffer));
}
if self.eof {
ret CoeEof;
}
alt self.input_port.recv() {
Payload(data) {
self.buffer = data;
ret CoeChar(vec::shift(self.buffer));
}
Done(*) {
self.eof = true;
ret CoeEof;
}
}
} }
fn unget(ch: u8) { fn unget(ch: u8) {