@@ -8,6 +8,7 @@ import lib.llvm.llvmext;
8
8
import lib. llvm . mk_object_file ;
9
9
import lib. llvm . mk_section_iter ;
10
10
import middle. fold ;
11
+ import middle. metadata ;
11
12
import middle. ty ;
12
13
import middle. typeck ;
13
14
import back. x86 ;
@@ -16,8 +17,11 @@ import util.common.span;
16
17
17
18
import std. _str ;
18
19
import std. _vec ;
20
+ import std. ebml ;
19
21
import std. fs ;
22
+ import std. io ;
20
23
import std. option ;
24
+ import std. option . none ;
21
25
import std. option . some ;
22
26
import std. os ;
23
27
import std. map . hashmap ;
@@ -30,6 +34,11 @@ type env = @rec(
30
34
mutable int next_crate_num
31
35
) ;
32
36
37
+ tag resolve_result {
38
+ rr_ok( ast. def_id ) ;
39
+ rr_not_found ( vec[ ast. ident ] , ast. ident ) ;
40
+ }
41
+
33
42
// Type decoding
34
43
35
44
// Compact string representation for ty.t values. API ty_str & parse_from_str.
@@ -213,10 +222,96 @@ impure fn parse_ty_fn(@pstate st, str_def sd) -> tup(vec[ty.arg], @ty.t) {
213
222
214
223
// Rust metadata parsing
215
224
216
- // TODO
225
+ fn parse_def_id ( str s) -> ast. def_id {
226
+ ret tup ( 1 , 0 ) ; // TODO
227
+ }
228
+
229
+ // Given a path and serialized crate metadata, returns the ID of the
230
+ // definition the path refers to.
231
+ impure fn resolve_path ( vec[ ast. ident ] path, vec[ u8] data) -> resolve_result {
232
+ impure fn resolve_path_inner( vec[ ast. ident ] path, & ebml. reader ebml_r)
233
+ -> resolve_result {
234
+ auto i = 0 u;
235
+ auto len = _vec. len [ ast. ident ] ( path) ;
236
+ while ( i < len) {
237
+ auto name = path. ( i) ;
238
+ auto last = i == len - 1 u;
239
+
240
+ // Search this level for the identifier.
241
+ auto found = false ;
242
+ while ( ebml. bytes_left ( ebml_r) > 0 u && !found) {
243
+ auto ebml_tag = ebml. peek ( ebml_r) ;
244
+ check ( ( ebml_tag. id == metadata. tag_paths_item ) ||
245
+ ( ebml_tag. id == metadata. tag_paths_mod ) ) ;
246
+
247
+ ebml. move_to_first_child ( ebml_r) ;
248
+ auto did_opt = none[ ast. def_id ] ;
249
+ auto name_opt = none[ ast. ident ] ;
250
+ while ( ebml. bytes_left ( ebml_r) > 0 u) {
251
+ auto inner_tag = ebml. peek ( ebml_r) ;
252
+ if ( inner_tag. id == metadata. tag_paths_name ) {
253
+ ebml. move_to_first_child ( ebml_r) ;
254
+ auto name_data = ebml. read_data ( ebml_r) ;
255
+ ebml. move_to_parent ( ebml_r) ;
256
+ auto nm = _str. unsafe_from_bytes ( name_data) ;
257
+ name_opt = some[ ast. ident ] ( nm) ;
258
+ } else if ( inner_tag. id == metadata. tag_items_def_id ) {
259
+ ebml. move_to_first_child ( ebml_r) ;
260
+ auto did_data = ebml. read_data ( ebml_r) ;
261
+ ebml. move_to_parent ( ebml_r) ;
262
+ auto did_str = _str. unsafe_from_bytes ( did_data) ;
263
+ log "did_str: " + did_str;
264
+ did_opt = some[ ast. def_id ] ( parse_def_id ( did_str) ) ;
265
+ }
266
+ ebml. move_to_next_sibling ( ebml_r) ;
267
+ }
268
+ ebml. move_to_parent ( ebml_r) ;
269
+
270
+ if ( _str. eq ( option. get [ ast. ident ] ( name_opt) , name) ) {
271
+ // Matched!
272
+ if ( last) {
273
+ ret rr_ok ( option. get [ ast. def_id ] ( did_opt) ) ;
274
+ }
275
+
276
+ // Move to the module/item we found for the next iteration
277
+ // of the loop...
278
+ ebml. move_to_first_child ( ebml_r) ;
279
+ found = true ;
280
+ }
281
+
282
+ ebml. move_to_next_sibling ( ebml_r) ;
283
+ }
284
+
285
+ if ( !found) {
286
+ auto prev = _vec. slice [ ast. ident ] ( path, 0 u, i) ;
287
+ ret rr_not_found ( prev, name) ;
288
+ }
289
+
290
+ i += 1 u;
291
+ }
292
+
293
+ fail; // not reached
294
+ }
295
+
296
+ auto io_r = io. new_reader_ ( io. new_byte_buf_reader ( data) ) ;
297
+ auto ebml_r = ebml. create_reader ( io_r) ;
298
+ while ( ebml. bytes_left ( ebml_r) > 0 u) {
299
+ auto ebml_tag = ebml. peek ( ebml_r) ;
300
+ log #fmt( "outer ebml tag id: %u" , ebml_tag. id ) ;
301
+ if ( ebml_tag. id == metadata. tag_paths ) {
302
+ ebml. move_to_first_child ( ebml_r) ;
303
+ ret resolve_path_inner ( path, ebml_r) ;
304
+ }
305
+ ebml. move_to_next_sibling ( ebml_r) ;
306
+ }
307
+
308
+ log "resolve_path(): no names in file" ;
309
+ fail;
310
+ }
217
311
218
312
219
313
fn load_crate( session . session sess,
314
+ int cnum ,
220
315
ast . ident ident,
221
316
vec[ str] library_search_paths ) {
222
317
auto filename = parser. default_native_name ( sess, ident) ;
@@ -235,6 +330,8 @@ fn load_crate(session.session sess,
235
330
auto cbuf = llvmext. LLVMGetSectionContents ( si. llsi) ;
236
331
auto csz = llvmext. LLVMGetSectionSize ( si. llsi) ;
237
332
auto cvbuf = cbuf as _vec. vbuf;
333
+ auto cvec = _vec. vec_from_vbuf[ u8] ( cvbuf, csz) ;
334
+ sess. set_external_crate( cnum, cvec) ;
238
335
ret;
239
336
}
240
337
llvmext. LLVMMoveToNextSection ( si. llsi) ;
@@ -252,8 +349,8 @@ fn fold_view_item_use(&env e, &span sp, ast.ident ident,
252
349
-> @ast. view_item {
253
350
auto cnum;
254
351
if ( !e. crate_cache. contains_key( ident) ) {
255
- load_crate( e. sess, ident, e. library_search_paths) ;
256
352
cnum = e. next_crate_num;
353
+ load_crate( e. sess, cnum, ident, e. library_search_paths) ;
257
354
e. crate_cache. insert( ident, e. next_crate_num) ;
258
355
e. next_crate_num += 1 ;
259
356
} else {
@@ -280,10 +377,27 @@ fn read_crates(session.session sess,
280
377
ret fold. fold_crate[ env] ( e, fld, crate ) ;
281
378
}
282
379
380
+
381
+ // Crate metadata queries
382
+
283
383
fn lookup_def( session. session sess, & span sp, int cnum, vec[ ast. ident] path)
284
- -> ast. def {
285
- // FIXME: fill in.
286
- fail;
384
+ -> ast. def {
385
+ auto data = sess. get_external_crate( cnum) ;
386
+
387
+ auto did;
388
+ alt ( resolve_path( path, data) ) {
389
+ case ( rr_ok( ?di) ) { did = di; }
390
+ case ( rr_not_found( ?prev, ?name) ) {
391
+ sess. span_err( sp,
392
+ #fmt( "unbound name '%s' (no item named '%s' found in '%s')" ,
393
+ _str. connect( path, "." ) , name, _str. connect( prev, "." ) ) ) ;
394
+ fail;
395
+ }
396
+ }
397
+
398
+ // TODO: Look up item type, use that to determine the type of def.
399
+
400
+ fail;
287
401
}
288
402
289
403
fn get_type( session. session sess, ast. def_id def) -> typeck. ty_and_params {
0 commit comments