1
Fork 0

auto merge of #5809 : Aatch/rust/start-attr, r=thestinger

This implements #5158. Currently it takes the command line args and the crate map. Since it doesn't take a `main` function pointer, you can't actually start the runtime easily, but that seems to be a shim to allow the current `rust_start` function to call into main.

However, you can do an end-run round the io library and do this:

```rust
use core::libc::{write, c_int, c_void, size_t, STDOUT_FILENO};

#[start]
fn my_start(_argc:int, _argv: **u8, _crate_map: *u8) -> int {
    do str::as_buf("Hello World!\n") |s,len| {
        unsafe {
            write(STDOUT_FILENO, s as *c_void, len as size_t);
        }
    }
    return 0;
}
```

Which is the most basic "Hello World" you can do in rust without starting up the runtime (though that has quite a lot to do with the fact that `core::io` uses `@` everywhere...)
This commit is contained in:
bors 2013-04-12 02:34:02 -07:00
commit 63e2724cdb
8 changed files with 176 additions and 46 deletions

View file

@ -801,6 +801,8 @@ pub fn Resolver(session: Session,
attr_main_fn: None,
main_fns: ~[],
start_fn: None,
def_map: @mut HashMap::new(),
export_map2: @mut HashMap::new(),
trait_map: HashMap::new(),
@ -860,9 +862,13 @@ pub struct Resolver {
// The function that has attribute named 'main'
attr_main_fn: Option<(node_id, span)>,
// The functions named 'main'
// The functions that could be main functions
main_fns: ~[Option<(node_id, span)>],
// The function that has the attribute 'start' on it
start_fn: Option<(node_id, span)>,
def_map: DefMap,
export_map2: ExportMap2,
trait_map: TraitMap,
@ -3538,6 +3544,7 @@ pub impl Resolver {
item_fn(ref fn_decl, _, _, ref generics, ref block) => {
// If this is the main function, we must record it in the
// session.
// FIXME #4404 android JNI hacks
if !*self.session.building_library ||
self.session.targ_cfg.os == session::os_android {
@ -3557,6 +3564,16 @@ pub impl Resolver {
~"multiple 'main' functions");
}
}
if attrs_contains_name(item.attrs, ~"start") {
if self.start_fn.is_none() {
self.start_fn = Some((item.id, item.span));
} else {
self.session.span_err(
item.span,
~"multiple 'start' functions");
}
}
}
self.resolve_function(OpaqueFunctionRibKind,
@ -5096,7 +5113,7 @@ pub impl Resolver {
//
fn check_duplicate_main(@mut self) {
let this = &mut *self;
if this.attr_main_fn.is_none() {
if this.attr_main_fn.is_none() && this.start_fn.is_none() {
if this.main_fns.len() >= 1u {
let mut i = 1u;
while i < this.main_fns.len() {
@ -5106,10 +5123,15 @@ pub impl Resolver {
~"multiple 'main' functions");
i += 1;
}
*this.session.main_fn = this.main_fns[0];
*this.session.entry_fn = this.main_fns[0];
*this.session.entry_type = Some(session::EntryMain);
}
} else if !this.start_fn.is_none() {
*this.session.entry_fn = this.start_fn;
*this.session.entry_type = Some(session::EntryStart);
} else {
*this.session.main_fn = this.attr_main_fn;
*this.session.entry_fn = this.attr_main_fn;
*this.session.entry_type = Some(session::EntryMain);
}
}