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 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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user