diff options
| author | Patrick Walton <[email protected]> | 2011-03-31 14:37:09 -0700 |
|---|---|---|
| committer | Patrick Walton <[email protected]> | 2011-03-31 14:37:44 -0700 |
| commit | 3c1de96cda33e9547adda14dc66294752c99e4c3 (patch) | |
| tree | 63d8743667358697013299ba452f412f48c658f2 /src | |
| parent | More stuff to go with the new expr_call_self AST node (diff) | |
| download | rust-3c1de96cda33e9547adda14dc66294752c99e4c3.tar.xz rust-3c1de96cda33e9547adda14dc66294752c99e4c3.zip | |
rustc: Use the crate index to look up defs
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/front/creader.rs | 55 | ||||
| -rw-r--r-- | src/lib/ebml.rs | 21 | ||||
| -rw-r--r-- | src/lib/io.rs | 11 |
3 files changed, 58 insertions, 29 deletions
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs index c285edd0..d95e4523 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 047218a3..8ed24913 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 11e6408c..7c6c0970 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); } |