From c1e287af7788261bd50f47a166fbbd3493355a38 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 12 Nov 2013 01:29:09 -0800 Subject: [PATCH] Make -Z gen-crate-map usable for I/O In #10422, I didn't actually test to make sure that the '-Z gen-crate-map' option was usable before I implemented it. The crate map was indeed generated when '-Z gen-crate-map' was specified, but the I/O factory slot was empty because of an extra check in trans about filling in that location. This commit both fixes that location, and checks in a "fancy test" which does lots of fun stuff. The test will use the rustc library to compile a rust crate, and then compile a C program to link against that crate and run the C program. To my knowledge this is the first test of its kind, so it's a little ad-hoc, but it seems to get the job done. We could perhaps generalize running tests like this, but for now I think it's fine to have this sort of functionality tucked away in a test. --- src/librustc/middle/trans/base.rs | 21 ++++++++-------- .../bootstrap-from-c-with-uvio/Makefile | 9 +++++++ .../bootstrap-from-c-with-uvio/lib.rs | 25 +++++++++++++++++++ .../bootstrap-from-c-with-uvio/main.c | 16 ++++++++++++ 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 src/test/run-make/bootstrap-from-c-with-uvio/Makefile create mode 100644 src/test/run-make/bootstrap-from-c-with-uvio/lib.rs create mode 100644 src/test/run-make/bootstrap-from-c-with-uvio/main.c diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index f14fc265b82b0..deb4f00d7a02f 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -77,7 +77,7 @@ use extra::time; use extra::sort; use syntax::ast::Name; use syntax::ast_map::{path, path_elt_to_str, path_name, path_pretty_name}; -use syntax::ast_util::{local_def}; +use syntax::ast_util::{local_def, is_local}; use syntax::attr; use syntax::codemap::Span; use syntax::parse::token; @@ -2996,7 +2996,7 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, return map; } -pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) { +pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) { let mut subcrates: ~[ValueRef] = ~[]; let mut i = 1; let cstore = ccx.sess.cstore; @@ -3014,19 +3014,20 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) { subcrates.push(p2i(ccx, cr)); i += 1; } - let event_loop_factory = if !*ccx.sess.building_library { - match ccx.tcx.lang_items.event_loop_factory() { - Some(did) => unsafe { + let event_loop_factory = match ccx.tcx.lang_items.event_loop_factory() { + Some(did) => unsafe { + if is_local(did) { + llvm::LLVMConstPointerCast(get_item_val(ccx, did.node), + ccx.int_type.ptr_to().to_ref()) + } else { let name = csearch::get_symbol(ccx.sess.cstore, did); let global = name.with_c_str(|buf| { llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf) }); global - }, - None => C_null(ccx.int_type.ptr_to()) - } - } else { - C_null(ccx.int_type.ptr_to()) + } + }, + None => C_null(ccx.int_type.ptr_to()) }; unsafe { let maptype = Type::array(&ccx.int_type, subcrates.len() as u64); diff --git a/src/test/run-make/bootstrap-from-c-with-uvio/Makefile b/src/test/run-make/bootstrap-from-c-with-uvio/Makefile new file mode 100644 index 0000000000000..7f466573da730 --- /dev/null +++ b/src/test/run-make/bootstrap-from-c-with-uvio/Makefile @@ -0,0 +1,9 @@ +-include ../tools.mk + +all: + $(RUSTC) lib.rs -Z gen-crate-map + ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot) + $(CC) main.c -o $(call RUN,main) -lboot -Wl,-rpath,$(TMPDIR) + $(call RUN,main) + rm $(call DYLIB,boot) + $(call FAIL,main) diff --git a/src/test/run-make/bootstrap-from-c-with-uvio/lib.rs b/src/test/run-make/bootstrap-from-c-with-uvio/lib.rs new file mode 100644 index 0000000000000..85941ec74a8da --- /dev/null +++ b/src/test/run-make/bootstrap-from-c-with-uvio/lib.rs @@ -0,0 +1,25 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[link(package_id = "boot", name = "boot", vers = "0.1")]; +#[crate_type = "lib"]; + +extern mod rustuv; // pull in uvio + +use std::rt; + +#[no_mangle] // this needs to get called from C +pub extern "C" fn foo(argc: int, argv: **u8) -> int { + do rt::start(argc, argv) { + do spawn { + println!("hello"); + } + } +} diff --git a/src/test/run-make/bootstrap-from-c-with-uvio/main.c b/src/test/run-make/bootstrap-from-c-with-uvio/main.c new file mode 100644 index 0000000000000..1872c1ea43b11 --- /dev/null +++ b/src/test/run-make/bootstrap-from-c-with-uvio/main.c @@ -0,0 +1,16 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// this is the rust entry point that we're going to call. +int foo(int argc, char *argv[]); + +int main(int argc, char *argv[]) { + return foo(argc, argv); +}