From 4eb3ce32801ddd9ad335bc82f70f245c5f3c797a Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 7 Sep 2011 14:28:02 -0700 Subject: [PATCH] Add landing pads to invokes Issue #236 --- src/comp/middle/trans.rs | 25 +++++++++++++++++++++---- src/comp/middle/trans_build.rs | 7 +++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 9a8b9bfaba1..df07f104270 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3799,15 +3799,32 @@ fn invoke_fastcall(bcx: &@block_ctxt, llfn: ValueRef, 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); + let retval = 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); + // The landing pad return type (the type being propagated). Not sure what + // this represents but it's determined by the personality function and + // this is what the EH proposal example uses. + let llretty = T_struct([T_ptr(T_i8()), T_i32()]); + // The exception handling personality function. This is the C++ + // personality function __gxx_personality_v0, wrapped in our naming + // convention. + let personality = bcx_ccx(bcx).upcalls.rust_personality; + // The only landing pad clause will be 'cleanup' + let clauses = 1u; + let llpad = LandingPad(bcx, llretty, personality, clauses); + // The landing pad result is used both for modifying the landing pad + // in the C API and as the exception value + let llretval = llpad; + // The landing pad block is a cleanup + SetCleanup(bcx, llpad); + // Continue unwinding + Resume(bcx, llretval); } fn trans_tup(cx: &@block_ctxt, elts: &[@ast::expr], id: ast::node_id) -> diff --git a/src/comp/middle/trans_build.rs b/src/comp/middle/trans_build.rs index c869ebbb24c..6f801551d11 100644 --- a/src/comp/middle/trans_build.rs +++ b/src/comp/middle/trans_build.rs @@ -547,6 +547,7 @@ fn Trap(cx: &@block_ctxt) -> ValueRef { fn LandingPad(cx: &@block_ctxt, Ty: TypeRef, PersFn: ValueRef, NumClauses: uint) -> ValueRef { + assert (!cx.terminated); ret str::as_buf("", {|buf| llvm::LLVMBuildLandingPad(B(cx), @@ -561,6 +562,12 @@ fn SetCleanup(_cx: &@block_ctxt, LandingPad: ValueRef) { llvm::LLVMSetCleanup(LandingPad, lib::llvm::True); } +fn Resume(cx: &@block_ctxt, Exn: ValueRef) -> ValueRef { + assert (!cx.terminated); + cx.terminated = true; + ret llvm::LLVMBuildResume(B(cx), Exn); +} + // // Local Variables: // mode: rust