diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2012-03-22 13:44:16 +0100 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2012-03-23 10:49:47 +0100 |
| commit | 0545e4a9200a9c971f8b5f95aa9a439ea0c20116 (patch) | |
| tree | be7a9b9f697ffe007460898137d8aafd204c6e63 /src/rustc | |
| parent | 894b7469d6902bba571024cc0f39c1521156d7a3 (diff) | |
| download | rust-0545e4a9200a9c971f8b5f95aa9a439ea0c20116.tar.gz rust-0545e4a9200a9c971f8b5f95aa9a439ea0c20116.zip | |
Support [rust_stack] annotation on native functions (crudely)
Diffstat (limited to 'src/rustc')
| -rw-r--r-- | src/rustc/middle/trans/base.rs | 4 | ||||
| -rw-r--r-- | src/rustc/middle/trans/native.rs | 60 |
2 files changed, 47 insertions, 17 deletions
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 4d82987ce02..0252802d6a7 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -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); diff --git a/src/rustc/middle/trans/native.rs b/src/rustc/middle/trans/native.rs index 049e31325d7..be10c8d0e78 100644 --- a/src/rustc/middle/trans/native.rs +++ b/src/rustc/middle/trans/native.rs @@ -652,24 +652,50 @@ fn trans_native_mod(ccx: @crate_ctxt, } let lname = link_name(native_item); - // Declare the "prototype" for the base function F: - 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) - } - }; + 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: + 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, tys: @c_stack_tys, llshimfn: ValueRef, @@ -717,10 +743,14 @@ 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 llshimfn = build_shim_fn(ccx, native_item, tys, cc); - build_wrap_fn(ccx, tys, llshimfn, llwrapfn); + 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); + } } } } |
