diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 893614cac9a..9a8b9bfaba1 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3761,7 +3761,7 @@ fn trans_call(in_cx: &@block_ctxt, f: &@ast::expr, for the call itself is unreachable. */ let retval = C_nil(); if !is_terminated(bcx) { - FastCall(bcx, faddr, llargs); + bcx = invoke_fastcall(bcx, faddr, llargs).bcx; alt lliterbody { none. { if !ty::type_is_nil(bcx_tcx(cx), ret_ty) { @@ -3794,6 +3794,22 @@ fn trans_call(in_cx: &@block_ctxt, f: &@ast::expr, ret rslt(bcx, retval); } +fn invoke_fastcall(bcx: &@block_ctxt, llfn: ValueRef, + llargs: &[ValueRef]) -> result { + + let normal_bcx = new_sub_block_ctxt(bcx, "normal return"); + let unwind_bcx = new_sub_block_ctxt(bcx, "unwind"); + let retval = trans_build::FastInvoke(bcx, llfn, llargs, + normal_bcx.llbb, + unwind_bcx.llbb); + trans_landing_pad(unwind_bcx); + ret rslt(normal_bcx, retval); +} + +fn trans_landing_pad(bcx: &@block_ctxt) { + Unreachable(bcx); +} + fn trans_tup(cx: &@block_ctxt, elts: &[@ast::expr], id: ast::node_id) -> result { let bcx = cx; diff --git a/src/comp/middle/trans_build.rs b/src/comp/middle/trans_build.rs index 52b976e2844..e7deb97a982 100644 --- a/src/comp/middle/trans_build.rs +++ b/src/comp/middle/trans_build.rs @@ -68,6 +68,21 @@ fn Invoke(cx: &@block_ctxt, Fn: ValueRef, Args: &[ValueRef], }); } +fn FastInvoke(cx: &@block_ctxt, Fn: ValueRef, Args: &[ValueRef], + Then: BasicBlockRef, Catch: BasicBlockRef) -> ValueRef { + assert (!cx.terminated); + cx.terminated = true; + let v = str::as_buf("", + {|buf| + llvm::LLVMBuildInvoke(B(cx), Fn, + vec::to_ptr(Args), + vec::len(Args), Then, + Catch, buf) + }); + llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv); + ret v; +} + fn Unreachable(cx: &@block_ctxt) -> ValueRef { assert (!cx.terminated); cx.terminated = true;