fn trans_gnu_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                             func: ValueRef,
                             data: ValueRef,
                             local_ptr: ValueRef,
                             dest: ValueRef,
                             dloc: DebugLoc) -> Block<'blk, 'tcx> {
    let llfn = get_rust_try_fn(bcx.fcx, &mut |bcx| {
        let ccx = bcx.ccx();
        let dloc = DebugLoc::None;

        // Translates the shims described above:
        //
        //   bcx:
        //      invoke %func(%args...) normal %normal unwind %catch
        //
        //   normal:
        //      ret 0
        //
        //   catch:
        //      (ptr, _) = landingpad
        //      store ptr, %local_ptr
        //      ret 1
        //
        // Note that the `local_ptr` data passed into the `try` intrinsic is
        // expected to be `*mut *mut u8` for this to actually work, but that's
        // managed by the standard library.

        let then = bcx.fcx.new_block("then");
        let catch = bcx.fcx.new_block("catch");

        let func = llvm::get_param(bcx.fcx.llfn, 0);
        let data = llvm::get_param(bcx.fcx.llfn, 1);
        let local_ptr = llvm::get_param(bcx.fcx.llfn, 2);
        Invoke(bcx, func, &[data], then.llbb, catch.llbb, dloc);
        Ret(then, C_i32(ccx, 0), dloc);

        // Type indicator for the exception being thrown.
        //
        // The first value in this tuple is a pointer to the exception object
        // being thrown.  The second value is a "selector" indicating which of
        // the landing pad clauses the exception's type had been matched to.
        // rust_try ignores the selector.
        let lpad_ty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)],
                                    false);
        let vals = LandingPad(catch, lpad_ty, bcx.fcx.eh_personality(), 1);
        AddClause(catch, vals, C_null(Type::i8p(ccx)));
        let ptr = ExtractValue(catch, vals, 0);
        Store(catch, ptr, BitCast(catch, local_ptr, Type::i8p(ccx).ptr_to()));
        Ret(catch, C_i32(ccx, 1), dloc);
    });

    // Note that no invoke is used here because by definition this function
    // can't panic (that's what it's catching).
    let ret = Call(bcx, llfn, &[func, data, local_ptr], dloc);
    Store(bcx, ret, dest);
    return bcx;
}
// Definition of the standard "try" function for Rust using the GNU-like model
// of exceptions (e.g. the normal semantics of LLVM's landingpad and invoke
// instructions).
//
// This translation is a little surprising because we always call a shim
// function instead of inlining the call to `invoke` manually here. This is done
// because in LLVM we're only allowed to have one personality per function
// definition. The call to the `try` intrinsic is being inlined into the
// function calling it, and that function may already have other personality
// functions in play. By calling a shim we're guaranteed that our shim will have
// the right personality function.
Definition of the standard "try" function for Rust using the GNU-like model
of exceptions .

