Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the #[boot] attribute #11153

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/libgreen/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,18 @@ pub mod sleeper_list;
pub mod stack;
pub mod task;

#[boot]
#[cfg(not(stage0))]
pub fn boot(main: fn()) {
simple::task().run(|| {
do run {
main();
};
});
}

#[lang = "start"]
#[cfg(not(test))]
#[cfg(not(test), stage0)]
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
use std::cast;
do start(argc, argv) {
Expand Down
16 changes: 6 additions & 10 deletions src/libnative/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,23 @@ mod bookeeping;
pub mod io;
pub mod task;

// XXX: this should not exist here
#[cfg(stage0, nativestart)]
#[lang = "start"]
pub fn lang_start(main: *u8, argc: int, argv: **u8) -> int {
use std::cast;
use std::task;

do start(argc, argv) {
#[cfg(not(stage0))]
#[boot]
pub fn boot(main: fn()) {
task::new().run(||{
use std::task;
// Instead of invoking main directly on this thread, invoke it on
// another spawned thread that we are guaranteed to know the size of the
// stack of. Currently, we do not have a method of figuring out the size
// of the main thread's stack, so for stack overflow detection to work
// we must spawn the task in a subtask which we know the stack size of.
let main: extern "Rust" fn() = unsafe { cast::transmute(main) };
let mut task = task::task();
task.name("<main>");
match do task.try { main() } {
Ok(()) => { os::set_exit_status(0); }
Err(..) => { os::set_exit_status(rt::DEFAULT_ERROR_CODE); }
}
}
});
}

/// Executes the given procedure after initializing the runtime with the given
Expand Down
8 changes: 4 additions & 4 deletions src/libnative/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {

// This structure is the glue between channels and the 1:1 scheduling mode. This
// structure is allocated once per task.
struct Ops {
lock: Mutex, // native synchronization
awoken: bool, // used to prevent spurious wakeups
io: io::IoFactory, // local I/O factory
pub struct Ops {
priv lock: Mutex, // native synchronization
priv awoken: bool, // used to prevent spurious wakeups
priv io: io::IoFactory, // local I/O factory

// This field holds the known bounds of the stack in (lo, hi) form. Not all
// native tasks necessarily know their precise bounds, hence this is
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
time(time_passes, "looking for entry point", (),
|_| middle::entry::find_entry_point(sess, crate, ast_map));

time(time_passes, "looking for boot function", (),
|_| middle::entry::find_boot_fn(sess, crate));

let freevars = time(time_passes, "freevar finding", (), |_|
freevars::annotate_freevars(def_map, crate));

Expand Down Expand Up @@ -912,6 +915,7 @@ pub fn build_session_(sopts: @session::options,
// For a library crate, this is always none
entry_fn: RefCell::new(None),
entry_type: Cell::new(None),
boot_fn: Cell::new(None),
span_diagnostic: span_diagnostic_handler,
filesearch: filesearch,
building_library: Cell::new(false),
Expand Down
14 changes: 7 additions & 7 deletions src/librustc/driver/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@ use metadata::filesearch;
use metadata;
use middle::lint;

use syntax;
use syntax::abi;
use syntax::ast;
use syntax::attr::AttrMetaMethods;
use syntax::ast::NodeId;
use syntax::ast::{IntTy, UintTy};
use syntax::codemap::Span;
use syntax::codemap;
use syntax::diagnostic;
use syntax::parse::ParseSess;
use syntax::{ast, codemap};
use syntax::abi;
use syntax::parse::token;
use syntax;

use std::cell::{Cell, RefCell};
use std::hashmap::{HashMap,HashSet};
Expand All @@ -35,8 +34,8 @@ pub struct config {
os: abi::Os,
arch: abi::Architecture,
target_strs: target_strs::t,
int_type: IntTy,
uint_type: UintTy,
int_type: ast::IntTy,
uint_type: ast::UintTy,
}

pub static verbose: uint = 1 << 0;
Expand Down Expand Up @@ -210,6 +209,7 @@ pub struct Session_ {
entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
entry_type: Cell<Option<EntryFnType>>,
span_diagnostic: @diagnostic::SpanHandler,
boot_fn: Cell<Option<ast::DefId>>,
filesearch: @filesearch::FileSearch,
building_library: Cell<bool>,
working_dir: Path,
Expand Down
31 changes: 19 additions & 12 deletions src/librustc/front/std_inject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ fn use_uv(crate: &ast::Crate) -> bool {
!attr::contains_name(crate.attrs, "no_uv")
}

fn use_stdboot(crate: &ast::Crate) -> bool {
!attr::contains_name(crate.attrs, "no_boot")
}

fn no_prelude(attrs: &[ast::Attribute]) -> bool {
attr::contains_name(attrs, "no_implicit_prelude")
}
Expand Down Expand Up @@ -67,25 +71,28 @@ impl fold::Folder for StandardLibraryInjector {
span: DUMMY_SP
}];

if use_uv(&crate) && !self.sess.building_library.get() {
vis.push(ast::ViewItem {
if use_stdboot(&crate) && !self.sess.building_library.get() {
let boot = attr::mk_word_item(@"boot");
vis.push(ast::view_item {
node: ast::ViewItemExternMod(self.sess.ident_of("green"),
Some((format!("green\\#{}", VERSION).to_managed(),
ast::CookedStr)),
ast::DUMMY_NODE_ID),
attrs: ~[],
vis: ast::Private,
span: DUMMY_SP
});
vis.push(ast::ViewItem {
node: ast::ViewItemExternMod(self.sess.ident_of("rustuv"),
Some((format!("rustuv\\#{}", VERSION).to_managed(),
ast::CookedStr)),
ast::DUMMY_NODE_ID),
attrs: ~[],
attrs: ~[attr::mk_attr(boot)],
vis: ast::Private,
span: DUMMY_SP
});
if use_uv(&crate) {
vis.push(ast::view_item {
node: ast::view_item_extern_mod(self.sess.ident_of("rustuv"),
Some((format!("rustuv\\#{}", VERSION).to_managed(),
ast::CookedStr)),
ast::DUMMY_NODE_ID),
attrs: ~[],
vis: ast::Private,
span: DUMMY_SP
});
}
}

vis.push_all(crate.module.view_items);
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ pub static tag_native_libraries_lib: uint = 0x104;
pub static tag_native_libraries_name: uint = 0x105;
pub static tag_native_libraries_kind: uint = 0x106;

pub static tag_boot_fn: uint = 0x107;

#[deriving(Clone)]
pub struct LinkMeta {
crateid: CrateId,
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,8 @@ pub fn get_trait_of_method(cstore: @cstore::CStore,
decoder::get_trait_of_method(cdata, def_id.node, tcx)
}

pub fn get_boot_fn(cstore: @mut cstore::CStore,
crate: ast::CrateNum) -> Option<ast::DefId> {
let cdata = cstore.get_crate_data(crate);
decoder::get_boot_fn(cdata)
}
6 changes: 6 additions & 0 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1275,3 +1275,9 @@ pub fn get_native_libraries(cdata: Cmd) -> ~[(cstore::NativeLibaryKind, ~str)] {
});
return result;
}

pub fn get_boot_fn(cdata: Cmd) -> Option<ast::DefId> {
reader::maybe_get_doc(reader::Doc(cdata.data()), tag_boot_fn).map(|doc| {
item_def_id(doc, cdata)
})
}
19 changes: 19 additions & 0 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct Stats {
dep_bytes: Cell<u64>,
lang_item_bytes: Cell<u64>,
native_lib_bytes: Cell<u64>,
boot_fn_bytes: Cell<u64>,
impl_bytes: Cell<u64>,
misc_bytes: Cell<u64>,
item_bytes: Cell<u64>,
Expand Down Expand Up @@ -1692,6 +1693,17 @@ fn encode_native_libraries(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) {
ebml_w.end_tag();
}

fn encode_boot_fn(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) {
match *ecx.tcx.sess.boot_fn {
Some(did) => {
ebml_w.start_tag(tag_boot_fn);
encode_def_id(ebml_w, did);
ebml_w.end_tag();
}
None => {}
};
}

struct ImplVisitor<'a,'b> {
ecx: &'a EncodeContext<'a>,
ebml_w: &'a mut writer::Encoder<'b>,
Expand Down Expand Up @@ -1816,6 +1828,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, crate: &Crate)
dep_bytes: Cell::new(0),
lang_item_bytes: Cell::new(0),
native_lib_bytes: Cell::new(0),
boot_fn_bytes: Cell::new(0),
impl_bytes: Cell::new(0),
misc_bytes: Cell::new(0),
item_bytes: Cell::new(0),
Expand Down Expand Up @@ -1874,6 +1887,11 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, crate: &Crate)
encode_native_libraries(&ecx, &mut ebml_w);
ecx.stats.native_lib_bytes.set(ebml_w.writer.tell() - i);

// Encode the native libraries used
i = wr.tell();
encode_boot_fn(&ecx, &mut ebml_w);
ecx.stats.boot_fn_bytes = wr.tell() - i;

// Encode the def IDs of impls, for coherence checking.
i = ebml_w.writer.tell();
encode_impls(&ecx, crate, &mut ebml_w);
Expand Down Expand Up @@ -1911,6 +1929,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, crate: &Crate)
println!(" dep bytes: {}", ecx.stats.dep_bytes.get());
println!(" lang item bytes: {}", ecx.stats.lang_item_bytes.get());
println!(" native bytes: {}", ecx.stats.native_lib_bytes.get());
println!(" boot fn bytes: {}", ecx.stats.boot_fn_bytes.get());
println!(" impl bytes: {}", ecx.stats.impl_bytes.get());
println!(" misc bytes: {}", ecx.stats.misc_bytes.get());
println!(" item bytes: {}", ecx.stats.item_bytes.get());
Expand Down
Loading