Support [rust_stack] annotation on native functions (crudely)

This commit is contained in:
Marijn Haverbeke
2012-03-22 13:44:16 +01:00
parent 894b7469d6
commit 0545e4a920
6 changed files with 53 additions and 31 deletions

View File

@@ -141,7 +141,6 @@ fn recv_<T: send>(p: *rust_port) -> T {
let yieldp = ptr::addr_of(yield); let yieldp = ptr::addr_of(yield);
let mut res; let mut res;
res = rusti::init::<T>(); res = rusti::init::<T>();
log(debug, ptr::addr_of(res));
rustrt::port_recv(ptr::addr_of(res) as *uint, p, yieldp); rustrt::port_recv(ptr::addr_of(res) as *uint, p, yieldp);
if yield != 0u { if yield != 0u {

View File

@@ -13,7 +13,9 @@ import libc::c_void;
#[nolink] #[nolink]
#[abi = "cdecl"] #[abi = "cdecl"]
native mod libc_ { native mod libc_ {
#[rust_stack]
fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void; fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
#[rust_stack]
fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void; fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
} }

View File

@@ -442,7 +442,7 @@ fn yield() {
let task_ = rustrt::rust_get_task(); let task_ = rustrt::rust_get_task();
let mut killed = false; let mut killed = false;
rusti::task_yield(task_, killed); rustrt::rust_task_yield(task_, killed);
if killed && !failing() { if killed && !failing() {
fail "killed"; fail "killed";
} }
@@ -533,12 +533,10 @@ fn spawn_raw(opts: task_opts, +f: fn~()) unsafe {
} }
#[abi = "rust-intrinsic"]
native mod rusti {
fn task_yield(task: *rust_task, &killed: bool);
}
native mod rustrt { native mod rustrt {
#[rust_stack]
fn rust_task_yield(task: *rust_task, &killed: bool);
fn rust_get_sched_id() -> sched_id; fn rust_get_sched_id() -> sched_id;
fn rust_new_sched(num_threads: libc::uintptr_t) -> sched_id; fn rust_new_sched(num_threads: libc::uintptr_t) -> sched_id;

View File

@@ -34,11 +34,4 @@ mod tests {
fn test_reinterpret_cast() unsafe { fn test_reinterpret_cast() unsafe {
assert reinterpret_cast(1) == 1u; assert reinterpret_cast(1) == 1u;
} }
#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_reinterpret_cast_wrong_size() unsafe {
let _i: uint = reinterpret_cast(0u8);
}
} }

View File

@@ -2625,7 +2625,7 @@ enum call_args {
// - new_fn_ctxt // - new_fn_ctxt
// - trans_args // - trans_args
fn trans_args(cx: block, llenv: ValueRef, args: call_args, fn_ty: ty::t, fn trans_args(cx: block, llenv: ValueRef, args: call_args, fn_ty: ty::t,
dest: dest, generic_intrinsic: bool) dest: dest, always_valid_retptr: bool)
-> {bcx: block, args: [ValueRef], retslot: ValueRef} { -> {bcx: block, args: [ValueRef], retslot: ValueRef} {
let _icx = cx.insn_ctxt("trans_args"); let _icx = cx.insn_ctxt("trans_args");
let mut temp_cleanups = []; let mut temp_cleanups = [];
@@ -2639,7 +2639,7 @@ fn trans_args(cx: block, llenv: ValueRef, args: call_args, fn_ty: ty::t,
// Arg 0: Output pointer. // Arg 0: Output pointer.
let llretslot = alt dest { let llretslot = alt dest {
ignore { ignore {
if ty::type_is_nil(retty) && !generic_intrinsic { if ty::type_is_nil(retty) && !always_valid_retptr {
llvm::LLVMGetUndef(T_ptr(T_nil())) llvm::LLVMGetUndef(T_ptr(T_nil()))
} else { } else {
let {bcx: cx, val} = alloc_ty(bcx, retty); let {bcx: cx, val} = alloc_ty(bcx, retty);

View File

@@ -652,24 +652,50 @@ fn trans_native_mod(ccx: @crate_ctxt,
} }
let lname = link_name(native_item); let lname = link_name(native_item);
// Declare the "prototype" for the base function F: let llbasefn = base_fn(ccx, lname, tys, cc);
let llbasefn = alt tys.x86_64_tys {
some(x86_64) {
decl_x86_64_fn(x86_64) {|fnty|
decl_fn(ccx.llmod, lname, cc, fnty)
}
}
_ {
let llbasefnty = T_fn(tys.arg_tys, tys.ret_ty);
decl_fn(ccx.llmod, lname, cc, llbasefnty)
}
};
// Name the shim function // Name the shim function
let shim_name = lname + "__c_stack_shim"; let shim_name = lname + "__c_stack_shim";
ret build_shim_fn_(ccx, shim_name, llbasefn, tys, cc, ret build_shim_fn_(ccx, shim_name, llbasefn, tys, cc,
build_args, build_ret); build_args, build_ret);
} }
fn base_fn(ccx: @crate_ctxt, lname: str, tys: @c_stack_tys,
cc: lib::llvm::CallConv) -> ValueRef {
// Declare the "prototype" for the base function F:
alt tys.x86_64_tys {
some(x86_64) {
decl_x86_64_fn(x86_64) {|fnty|
decl_fn(ccx.llmod, lname, cc, fnty)
}
}
_ {
let llbasefnty = T_fn(tys.arg_tys, tys.ret_ty);
decl_fn(ccx.llmod, lname, cc, llbasefnty)
}
}
}
// FIXME this is very shaky and probably gets ABIs wrong all over
// the place
fn build_direct_fn(ccx: @crate_ctxt, decl: ValueRef,
item: @ast::native_item, tys: @c_stack_tys,
cc: lib::llvm::CallConv) {
let fcx = new_fn_ctxt(ccx, [], decl, none);
let bcx = top_scope_block(fcx, none), lltop = bcx.llbb;
let llbasefn = base_fn(ccx, link_name(item), tys, cc);
let ty = ty::lookup_item_type(ccx.tcx,
ast_util::local_def(item.id)).ty;
let args = vec::from_fn(ty::ty_fn_args(ty).len(), {|i|
get_param(decl, i + first_real_arg)
});
let retval = Call(bcx, llbasefn, args);
if !ty::type_is_nil(ty::ty_fn_ret(ty)) {
Store(bcx, retval, fcx.llretptr);
}
build_return(bcx);
finish_fn(fcx, lltop);
}
fn build_wrap_fn(ccx: @crate_ctxt, fn build_wrap_fn(ccx: @crate_ctxt,
tys: @c_stack_tys, tys: @c_stack_tys,
llshimfn: ValueRef, llshimfn: ValueRef,
@@ -717,10 +743,14 @@ fn trans_native_mod(ccx: @crate_ctxt,
alt native_item.node { alt native_item.node {
ast::native_item_fn(fn_decl, _) { ast::native_item_fn(fn_decl, _) {
let id = native_item.id; let id = native_item.id;
let tys = c_stack_tys(ccx, id);
let llwrapfn = get_item_val(ccx, id); let llwrapfn = get_item_val(ccx, id);
let llshimfn = build_shim_fn(ccx, native_item, tys, cc); let tys = c_stack_tys(ccx, id);
build_wrap_fn(ccx, tys, llshimfn, llwrapfn); if attr::attrs_contains_name(native_item.attrs, "rust_stack") {
build_direct_fn(ccx, llwrapfn, native_item, tys, cc);
} else {
let llshimfn = build_shim_fn(ccx, native_item, tys, cc);
build_wrap_fn(ccx, tys, llshimfn, llwrapfn);
}
} }
} }
} }