This translation is a little surprising because we always call a shim
function instead of inlining the call to `invoke` manually here. This is done
because in LLVM we're only allowed to have one personality per function
definition. The call to the `try` intrinsic is being inlined into the
function calling it, and that function may already have other personality
functions in play. By calling a shim we're guaranteed that our shim will have
the right personality function.
Definition of the standard " try " function for Rust using the GNU - like model of exceptions . This translation is a little surprising because we always call a shim function instead of inlining the call to ` invoke ` manually here . This is done because in LLVM we ' re only allowed to have one personality per function definition . The call to the ` try ` intrinsic is being inlined into the function calling it and that function may already have other personality functions in play . By calling a shim we ' re guaranteed that our shim will have the right personality function .
fn trans_gnu_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                             func: ValueRef,
                             data: ValueRef,
                             local_ptr: ValueRef,
                             dest: ValueRef,
                             dloc: DebugLoc) -> Block<'blk, 'tcx> {
    let llfn = get_rust_try_fn(bcx.fcx, &mut |bcx| {
        let ccx = bcx.ccx();
        let dloc = DebugLoc::None;
        // Translates the shims described above:
        //
        //   bcx:
        //      invoke %func(%args...) normal %normal unwind %catch
        //
        //   normal:
        //      ret 0
        //
        //   catch:
        //      (ptr, _) = landingpad
        //      store ptr, %local_ptr
        //      ret 1
        //
        // Note that the `local_ptr` data passed into the `try` intrinsic is
        // expected to be `*mut *mut u8` for this to actually work, but that's
        // managed by the standard library.
        let then = bcx.fcx.new_block("then");
        let catch = bcx.fcx.new_block("catch");
        let func = llvm::get_param(bcx.fcx.llfn, 0);
        let data = llvm::get_param(bcx.fcx.llfn, 1);
        let local_ptr = llvm::get_param(bcx.fcx.llfn, 2);
        Invoke(bcx, func, &[data], then.llbb, catch.llbb, dloc);
        Ret(then, C_i32(ccx, 0), dloc);
        // Type indicator for the exception being thrown.
        //
        // The first value in this tuple is a pointer to the exception object
        // being thrown.  The second value is a "selector" indicating which of
        // the landing pad clauses the exception's type had been matched to.
        // rust_try ignores the selector.
        let lpad_ty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)],
                                    false);
        let vals = LandingPad(catch, lpad_ty, bcx.fcx.eh_personality(), 1);
        AddClause(catch, vals, C_null(Type::i8p(ccx)));
        let ptr = ExtractValue(catch, vals, 0);
        Store(catch, ptr, BitCast(catch, local_ptr, Type::i8p(ccx).ptr_to()));
        Ret(catch, C_i32(ccx, 1), dloc);
    });
    // Note that no invoke is used here because by definition this function
    // can't panic (that's what it's catching).
    let ret = Call(bcx, llfn, &[func, data, local_ptr], dloc);
    Store(bcx, ret, dest);
    return bcx;
}
fn trans_gnu_try < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > , func : ValueRef , data : ValueRef , local_ptr : ValueRef , dest : ValueRef , dloc : DebugLoc ) -> Block < ' blk , ' tcx > { let llfn = get_rust_try_fn ( bcx . fcx , & mut | bcx | { let ccx = bcx . ccx ( ) ; let dloc = DebugLoc :: None ; // Translates the shims described above: // //   bcx: //      invoke %func(%args...) normal %normal unwind %catch // //   normal: //      ret 0 // //   catch: //      (ptr, _) = landingpad //      store ptr, %local_ptr //      ret 1 // // Note that the `local_ptr` data passed into the `try` intrinsic is // expected to be `*mut *mut u8` for this to actually work, but that's // managed by the standard library. let then = bcx . fcx . new_block ( " " ) ; let catch = bcx . fcx . new_block ( " " ) ; let func = llvm :: get_param ( bcx . fcx . llfn , 0 ) ; let data = llvm :: get_param ( bcx . fcx . llfn , 1 ) ; let local_ptr = llvm :: get_param ( bcx . fcx . llfn , 2 ) ; Invoke ( bcx , func , & [ data ] , then . llbb , catch . llbb , dloc ) ; Ret ( then , C_i32 ( ccx , 0 ) , dloc ) ; // Type indicator for the exception being thrown. // // The first value in this tuple is a pointer to the exception object // being thrown.  The second value is a "selector" indicating which of // the landing pad clauses the exception's type had been matched to. // rust_try ignores the selector. let lpad_ty = Type :: struct_ ( ccx , & [ Type :: i8p ( ccx ) , Type :: i32 ( ccx ) ] , false ) ; let vals = LandingPad ( catch , lpad_ty , bcx . fcx . eh_personality ( ) , 1 ) ; AddClause ( catch , vals , C_null ( Type :: i8p ( ccx ) ) ) ; let ptr = ExtractValue ( catch , vals , 0 ) ; Store ( catch , ptr , BitCast ( catch , local_ptr , Type :: i8p ( ccx ) . ptr_to ( ) ) ) ; Ret ( catch , C_i32 ( ccx , 1 ) , dloc ) ; } ) ; // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = Call ( bcx , llfn , & [ func , data , local_ptr ] , dloc ) ; Store ( bcx , ret , dest ) ; return bcx ; }
Definition of the standard "try" function for Rust using the GNU-like model
of exceptions (e.g.
Definition of the standard " try " function for Rust using the GNU - like model of exceptions ( e . g .
bcx
Block<'blk, 'tcx>
func
ValueRef
data
ValueRef
local_ptr
ValueRef
dest
ValueRef
dloc
DebugLoc
bcx
Block<'blk, 'tcx>
func
ValueRef
data
ValueRef
local_ptr
ValueRef
dest
ValueRef
dloc
DebugLoc