let mut pad_bcx = fcx.build_new_block("unwind_custom_");
- let llpersonality = pad_bcx.fcx().eh_personality();
+ let llpersonality = pad_bcx.ccx.eh_personality();
let resume_bcx = fcx.build_new_block("resume");
let val = if base::wants_msvc_seh(fcx.ccx.sess()) {
BlockAndBuilder::new(self.new_block(name), self)
}
- pub fn eh_personality(&self) -> ValueRef {
- // The exception handling personality function.
- //
- // If our compilation unit has the `eh_personality` lang item somewhere
- // within it, then we just need to translate that. Otherwise, we're
- // building an rlib which will depend on some upstream implementation of
- // this function, so we just codegen a generic reference to it. We don't
- // specify any of the types for the function, we just make it a symbol
- // that LLVM can later use.
- //
- // Note that MSVC is a little special here in that we don't use the
- // `eh_personality` lang item at all. Currently LLVM has support for
- // both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
- // *name of the personality function* to decide what kind of unwind side
- // tables/landing pads to emit. It looks like Dwarf is used by default,
- // injecting a dependency on the `_Unwind_Resume` symbol for resuming
- // an "exception", but for MSVC we want to force SEH. This means that we
- // can't actually have the personality function be our standard
- // `rust_eh_personality` function, but rather we wired it up to the
- // CRT's custom personality function, which forces LLVM to consider
- // landing pads as "landing pads for SEH".
- let ccx = self.ccx;
- let tcx = ccx.tcx();
- match tcx.lang_items.eh_personality() {
- Some(def_id) if !base::wants_msvc_seh(ccx.sess()) => {
- Callee::def(ccx, def_id, tcx.intern_substs(&[])).reify(ccx)
- }
- _ => {
- if let Some(llpersonality) = ccx.eh_personality().get() {
- return llpersonality
- }
- let name = if base::wants_msvc_seh(ccx.sess()) {
- "__CxxFrameHandler3"
- } else {
- "rust_eh_personality"
- };
- let fty = Type::variadic_func(&[], &Type::i32(ccx));
- let f = declare::declare_cfn(ccx, name, fty);
- ccx.eh_personality().set(Some(f));
- f
- }
- }
- }
-
// Returns a ValueRef of the "eh_unwind_resume" lang item if one is defined,
// otherwise declares it as an external function.
pub fn eh_unwind_resume(&self) -> Callee<'tcx> {
use rustc::hir::def_id::DefId;
use rustc::traits;
use debuginfo;
+use callee::Callee;
+use base;
use declare;
use glue::DropGlueKind;
use monomorphize::Instance;
&self.local().dbg_cx
}
- pub fn eh_personality<'a>(&'a self) -> &'a Cell<Option<ValueRef>> {
- &self.local().eh_personality
- }
-
pub fn eh_unwind_resume<'a>(&'a self) -> &'a Cell<Option<ValueRef>> {
&self.local().eh_unwind_resume
}
base_n::push_str(idx as u64, base_n::ALPHANUMERIC_ONLY, &mut name);
name
}
+
+ pub fn eh_personality(&self) -> ValueRef {
+ // The exception handling personality function.
+ //
+ // If our compilation unit has the `eh_personality` lang item somewhere
+ // within it, then we just need to translate that. Otherwise, we're
+ // building an rlib which will depend on some upstream implementation of
+ // this function, so we just codegen a generic reference to it. We don't
+ // specify any of the types for the function, we just make it a symbol
+ // that LLVM can later use.
+ //
+ // Note that MSVC is a little special here in that we don't use the
+ // `eh_personality` lang item at all. Currently LLVM has support for
+ // both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
+ // *name of the personality function* to decide what kind of unwind side
+ // tables/landing pads to emit. It looks like Dwarf is used by default,
+ // injecting a dependency on the `_Unwind_Resume` symbol for resuming
+ // an "exception", but for MSVC we want to force SEH. This means that we
+ // can't actually have the personality function be our standard
+ // `rust_eh_personality` function, but rather we wired it up to the
+ // CRT's custom personality function, which forces LLVM to consider
+ // landing pads as "landing pads for SEH".
+ let tcx = self.tcx();
+ match tcx.lang_items.eh_personality() {
+ Some(def_id) if !base::wants_msvc_seh(self.sess()) => {
+ Callee::def(self, def_id, tcx.intern_substs(&[])).reify(self)
+ }
+ _ => {
+ if let Some(llpersonality) = self.local().eh_personality.get() {
+ return llpersonality
+ }
+ let name = if base::wants_msvc_seh(self.sess()) {
+ "__CxxFrameHandler3"
+ } else {
+ "rust_eh_personality"
+ };
+ let fty = Type::variadic_func(&[], &Type::i32(self));
+ let f = declare::declare_cfn(self, name, fty);
+ self.local().eh_personality.set(Some(f));
+ f
+ }
+ }
+ }
+
}
pub struct TypeOfDepthLock<'a, 'tcx: 'a>(&'a LocalCrateContext<'tcx>);
let llfn = get_rust_try_fn(bcx.fcx(), &mut |bcx| {
let ccx = bcx.ccx;
- bcx.set_personality_fn(bcx.fcx().eh_personality());
+ bcx.set_personality_fn(bcx.ccx.eh_personality());
let normal = bcx.fcx().build_new_block("normal");
let catchswitch = bcx.fcx().build_new_block("catchswitch");
// rust_try ignores the selector.
let lpad_ty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)],
false);
- let vals = catch.landing_pad(lpad_ty, bcx.fcx().eh_personality(), 1, catch.fcx().llfn);
+ let vals = catch.landing_pad(lpad_ty, bcx.ccx.eh_personality(), 1, catch.fcx().llfn);
catch.add_clause(vals, C_null(Type::i8p(ccx)));
let ptr = catch.extract_value(vals, 0);
catch.store(ptr, catch.bitcast(local_ptr, Type::i8p(ccx).ptr_to()));
self.landing_pads[target_bb] = Some(bcx.llbb());
let ccx = bcx.ccx;
- let llpersonality = self.fcx.eh_personality();
+ let llpersonality = self.ccx.eh_personality();
let llretty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)], false);
let llretval = bcx.landing_pad(llretty, llpersonality, 1, self.fcx.llfn);
bcx.set_cleanup(llretval);
mircx.cleanup_kinds.iter_enumerated().map(|(bb, cleanup_kind)| {
if let CleanupKind::Funclet = *cleanup_kind {
let bcx = mircx.build_block(bb);
- bcx.set_personality_fn(fcx.eh_personality());
+ bcx.set_personality_fn(mircx.ccx.eh_personality());
if base::wants_msvc_seh(fcx.ccx.sess()) {
return Some(Funclet::new(bcx.cleanup_pad(None, &[])));
}