about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-04-27 14:21:17 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-04-30 10:44:31 -0700
commit2bb3b63ec4379b812aeceb690d78763ec55d3cbb (patch)
treef189a83d88971f52d155fb91438a4d8ad81033a4 /src
parentdc117fecde14706b3ab5fbcd64f743dba6de9e1b (diff)
downloadrust-2bb3b63ec4379b812aeceb690d78763ec55d3cbb.tar.gz
rust-2bb3b63ec4379b812aeceb690d78763ec55d3cbb.zip
Eliminate a copy in syntax::parse::new_parser_from_file
Fixing a FIXME turned out to be pretty involved. I added an io function
that returns a unique boxed string (for the contents of a file) rather than
a string, and went from there. Also made the src field of codemap a unique
boxed string. This doesn't seem to make that much difference in amount of
allocation according to valgrind (disappointingly), but I also had to introduce
a copy somewhere else pending a new snapshot, so maybe that's it.
Diffstat (limited to 'src')
-rw-r--r--src/fuzzer/fuzzer.rs12
-rw-r--r--src/libcore/core.rs2
-rw-r--r--src/libcore/io.rs18
-rw-r--r--src/libcore/str.rs21
-rw-r--r--src/librustsyntax/codemap.rs6
-rw-r--r--src/librustsyntax/ext/expand.rs2
-rw-r--r--src/librustsyntax/parse.rs27
-rw-r--r--src/librustsyntax/parse/comments.rs2
-rw-r--r--src/librustsyntax/parse/lexer.rs2
-rw-r--r--src/librustsyntax/parse/token.rs4
-rw-r--r--src/rustc/driver/driver.rs2
-rw-r--r--src/rustdoc/astsrv.rs11
-rw-r--r--src/rustdoc/extract.rs4
-rw-r--r--src/rustdoc/fold.rs8
-rw-r--r--src/rustdoc/parse.rs10
15 files changed, 88 insertions, 43 deletions
diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs
index 47c6371ad16..352038ef72b 100644
--- a/src/fuzzer/fuzzer.rs
+++ b/src/fuzzer/fuzzer.rs
@@ -271,7 +271,7 @@ fn check_variants_T<T: copy>(
                 // testing the string for stability is easier and ok for now.
                 let handler = diagnostic::mk_handler(none);
                 let str3 =
-                    @as_str(bind pprust::print_crate(
+                    ~as_str(bind pprust::print_crate(
                         codemap,
                         diagnostic::mk_span_handler(handler, codemap),
                         crate2,
@@ -417,7 +417,7 @@ fn check_compiling(filename: str) -> happiness {
 }
 
 
-fn parse_and_print(code: @str) -> str {
+fn parse_and_print(code: ~str) -> str {
     let filename = "tmp.rs";
     let cm = codemap::new_codemap();
     let handler = diagnostic::mk_handler(none);
@@ -507,7 +507,7 @@ fn file_might_not_converge(filename: str) -> bool {
     ret false;
 }
 
-fn check_roundtrip_convergence(code: @str, maxIters: uint) {
+fn check_roundtrip_convergence(+code: ~str, maxIters: uint) {
 
     let mut i = 0u;
     let mut newv = code;
@@ -516,7 +516,7 @@ fn check_roundtrip_convergence(code: @str, maxIters: uint) {
     while i < maxIters {
         oldv = newv;
         if content_might_not_converge(*oldv) { ret; }
-        newv = @parse_and_print(oldv);
+        newv = ~parse_and_print(oldv);
         if oldv == newv { break; }
         i += 1u;
     }
@@ -538,7 +538,7 @@ fn check_convergence(files: [str]) {
     #error("pp convergence tests: %u files", vec::len(files));
     for files.each {|file|
         if !file_might_not_converge(file) {
-            let s = @result::get(io::read_whole_file_str(file));
+            let s = ~result::get(io::read_whole_file_str(file));
             if !content_might_not_converge(*s) {
                 #error("pp converge: %s", file);
                 // Change from 7u to 2u once
@@ -557,7 +557,7 @@ fn check_variants(files: [str], cx: context) {
             cont;
         }
 
-        let s = @result::get(io::read_whole_file_str(file));
+        let s = ~result::get(io::read_whole_file_str(file));
         if contains(*s, "#") {
             cont; // Macros are confusing
         }
diff --git a/src/libcore/core.rs b/src/libcore/core.rs
index 8681f7d2a1c..84c15385a7f 100644
--- a/src/libcore/core.rs
+++ b/src/libcore/core.rs
@@ -49,7 +49,7 @@ mod std {
 
 #[doc = "
 A standard function to use to indicate unreachable code. Because the
-function is guaranteed to fail typestate will correctly identify
+function is guaranteed to fail, typestate will correctly identify
 any code paths following the appearance of this function as unreachable.
 "]
 fn unreachable() -> ! {
diff --git a/src/libcore/io.rs b/src/libcore/io.rs
index 0c723fc8c63..f61b622f088 100644
--- a/src/libcore/io.rs
+++ b/src/libcore/io.rs
@@ -650,6 +650,24 @@ fn read_whole_file_str(file: str) -> result<str, str> {
     })
 }
 
+/*
+  Returns the result as a unique boxed string rather than a string
+ */
+fn read_whole_file_ref(file: str) -> result<~str, str> {
+     let f = os::as_c_charp(file, {|pathbuf|
+        os::as_c_charp("r", {|modebuf|
+            libc::fopen(pathbuf, modebuf)
+        })
+    });
+    ret if f as uint == 0u { result::err("error opening " + file) }
+        else unsafe {
+        let buf : ~mut [const u8] = ~mut [const];
+        let self = FILE_reader(f, true);
+        while (!self.eof()) { *buf += self.read_bytes(2048u); }
+        result::ok(str::unsafe::from_bytes_move(buf))
+    }
+}
+
 // FIXME implement this in a low-level way. Going through the abstractions is
 // pointless. // #2004
 fn read_whole_file(file: str) -> result<[u8], str> {
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 12258f5eb27..1fff066c025 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -124,6 +124,19 @@ fn from_bytes(vv: [u8]) -> str unsafe {
 }
 
 #[doc = "
+Convert a unique vector of bytes (passed by move)
+   to a unique boxed UTF-8 string
+
+# Failure
+
+Fails if invalid UTF-8
+"]
+fn from_bytes_move(-vv: ~mut [const u8]) -> ~str unsafe {
+   assert is_utf8(::unsafe::reinterpret_cast(vv));
+   ret unsafe::from_bytes_move(vv);
+}
+
+#[doc = "
 Convert a byte to a UTF-8 string
 
 # Failure
@@ -1631,6 +1644,7 @@ mod unsafe {
       from_buf,
       from_c_str,
       from_bytes,
+      from_bytes_move,
       slice_bytes,
       push_byte,
       pop_byte,
@@ -1685,6 +1699,13 @@ mod unsafe {
        ret scopy;
    }
 
+   unsafe fn from_bytes_move(-v: ~mut [const u8]) -> ~str unsafe {
+     *v += [0u8];
+     let s: ~str = ::unsafe::reinterpret_cast(v);
+     ::unsafe::forget(v);
+     s
+   }
+
    #[doc = "
    Converts a byte to a string.
 
diff --git a/src/librustsyntax/codemap.rs b/src/librustsyntax/codemap.rs
index b8579f6733d..2340bb5ab1d 100644
--- a/src/librustsyntax/codemap.rs
+++ b/src/librustsyntax/codemap.rs
@@ -38,7 +38,7 @@ enum file_substr {
 }
 
 type filemap =
-    @{name: filename, substr: file_substr, src: @str,
+    @{name: filename, substr: file_substr, src: ~str,
       start_pos: file_pos, mut lines: [file_pos]};
 
 type codemap = @{mut files: [filemap]};
@@ -48,7 +48,7 @@ type loc = {file: filemap, line: uint, col: uint};
 fn new_codemap() -> codemap { @{mut files: [] } }
 
 fn new_filemap_w_substr(filename: filename, substr: file_substr,
-                        src: @str,
+                        -src: ~str,
                         start_pos_ch: uint, start_pos_byte: uint)
    -> filemap {
     ret @{name: filename, substr: substr, src: src,
@@ -56,7 +56,7 @@ fn new_filemap_w_substr(filename: filename, substr: file_substr,
           mut lines: [{ch: start_pos_ch, byte: start_pos_byte}]};
 }
 
-fn new_filemap(filename: filename, src: @str,
+fn new_filemap(filename: filename, -src: ~str,
                start_pos_ch: uint, start_pos_byte: uint)
     -> filemap {
     ret new_filemap_w_substr(filename, fss_none, src,
diff --git a/src/librustsyntax/ext/expand.rs b/src/librustsyntax/ext/expand.rs
index f70a75bd96a..ae4fc082141 100644
--- a/src/librustsyntax/ext/expand.rs
+++ b/src/librustsyntax/ext/expand.rs
@@ -121,7 +121,7 @@ fn expand_crate(parse_sess: parse::parse_sess,
             with *afp};
     let f = make_fold(f_pre);
     let cm = parse_expr_from_source_str("<core-macros>",
-                                        @core_macros(),
+                                        ~core_macros(),
                                         cfg,
                                         parse_sess);
 
diff --git a/src/librustsyntax/parse.rs b/src/librustsyntax/parse.rs
index d1a997187da..d735af6d117 100644
--- a/src/librustsyntax/parse.rs
+++ b/src/librustsyntax/parse.rs
@@ -73,20 +73,22 @@ fn parse_crate_from_source_file(input: str, cfg: ast::crate_cfg,
     ret r;
 }
 
-fn parse_crate_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
-                               sess: parse_sess) -> @ast::crate {
+fn parse_crate_from_source_str(name: str, source: ~str,
+               cfg: ast::crate_cfg, sess: parse_sess) -> @ast::crate {
+  // FIXME: Get rid of copy once there's a snapshot
     let p = new_parser_from_source_str(
-        sess, cfg, name, codemap::fss_none, source);
+           sess, cfg, name, codemap::fss_none, @(*source));
     let r = parser::parse_crate_mod(p, cfg);
     sess.chpos = p.reader.chpos;
     sess.byte_pos = sess.byte_pos + p.reader.pos;
     ret r;
 }
 
-fn parse_expr_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
-                              sess: parse_sess) -> @ast::expr {
+fn parse_expr_from_source_str(name: str, source: ~str,
+               cfg: ast::crate_cfg, sess: parse_sess) -> @ast::expr {
+  // FIXME: Get rid of copy once there's a snapshot
     let p = new_parser_from_source_str(
-        sess, cfg, name, codemap::fss_none, source);
+        sess, cfg, name, codemap::fss_none, @(*source));
     let r = parser::parse_expr(p);
     sess.chpos = p.reader.chpos;
     sess.byte_pos = sess.byte_pos + p.reader.pos;
@@ -134,12 +136,15 @@ fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader,
       restricted_keywords: token::restricted_keyword_table()}
 }
 
+/* FIXME: still taking an @ b/c #ast using this.
+ Fix when there's a snapshot */
 fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
                               name: str, ss: codemap::file_substr,
                               source: @str) -> parser {
     let ftype = parser::SOURCE_FILE;
     let filemap = codemap::new_filemap_w_substr
-        (name, ss, source, sess.chpos, sess.byte_pos);
+      // FIXME: remove copy once there's a new snap
+      (name, ss, ~(*source), sess.chpos, sess.byte_pos);
     sess.cm.files += [filemap];
     let itr = @interner::mk(str::hash, str::eq);
     let rdr = lexer::new_reader(sess.span_diagnostic,
@@ -148,12 +153,10 @@ fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
 }
 
 fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg, path: str,
-                        ftype: parser::file_type) ->
-   parser {
-    let src = alt io::read_whole_file_str(path) {
+                        ftype: parser::file_type) -> parser {
+    let src = alt io::read_whole_file_ref(path) {
       result::ok(src) {
-        // FIXME: This copy is unfortunate
-        @src
+        src
       }
       result::err(e) {
         sess.span_diagnostic.handler().fatal(e)
diff --git a/src/librustsyntax/parse/comments.rs b/src/librustsyntax/parse/comments.rs
index 493ed7b369b..15319e21f40 100644
--- a/src/librustsyntax/parse/comments.rs
+++ b/src/librustsyntax/parse/comments.rs
@@ -154,7 +154,7 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
                                 path: str,
                                 srdr: io::reader) ->
    {cmnts: [cmnt], lits: [lit]} {
-    let src = @str::from_bytes(srdr.read_whole_stream());
+    let src = ~str::from_bytes(srdr.read_whole_stream());
     let itr = @interner::mk::<str>(str::hash, str::eq);
     let rdr = new_reader(span_diagnostic,
                          codemap::new_filemap(path, src, 0u, 0u), itr);
diff --git a/src/librustsyntax/parse/lexer.rs b/src/librustsyntax/parse/lexer.rs
index ec9f785db2f..321bf076a1e 100644
--- a/src/librustsyntax/parse/lexer.rs
+++ b/src/librustsyntax/parse/lexer.rs
@@ -6,7 +6,7 @@ export reader, new_reader, next_token, is_whitespace;
 
 type reader = @{
     span_diagnostic: diagnostic::span_handler,
-    src: @str,
+    src: ~str,
     mut col: uint,
     mut pos: uint,
     mut curr: char,
diff --git a/src/librustsyntax/parse/token.rs b/src/librustsyntax/parse/token.rs
index 3f9ce9d91b6..c962d4ec16c 100644
--- a/src/librustsyntax/parse/token.rs
+++ b/src/librustsyntax/parse/token.rs
@@ -124,7 +124,7 @@ fn to_str(in: interner<str>, t: token) -> str {
 
       /* Literals */
       LIT_INT(c, ast::ty_char) {
-        // FIXME: escape.
+        // FIXME: escape. (#2306)
         let mut tmp = "'";
         str::push_char(tmp, c as char);
         str::push_char(tmp, '\'');
@@ -140,7 +140,7 @@ fn to_str(in: interner<str>, t: token) -> str {
         ret interner::get::<str>(in, s) +
             ast_util::float_ty_to_str(t);
       }
-      LIT_STR(s) { // FIXME: escape.
+      LIT_STR(s) { // FIXME: escape. (#2306)
         ret "\"" + interner::get::<str>(in, s) + "\"";
       }
 
diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs
index 75c75c3217b..06e54c84b57 100644
--- a/src/rustc/driver/driver.rs
+++ b/src/rustc/driver/driver.rs
@@ -78,7 +78,7 @@ fn parse_input(sess: session, cfg: ast::crate_cfg, input: str)
     if !input_is_stdin(input) {
         parse::parse_crate_from_file(input, cfg, sess.parse_sess)
     } else {
-        let src = @str::from_bytes(io::stdin().read_whole_stream());
+        let src = ~str::from_bytes(io::stdin().read_whole_stream());
         parse::parse_crate_from_source_str(input, src, cfg, sess.parse_sess)
     }
 }
diff --git a/src/rustdoc/astsrv.rs b/src/rustdoc/astsrv.rs
index 71716ea059e..f1eae1b4619 100644
--- a/src/rustdoc/astsrv.rs
+++ b/src/rustdoc/astsrv.rs
@@ -36,7 +36,10 @@ type ctxt = {
 
 type srv_owner<T> = fn(srv: srv) -> T;
 type ctxt_handler<T> = fn~(ctxt: ctxt) -> T;
-type parser = fn~(session::session, str) -> @ast::crate;
+/* The idea is that a parser takes an input of type U,
+   which lets us have parsers that either take unboxed or
+   boxed strings. */
+type parser<U> = fn~(session::session, U) -> @ast::crate;
 
 enum msg {
     handle_request(fn~(ctxt)),
@@ -48,14 +51,14 @@ enum srv = {
 };
 
 fn from_str<T>(source: str, owner: srv_owner<T>) -> T {
-    run(owner, source, parse::from_str_sess)
+    run(owner, ~source, parse::from_str_sess)
 }
 
 fn from_file<T>(file: str, owner: srv_owner<T>) -> T {
     run(owner, file, parse::from_file_sess)
 }
 
-fn run<T>(owner: srv_owner<T>, source: str, parse: parser) -> T {
+fn run<T, U: send>(owner: srv_owner<T>, +source: U, parse: parser<U>) -> T {
 
     let srv_ = srv({
         ch: task::spawn_listener {|po|
@@ -68,7 +71,7 @@ fn run<T>(owner: srv_owner<T>, source: str, parse: parser) -> T {
     ret res;
 }
 
-fn act(po: comm::port<msg>, source: str, parse: parser) {
+fn act<U>(po: comm::port<msg>, source: U, parse: parser<U>) {
     let (sess, ignore_errors) = build_session();
 
     let ctxt = build_ctxt(
diff --git a/src/rustdoc/extract.rs b/src/rustdoc/extract.rs
index fc54a1ea9f6..1eaaa967d2d 100644
--- a/src/rustdoc/extract.rs
+++ b/src/rustdoc/extract.rs
@@ -289,7 +289,7 @@ fn should_extract_tys() {
 mod test {
 
     fn mk_doc(source: str) -> doc::doc {
-        let ast = parse::from_str(source);
+        let ast = parse::from_str(~source);
         extract(ast, "")
     }
 
@@ -349,7 +349,7 @@ mod test {
 
     #[test]
     fn extract_should_use_default_crate_name() {
-        let source = "";
+        let source = ~"";
         let ast = parse::from_str(source);
         let doc = extract(ast, "burp");
         assert doc.cratemod().name() == "burp";
diff --git a/src/rustdoc/fold.rs b/src/rustdoc/fold.rs
index 87b9d85637c..a9aace20d1d 100644
--- a/src/rustdoc/fold.rs
+++ b/src/rustdoc/fold.rs
@@ -354,7 +354,7 @@ fn default_seq_fold_type<T>(
 #[test]
 fn default_fold_should_produce_same_doc() {
     let source = "mod a { fn b() { } mod c { fn d() { } } }";
-    let ast = parse::from_str(source);
+    let ast = parse::from_str(~source);
     let doc = extract::extract(ast, "");
     let fld = default_seq_fold(());
     let folded = fld.fold_doc(fld, doc);
@@ -364,7 +364,7 @@ fn default_fold_should_produce_same_doc() {
 #[test]
 fn default_fold_should_produce_same_consts() {
     let source = "const a: int = 0;";
-    let ast = parse::from_str(source);
+    let ast = parse::from_str(~source);
     let doc = extract::extract(ast, "");
     let fld = default_seq_fold(());
     let folded = fld.fold_doc(fld, doc);
@@ -374,7 +374,7 @@ fn default_fold_should_produce_same_consts() {
 #[test]
 fn default_fold_should_produce_same_enums() {
     let source = "enum a { b }";
-    let ast = parse::from_str(source);
+    let ast = parse::from_str(~source);
     let doc = extract::extract(ast, "");
     let fld = default_seq_fold(());
     let folded = fld.fold_doc(fld, doc);
@@ -384,7 +384,7 @@ fn default_fold_should_produce_same_enums() {
 #[test]
 fn default_parallel_fold_should_produce_same_doc() {
     let source = "mod a { fn b() { } mod c { fn d() { } } }";
-    let ast = parse::from_str(source);
+    let ast = parse::from_str(~source);
     let doc = extract::extract(ast, "");
     let fld = default_par_fold(());
     let folded = fld.fold_doc(fld, doc);
diff --git a/src/rustdoc/parse.rs b/src/rustdoc/parse.rs
index 3ad8f51e8db..8c4c385c55b 100644
--- a/src/rustdoc/parse.rs
+++ b/src/rustdoc/parse.rs
@@ -27,18 +27,18 @@ fn from_file(file: str) -> @ast::crate {
         file, [], new_parse_sess())
 }
 
-fn from_str(source: str) -> @ast::crate {
+fn from_str(source: ~str) -> @ast::crate {
     parse::parse_crate_from_source_str(
-        "-", @source, [], new_parse_sess())
+        "-", source, [], new_parse_sess())
 }
 
-fn from_file_sess(sess: session::session, file: str) -> @ast::crate {
+fn from_file_sess(sess: session::session, &&file: str) -> @ast::crate {
     parse::parse_crate_from_file(file, cfg(sess), sess.parse_sess)
 }
 
-fn from_str_sess(sess: session::session, source: str) -> @ast::crate {
+fn from_str_sess(sess: session::session, &&source: ~str) -> @ast::crate {
     parse::parse_crate_from_source_str(
-        "-", @source, cfg(sess), sess.parse_sess)
+        "-", source, cfg(sess), sess.parse_sess)
 }
 
 fn cfg(sess: session::session) -> ast::crate_cfg {