@@ -35,7 +35,7 @@ type env = @rec(
35
35
36
36
tag resolve_result {
37
37
rr_ok( ast. def_id ) ;
38
- rr_not_found ( vec [ ast . ident ] , ast. ident ) ;
38
+ rr_not_found ( ast. ident ) ;
39
39
}
40
40
41
41
// Type decoding
@@ -253,94 +253,15 @@ fn parse_def_id(vec[u8] buf) -> ast.def_id {
253
253
ret tup( crate_num, def_num) ;
254
254
}
255
255
256
- // Given a path and serialized crate metadata, returns the ID of the
257
- // definition the path refers to.
258
- impure fn resolve_path ( vec[ ast. ident ] path, vec[ u8] data) -> resolve_result {
259
- impure fn resolve_path_inner( vec[ ast. ident ] path, & ebml. reader ebml_r)
260
- -> resolve_result {
261
- auto i = 0 u;
262
- auto len = _vec. len [ ast. ident ] ( path) ;
263
- while ( i < len) {
264
- auto name = path. ( i) ;
265
- auto last = i == len - 1 u;
266
-
267
- // Search this level for the identifier.
268
- auto found = false ;
269
- while ( ebml. bytes_left ( ebml_r) > 0 u && !found) {
270
- auto ebml_tag = ebml. peek ( ebml_r) ;
271
- if ( ( ebml_tag. id == metadata. tag_paths_data_item ) ||
272
- ( ebml_tag. id == metadata. tag_paths_data_mod ) ) {
273
- ebml. move_to_first_child ( ebml_r) ;
274
- auto did_opt = none[ ast. def_id ] ;
275
- auto name_opt = none[ ast. ident ] ;
276
- while ( ebml. bytes_left ( ebml_r) > 0 u) {
277
- auto inner_tag = ebml. peek ( ebml_r) ;
278
- if ( inner_tag. id == metadata. tag_paths_data_name ) {
279
- ebml. move_to_first_child ( ebml_r) ;
280
- auto name_data = ebml. read_data ( ebml_r) ;
281
- ebml. move_to_parent ( ebml_r) ;
282
- auto nm = _str. unsafe_from_bytes ( name_data) ;
283
- name_opt = some[ ast. ident ] ( nm) ;
284
- } else if ( inner_tag. id == metadata. tag_def_id ) {
285
- ebml. move_to_first_child ( ebml_r) ;
286
- auto did_data = ebml. read_data ( ebml_r) ;
287
- ebml. move_to_parent ( ebml_r) ;
288
- auto did = parse_def_id ( did_data) ;
289
- did_opt = some[ ast. def_id ] ( did) ;
290
- }
291
- ebml. move_to_next_sibling ( ebml_r) ;
292
- }
293
- ebml. move_to_parent ( ebml_r) ;
294
-
295
- if ( _str. eq ( option. get [ ast. ident ] ( name_opt) , name) ) {
296
- // Matched!
297
- if ( last) {
298
- ret rr_ok ( option. get [ ast. def_id ] ( did_opt) ) ;
299
- }
300
-
301
- // Move to the module/item we found for the next
302
- // iteration of the loop...
303
- ebml. move_to_first_child ( ebml_r) ;
304
- found = true ;
305
- }
306
- }
307
- ebml. move_to_next_sibling ( ebml_r) ;
308
- }
309
-
310
- if ( !found) {
311
- auto prev = _vec. slice [ ast. ident ] ( path, 0 u, i) ;
312
- ret rr_not_found ( prev, name) ;
313
- }
314
-
315
- i += 1 u;
316
- }
317
-
318
- fail; // not reached
319
- }
320
-
321
- auto io_r = io. new_reader_ ( io. new_byte_buf_reader ( data) ) ;
322
- auto ebml_r = ebml. create_reader ( io_r) ;
323
- while ( ebml. bytes_left ( ebml_r) > 0 u) {
324
- auto ebml_tag = ebml. peek ( ebml_r) ;
325
- if ( ebml_tag. id == metadata. tag_paths ) {
326
- ebml. move_to_first_child ( ebml_r) ;
327
- ret resolve_path_inner ( path, ebml_r) ;
328
- }
329
- ebml. move_to_next_sibling ( ebml_r) ;
330
- }
331
-
332
- log "resolve_path(): no names in file" ;
333
- fail;
334
- }
335
-
336
- impure fn move_to_item ( & ebml. reader ebml_r, int item_id) {
337
- ebml. move_to_sibling_with_id ( ebml_r, metadata. tag_items ) ;
256
+ impure fn lookup_hash_entry ( & ebml. reader ebml_r,
257
+ impure fn( & ebml. reader ) -> bool eq_fn,
258
+ uint hash) -> bool {
338
259
ebml. move_to_child_with_id ( ebml_r, metadata. tag_index ) ;
339
260
ebml. move_to_child_with_id ( ebml_r, metadata. tag_index_table ) ;
340
261
ebml. move_to_first_child ( ebml_r) ;
341
262
342
263
// Move to the bucket.
343
- auto bucket_index = metadata . hash_def_num ( item_id ) % 256 u;
264
+ auto bucket_index = hash % 256 u;
344
265
auto buf_reader = ebml_r. reader . get_buf_reader ( ) ;
345
266
buf_reader. seek ( ( bucket_index * 4 u) as int , io. seek_cur ) ;
346
267
auto bucket_pos = ebml_r. reader . read_be_uint ( 4 u) ;
@@ -353,21 +274,57 @@ impure fn move_to_item(&ebml.reader ebml_r, int item_id) {
353
274
if ( ebml. peek ( ebml_r) . id == metadata. tag_index_buckets_bucket_elt ) {
354
275
ebml. move_to_first_child ( ebml_r) ;
355
276
auto pos = ebml_r. reader . read_be_uint ( 4 u) ;
356
- auto this_item_id = ebml_r. reader . read_be_uint ( 4 u) as int ;
357
- if ( item_id == this_item_id) {
277
+ if ( eq_fn ( ebml_r) ) {
358
278
// Found the item. Move to its data and return.
359
279
ebml. reset_reader ( ebml_r, pos) ;
360
- check ( ebml. peek ( ebml_r) . id == metadata. tag_items_data_item ) ;
361
280
ebml. move_to_first_child ( ebml_r) ;
362
- ret;
281
+ ret true ;
363
282
}
364
283
ebml. move_to_parent ( ebml_r) ;
365
284
}
366
285
ebml. move_to_next_sibling ( ebml_r) ;
367
286
}
368
287
369
- log #fmt( "item %d not found in bucket at pos %u" , item_id, bucket_pos) ;
370
- fail;
288
+ ret false;
289
+ }
290
+
291
+ // Given a path and serialized crate metadata, returns the ID of the
292
+ // definition the path refers to.
293
+ impure fn resolve_path( vec[ ast. ident ] path, vec[ u8] data) -> resolve_result {
294
+ impure fn eq_item( & ebml. reader ebml_r, str s) -> bool {
295
+ auto this_str = _str. unsafe_from_bytes ( ebml. read_data ( ebml_r) ) ;
296
+ ret _str. eq ( this_str, s) ;
297
+ }
298
+
299
+ auto s = _str. connect ( path, "." ) ;
300
+
301
+ auto io_r = io. new_reader_ ( io. new_byte_buf_reader ( data) ) ;
302
+ auto ebml_r = ebml. create_reader ( io_r) ;
303
+ ebml. move_to_sibling_with_id ( ebml_r, metadata. tag_paths ) ;
304
+
305
+ auto eqer = bind eq_item ( _, s) ;
306
+ auto hash = metadata. hash_path ( s) ;
307
+ if ( !lookup_hash_entry ( ebml_r, eqer, hash) ) {
308
+ ret rr_not_found ( s) ;
309
+ }
310
+
311
+ ebml. move_to_sibling_with_id ( ebml_r, metadata. tag_def_id ) ;
312
+ ebml. move_to_first_child ( ebml_r) ;
313
+ auto did_data = ebml. read_data ( ebml_r) ;
314
+ ebml. move_to_parent ( ebml_r) ;
315
+ auto did = parse_def_id ( did_data) ;
316
+ ret rr_ok( did) ;
317
+ }
318
+
319
+ impure fn move_to_item ( & ebml. reader ebml_r, int item_id) {
320
+ impure fn eq_item ( & ebml. reader ebml_r, int item_id) -> bool {
321
+ ret ( ebml_r. reader . read_be_uint ( 4 u) as int ) == item_id;
322
+ }
323
+
324
+ auto eqer = bind eq_item ( _, item_id) ;
325
+ auto hash = metadata. hash_def_num ( item_id) ;
326
+ ebml. move_to_sibling_with_id ( ebml_r, metadata. tag_items ) ;
327
+ lookup_hash_entry ( ebml_r, eqer, hash) ;
371
328
}
372
329
373
330
// Looks up an item in the given metadata and returns an EBML reader pointing
@@ -573,7 +530,7 @@ fn lookup_def(session.session sess, int cnum, vec[ast.ident] path)
573
530
auto did;
574
531
alt ( resolve_path( path, data) ) {
575
532
case ( rr_ok( ?di) ) { did = di; }
576
- case ( rr_not_found( ?prev , ? name) ) {
533
+ case ( rr_not_found( ?name) ) {
577
534
ret none[ ast. def] ;
578
535
}
579
536
}
0 commit comments