about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-03-31 14:37:09 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-03-31 14:37:44 -0700
commit3c1de96cda33e9547adda14dc66294752c99e4c3 (patch)
tree63d8743667358697013299ba452f412f48c658f2
parentef0c903f6a25cd9d8c900fbde336d4a4a5b43c56 (diff)
rustc: Use the crate index to look up defs
-rw-r--r--src/comp/front/creader.rs55
-rw-r--r--src/lib/ebml.rs21
-rw-r--r--src/lib/io.rs11
3 files changed, 58 insertions, 29 deletions
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs
index c285edd0b79..d95e4523b5a 100644
--- a/src/comp/front/creader.rs
+++ b/src/comp/front/creader.rs
@@ -328,43 +328,40 @@ impure fn resolve_path(vec[ast.ident] path, vec[u8] data) -> resolve_result {
 }
 
 impure fn move_to_item(&ebml.reader ebml_r, int item_id) {
-    while (ebml.bytes_left(ebml_r) > 0u) {
-        auto outer_ebml_tag = ebml.peek(ebml_r);
-        if (outer_ebml_tag.id == metadata.tag_items) {
-            ebml.move_to_first_child(ebml_r);
-
-            while (ebml.bytes_left(ebml_r) > 0u) {
-                auto inner_ebml_tag = ebml.peek(ebml_r);
-                if (inner_ebml_tag.id == metadata.tag_items_data_item) {
-                    ebml.move_to_first_child(ebml_r);
+    ebml.move_to_sibling_with_id(ebml_r, metadata.tag_items);
+    ebml.move_to_child_with_id(ebml_r, metadata.tag_items_index);
+    ebml.move_to_child_with_id(ebml_r, metadata.tag_items_index_table);
+    ebml.move_to_first_child(ebml_r);
 
-                    while (ebml.bytes_left(ebml_r) > 0u) {
-                        auto innermost_ebml_tag = ebml.peek(ebml_r);
-                        if (innermost_ebml_tag.id == metadata.tag_def_id) {
-                            ebml.move_to_first_child(ebml_r);
-                            auto did_data = ebml.read_data(ebml_r);
-                            ebml.move_to_parent(ebml_r);
+    // Move to the bucket.
+    auto bucket_index = metadata.hash_def_num(item_id) % 256u;
+    auto buf_reader = ebml_r.reader.get_buf_reader();
+    buf_reader.seek((bucket_index * 4u) as int, io.seek_cur);
+    auto bucket_pos = ebml_r.reader.read_be_uint(4u);
+    ebml.reset_reader(ebml_r, bucket_pos);
 
-                            auto this_did = parse_def_id(did_data);
-                            if (this_did._1 == item_id) {
-                                // Move to the start of this item's data.
-                                ebml.move_to_parent(ebml_r);
-                                ebml.move_to_first_child(ebml_r);
-                                ret;
-                            }
-                        }
-                        ebml.move_to_next_sibling(ebml_r);
-                    }
-                    ebml.move_to_parent(ebml_r);
-                }
-                ebml.move_to_next_sibling(ebml_r);
+    // Search to find the item ID in the bucket.
+    check (ebml.peek(ebml_r).id == metadata.tag_items_index_buckets_bucket);
+    ebml.move_to_first_child(ebml_r);
+    while (ebml.bytes_left(ebml_r) > 0u) {
+        if (ebml.peek(ebml_r).id ==
+                metadata.tag_items_index_buckets_bucket_elt) {
+            ebml.move_to_first_child(ebml_r);
+            auto pos = ebml_r.reader.read_be_uint(4u);
+            auto this_item_id = ebml_r.reader.read_be_uint(4u) as int;
+            if (item_id == this_item_id) {
+                // Found the item. Move to its data and return.
+                ebml.reset_reader(ebml_r, pos);
+                check (ebml.peek(ebml_r).id == metadata.tag_items_data_item);
+                ebml.move_to_first_child(ebml_r);
+                ret;
             }
             ebml.move_to_parent(ebml_r);
         }
         ebml.move_to_next_sibling(ebml_r);
     }
 
-    log #fmt("move_to_item: item not found: %d", item_id);
+    log #fmt("item %d not found in bucket at pos %u", item_id, bucket_pos);
     fail;
 }
 
diff --git a/src/lib/ebml.rs b/src/lib/ebml.rs
index 047218a33a6..8ed249130f2 100644
--- a/src/lib/ebml.rs
+++ b/src/lib/ebml.rs
@@ -90,11 +90,32 @@ impure fn move_to_parent(&reader r) {
     r.reader.seek(st.tag_pos as int, io.seek_set);
 }
 
+// Moves to the sibling of the current item with the given tag ID.
+impure fn move_to_sibling_with_id(&reader r, uint tag_id) {
+    while (peek(r).id != tag_id) {
+        move_to_next_sibling(r);
+    }
+}
+
+// Moves to the first child of the current item with the given tag ID.
+impure fn move_to_child_with_id(&reader r, uint tag_id) {
+    move_to_first_child(r);
+    move_to_sibling_with_id(r, tag_id);
+}
+
 // Reads the data segment of a tag.
 impure fn read_data(&reader r) -> vec[u8] {
     ret r.reader.read_bytes(bytes_left(r));
 }
 
+// Blows away the tag stack and moves the reader to the given byte position.
+impure fn reset_reader(&reader r, uint pos) {
+    // FIXME: rustc "ty_var in trans.type_of" bug
+    let vec[ebml_state] states = vec();
+    r.states = states;
+    r.reader.seek(pos as int, io.seek_set);
+}
+
 impure fn peek(&reader r) -> ebml_tag {
     check (bytes_left(r) > 0u);
     auto pos = r.reader.tell();
diff --git a/src/lib/io.rs b/src/lib/io.rs
index 11e6408c626..7c6c0970fe8 100644
--- a/src/lib/io.rs
+++ b/src/lib/io.rs
@@ -39,6 +39,7 @@ type reader =
           impure fn read_c_str() -> str;
           impure fn read_le_uint(uint size) -> uint;
           impure fn read_le_int(uint size) -> int;
+          impure fn read_be_uint(uint size) -> uint;
 
           impure fn seek(int offset, seek_style whence);
           impure fn tell() -> uint; // FIXME: eventually u64
@@ -167,6 +168,16 @@ state obj new_reader(buf_reader rdr) {
         }
         ret val as int;
     }
+    // FIXME deal with eof?
+    impure fn read_be_uint(uint size) -> uint {
+        auto val = 0u;
+        auto sz = size; // FIXME: trans.ml bug workaround
+        while (sz > 0u) {
+            sz -= 1u;
+            val += (read_byte_from_buf_reader(rdr) as uint) << (sz * 8u);
+        }
+        ret val;
+    }
     impure fn seek(int offset, seek_style whence) {
         ret rdr.seek(offset, whence);
     }