diff --git a/Makefile.in b/Makefile.in index 4c5c8981259..8e4f2ca45ff 100644 --- a/Makefile.in +++ b/Makefile.in @@ -696,6 +696,7 @@ TEST_XFAILS_STAGE0 := $(FLOAT_XFAILS) \ threads.rs \ type-sizes.rs \ typestate-cfg-nesting.rs \ + use-import-export.rs \ user.rs \ utf8.rs \ vec-alloc-append.rs \ diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index d48792d117e..349f887a2f9 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -374,8 +374,7 @@ tag native_item_ { fn_decl, vec[ty_param], def_id, ann); } -// TODO: Actually store something here. -type external_crate_info = (); +type external_crate_info = rec(vec[u8] data); fn index_view_item(mod_index index, @view_item it) { alt (it.node) { diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs index 7212840c9bd..e052e94a838 100644 --- a/src/comp/front/creader.rs +++ b/src/comp/front/creader.rs @@ -2,11 +2,14 @@ import driver.session; import front.ast; +import lib.llvm.False; +import lib.llvm.llvm; import lib.llvm.llvmext; import lib.llvm.mk_object_file; import lib.llvm.mk_section_iter; import middle.fold; import middle.ty; +import back.x86; import util.common; import util.common.span; @@ -19,6 +22,7 @@ import std.map.hashmap; // TODO: map to a real type here. type env = @rec( + session.session sess, @hashmap[str, @ast.external_crate_info] crate_cache, vec[str] library_search_paths ); @@ -204,15 +208,39 @@ impure fn parse_ty_fn(@pstate st, str_def sd) -> tup(vec[ty.arg], @ty.t) { } +// Rust metadata parsing -// TODO: return something -fn load_crate(ast.ident ident, vec[str] library_search_paths) -> @() { +// TODO + + +fn load_crate(session.session sess, + ast.ident ident, + vec[str] library_search_paths) -> @ast.external_crate_info { + auto filename = parser.default_native_name(sess, ident); for (str library_search_path in library_search_paths) { - auto path = fs.connect(library_search_path, ident); - // TODO + auto path = fs.connect(library_search_path, filename); + auto pbuf = _str.buf(path); + auto mb = llvmext.LLVMRustCreateMemoryBufferWithContentsOfFile(pbuf); + if (mb as int != 0) { + auto of = mk_object_file(mb); + auto si = mk_section_iter(of.llof); + while (llvmext.LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == + False) { + auto name_buf = llvmext.LLVMGetSectionName(si.llsi); + auto name = _str.str_from_cstr(name_buf); + if (_str.eq(name, x86.get_meta_sect_name())) { + auto cbuf = llvmext.LLVMGetSectionContents(si.llsi); + auto csz = llvmext.LLVMGetSectionSize(si.llsi); + auto cvbuf = cbuf as _vec.vbuf; + ret @rec(data=_vec.vec_from_vbuf[u8](cvbuf, csz)); + } + } + } } - ret @(); + log #fmt("can't open crate '%s' (looked for '%s' in lib search paths)", + ident, filename); + fail; } fn fold_view_item_use(&env e, &span sp, ast.ident ident, @@ -220,7 +248,7 @@ fn fold_view_item_use(&env e, &span sp, ast.ident ident, -> @ast.view_item { auto external_crate; if (!e.crate_cache.contains_key(ident)) { - external_crate = load_crate(ident, e.library_search_paths); + external_crate = load_crate(e.sess, ident, e.library_search_paths); e.crate_cache.insert(ident, external_crate); } else { external_crate = e.crate_cache.get(ident); @@ -236,6 +264,7 @@ fn read_crates(session.session sess, @ast.crate crate, vec[str] library_search_paths) -> @ast.crate { auto e = @rec( + sess=sess, crate_cache=@common.new_str_hash[@ast.external_crate_info](), library_search_paths=library_search_paths ); diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index a0c8aecbfca..db1f1b24b65 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -42,6 +42,7 @@ mod util { } auth driver.rustc.main = impure; +auth front.creader.load_crate = unsafe; auth middle.metadata = unsafe; auth middle.trans = unsafe; auth middle.trans.copy_args_to_allocas = impure; diff --git a/src/lib/_vec.rs b/src/lib/_vec.rs index 36b529cc070..c3fc7035a84 100644 --- a/src/lib/_vec.rs +++ b/src/lib/_vec.rs @@ -1,7 +1,7 @@ import option.none; import option.some; -import vbuf = rustrt.vbuf; +type vbuf = rustrt.vbuf; type operator2[T,U,V] = fn(&T, &U) -> V; @@ -28,6 +28,8 @@ native "rust" mod rustrt { fn refcount[T](vec[T] v) -> uint; fn vec_print_debug_info[T](vec[T] v); + + fn vec_from_vbuf[T](vbuf v, uint n_elts) -> vec[T]; } fn alloc[T](uint n_elts) -> vec[T] { @@ -48,6 +50,10 @@ fn refcount[T](vec[mutable? T] v) -> uint { } } +unsafe fn vec_from_vbuf[T](vbuf v, uint n_elts) -> vec[T] { + ret rustrt.vec_from_vbuf[T](v, n_elts); +} + type init_op[T] = fn(uint i) -> T; fn init_fn[T](&init_op[T] op, uint n_elts) -> vec[T] { diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 1d8f8ba82aa..983337745b9 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -170,6 +170,13 @@ vec_alloc_with_data(rust_task *task, return new (mem) rust_vec(dom, alloc, fill * elt_size, (uint8_t*)d); } +extern "C" CDECL rust_vec* +vec_from_vbuf(rust_task *task, type_desc *ty, void *vbuf, size_t n_elts) +{ + return vec_alloc_with_data(task, n_elts, n_elts * ty->size, ty->size, + vbuf); +} + extern "C" CDECL rust_str* str_alloc(rust_task *task, size_t n_bytes) { diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 1f081605d24..d917aa937a1 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -62,6 +62,7 @@ upcall_yield vec_alloc vec_alloc_mut vec_buf +vec_from_vbuf vec_len vec_len_set vec_print_debug_info