Support [rust_stack] annotation on native functions (crudely)
This commit is contained in:
@@ -141,7 +141,6 @@ fn recv_<T: send>(p: *rust_port) -> T {
|
||||
let yieldp = ptr::addr_of(yield);
|
||||
let mut res;
|
||||
res = rusti::init::<T>();
|
||||
log(debug, ptr::addr_of(res));
|
||||
rustrt::port_recv(ptr::addr_of(res) as *uint, p, yieldp);
|
||||
|
||||
if yield != 0u {
|
||||
|
||||
@@ -13,7 +13,9 @@ import libc::c_void;
|
||||
#[nolink]
|
||||
#[abi = "cdecl"]
|
||||
native mod libc_ {
|
||||
#[rust_stack]
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -442,7 +442,7 @@ fn yield() {
|
||||
|
||||
let task_ = rustrt::rust_get_task();
|
||||
let mut killed = false;
|
||||
rusti::task_yield(task_, killed);
|
||||
rustrt::rust_task_yield(task_, killed);
|
||||
if killed && !failing() {
|
||||
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 {
|
||||
#[rust_stack]
|
||||
fn rust_task_yield(task: *rust_task, &killed: bool);
|
||||
|
||||
fn rust_get_sched_id() -> sched_id;
|
||||
fn rust_new_sched(num_threads: libc::uintptr_t) -> sched_id;
|
||||
|
||||
|
||||
@@ -34,11 +34,4 @@ mod tests {
|
||||
fn test_reinterpret_cast() unsafe {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2625,7 +2625,7 @@ enum call_args {
|
||||
// - new_fn_ctxt
|
||||
// - trans_args
|
||||
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} {
|
||||
let _icx = cx.insn_ctxt("trans_args");
|
||||
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.
|
||||
let llretslot = alt dest {
|
||||
ignore {
|
||||
if ty::type_is_nil(retty) && !generic_intrinsic {
|
||||
if ty::type_is_nil(retty) && !always_valid_retptr {
|
||||
llvm::LLVMGetUndef(T_ptr(T_nil()))
|
||||
} else {
|
||||
let {bcx: cx, val} = alloc_ty(bcx, retty);
|
||||
|
||||
@@ -652,8 +652,17 @@ fn trans_native_mod(ccx: @crate_ctxt,
|
||||
}
|
||||
|
||||
let lname = link_name(native_item);
|
||||
let llbasefn = base_fn(ccx, lname, tys, cc);
|
||||
// Name the shim function
|
||||
let shim_name = lname + "__c_stack_shim";
|
||||
ret build_shim_fn_(ccx, shim_name, llbasefn, tys, cc,
|
||||
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:
|
||||
let llbasefn = alt tys.x86_64_tys {
|
||||
alt tys.x86_64_tys {
|
||||
some(x86_64) {
|
||||
decl_x86_64_fn(x86_64) {|fnty|
|
||||
decl_fn(ccx.llmod, lname, cc, fnty)
|
||||
@@ -663,11 +672,28 @@ fn trans_native_mod(ccx: @crate_ctxt,
|
||||
let llbasefnty = T_fn(tys.arg_tys, tys.ret_ty);
|
||||
decl_fn(ccx.llmod, lname, cc, llbasefnty)
|
||||
}
|
||||
};
|
||||
// Name the shim function
|
||||
let shim_name = lname + "__c_stack_shim";
|
||||
ret build_shim_fn_(ccx, shim_name, llbasefn, tys, cc,
|
||||
build_args, build_ret);
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
@@ -717,13 +743,17 @@ fn trans_native_mod(ccx: @crate_ctxt,
|
||||
alt native_item.node {
|
||||
ast::native_item_fn(fn_decl, _) {
|
||||
let id = native_item.id;
|
||||
let tys = c_stack_tys(ccx, id);
|
||||
let llwrapfn = get_item_val(ccx, id);
|
||||
let tys = c_stack_tys(ccx, id);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn trans_builtin(ccx: @crate_ctxt, decl: ValueRef, item: @ast::native_item,
|
||||
|
||||
Reference in New Issue
Block a user