Skip to content

Commit

Permalink
auto merge of #11121 : vadimcn/rust/no-c++2, r=alexcrichton
Browse files Browse the repository at this point in the history
This PR removes Rust's dependency on C++ for exception handling. Instead, it will use the unwind library API directly.

closes #10469
  • Loading branch information
bors committed Dec 24, 2013
2 parents b8c87fd + e3b3715 commit 32e730f
Show file tree
Hide file tree
Showing 16 changed files with 355 additions and 161 deletions.
22 changes: 12 additions & 10 deletions mk/rt.mk
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@ RUNTIME_CXXFLAGS_$(1)_$(2) = -D_RUST_STAGE1
endif
endif

RUNTIME_CXXS_$(1)_$(2) := \
rt/rust_cxx_glue.cpp

RUNTIME_CS_$(1)_$(2) := \
rt/rust_builtin.c \
rt/rust_upcall.c \
rt/miniz.c \
rt/rust_android_dummy.c \
rt/rust_test_helpers.c

RUNTIME_LL_$(1)_$(2) := \
rt/rust_try.ll

# stage0 remove this after the next snapshot
%.cpp:
@touch tmp/foo.o
Expand All @@ -94,19 +94,16 @@ RT_BUILD_DIR_$(1)_$(2) := $$(RT_OUTPUT_DIR_$(1))/stage$(2)
RUNTIME_DEF_$(1)_$(2) := $$(RT_OUTPUT_DIR_$(1))/rustrt$$(CFG_DEF_SUFFIX_$(1))
RUNTIME_INCS_$(1)_$(2) := -I $$(S)src/rt -I $$(S)src/rt/isaac -I $$(S)src/rt/uthash \
-I $$(S)src/rt/arch/$$(HOST_$(1))
RUNTIME_OBJS_$(1)_$(2) := $$(RUNTIME_CXXS_$(1)_$(2):rt/%.cpp=$$(RT_BUILD_DIR_$(1)_$(2))/%.o) \
RUNTIME_OBJS_$(1)_$(2) := \
$$(RUNTIME_CS_$(1)_$(2):rt/%.c=$$(RT_BUILD_DIR_$(1)_$(2))/%.o) \
$$(RUNTIME_S_$(1)_$(2):rt/%.S=$$(RT_BUILD_DIR_$(1)_$(2))/%.o)
$$(RUNTIME_S_$(1)_$(2):rt/%.S=$$(RT_BUILD_DIR_$(1)_$(2))/%.o) \
$$(RUNTIME_LL_$(1)_$(2):rt/%.ll=$$(RT_BUILD_DIR_$(1)_$(2))/%.o)

ALL_OBJ_FILES += $$(RUNTIME_OBJS_$(1)_$(2))

MORESTACK_OBJS_$(1)_$(2) := $$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/morestack.o
ALL_OBJ_FILES += $$(MORESTACK_OBJS_$(1)_$(2))

$$(RT_BUILD_DIR_$(1)_$(2))/rust_cxx_glue.o: rt/rust_cxx_glue.cpp $$(MKFILE_DEPS)
@$$(call E, compile: $$@)
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@, $$(RUNTIME_INCS_$(1)_$(2)) \
$$(SNAP_DEFINES) $$(RUNTIME_CXXFLAGS_$(1)_$(2))) $$<

$$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.c $$(MKFILE_DEPS)
@$$(call E, compile: $$@)
$$(Q)$$(call CFG_COMPILE_C_$(1), $$@, $$(RUNTIME_INCS_$(1)_$(2)) \
Expand All @@ -117,6 +114,11 @@ $$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.S $$(MKFILE_DEPS) \
@$$(call E, compile: $$@)
$$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<)

$$(RT_BUILD_DIR_$(1)_$(2))/%.o: rt/%.ll $$(MKFILE_DEPS) \
$$(LLVM_CONFIG_$$(CFG_BUILD))
@$$(call E, compile: $$@)
$$(Q)$(LLC_$(CFG_BUILD)) -filetype=obj -mtriple=$(1) -relocation-model=pic -o $$@ $$<

$$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJS_$(1)_$(2))
@$$(call E, link: $$@)
$$(Q)$(AR_$(1)) rcs $$@ $$^
Expand Down
1 change: 1 addition & 0 deletions src/etc/mklldeps.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
for lib in out.strip().split(' '):
lib = lib[2:] # chop of the leading '-l'
f.write("#[link(name = \"" + lib + "\", kind = \"static\")]\n")
f.write("#[link(name = \"stdc++\")]\n")
if os == 'win32':
f.write("#[link(name = \"imagehlp\")]\n")
f.write("extern {}\n")
14 changes: 9 additions & 5 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,10 +708,7 @@ pub fn get_cc_prog(sess: Session) -> ~str {
// In the future, FreeBSD will use clang as default compiler.
// It would be flexible to use cc (system's default C compiler)
// instead of hard-coded gcc.
// For win32, there is no cc command, so we add a condition to make it use
// g++. We use g++ rather than gcc because it automatically adds linker
// options required for generation of dll modules that correctly register
// stack unwind tables.
// For win32, there is no cc command, so we add a condition to make it use gcc.
match sess.targ_cfg.os {
abi::OsAndroid => match sess.opts.android_cross_path {
Some(ref path) => format!("{}/bin/arm-linux-androideabi-gcc", *path),
Expand All @@ -720,7 +717,7 @@ pub fn get_cc_prog(sess: Session) -> ~str {
(--android-cross-path)")
}
},
abi::OsWin32 => ~"g++",
abi::OsWin32 => ~"gcc",
_ => ~"cc",
}
}
Expand Down Expand Up @@ -1032,6 +1029,13 @@ fn link_args(sess: Session,
}
}

if sess.targ_cfg.os == abi::OsWin32 {
// Make sure that we link to the dynamic libgcc, otherwise cross-module
// DWARF stack unwinding will not work.
// This behavior may be overriden by --link-args "-static-libgcc"
args.push(~"-shared-libgcc");
}

add_local_native_libraries(&mut args, sess);
add_upstream_rust_crates(&mut args, sess, dylib, tmpdir);
add_upstream_native_libraries(&mut args, sess);
Expand Down
35 changes: 0 additions & 35 deletions src/librustc/back/upcall.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ pub mod back {
pub mod link;
pub mod manifest;
pub mod abi;
pub mod upcall;
pub mod arm;
pub mod mips;
pub mod x86;
Expand Down
1 change: 0 additions & 1 deletion src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,6 @@ pub mod llvm {
// automatically updated whenever LLVM is updated to include an up-to-date
// set of the libraries we need to link to LLVM for.
#[link(name = "rustllvm", kind = "static")]
#[link(name = "stdc++")]
extern {
/* Create and destroy contexts. */
pub fn LLVMContextCreate() -> ContextRef;
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ pub fn collect_language_items(crate: &ast::Crate,
}

lets_do_this! {
There are 42 lang items.
There are 43 lang items.

// ID, Variant name, Name, Method name;
0, FreezeTraitLangItem, "freeze", freeze_trait;
Expand Down Expand Up @@ -261,5 +261,7 @@ lets_do_this! {
40, EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory;

41, TypeIdLangItem, "type_id", type_id;

42, EhPersonalityLangItem, "eh_personality", eh_personality_fn;
}

11 changes: 7 additions & 4 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use metadata::{csearch, cstore, encoder};
use middle::astencode;
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
use middle::lang_items::{MallocFnLangItem, ClosureExchangeMallocFnLangItem};
use middle::lang_items::{EhPersonalityLangItem};
use middle::trans::_match;
use middle::trans::adt;
use middle::trans::base;
Expand Down Expand Up @@ -1027,10 +1028,10 @@ pub fn get_landing_pad(bcx: @mut Block) -> BasicBlockRef {
// this represents but it's determined by the personality function and
// this is what the EH proposal example uses.
let llretty = Type::struct_([Type::i8p(), Type::i32()], false);
// The exception handling personality function. This is the C++
// personality function __gxx_personality_v0, wrapped in our naming
// convention.
let personality = bcx.ccx().upcalls.rust_personality;
// The exception handling personality function.
let personality = callee::trans_fn_ref(bcx,
langcall(bcx, None, "", EhPersonalityLangItem),
0).llfn;
// The only landing pad clause will be 'cleanup'
let llretval = LandingPad(pad_bcx, llretty, personality, 1u);
// The landing pad block is a cleanup
Expand Down Expand Up @@ -3195,6 +3196,8 @@ pub fn trans_crate(sess: session::Session,
reachable.push(ccx.crate_map_name.to_owned());
reachable.push(~"main");
reachable.push(~"rust_stack_exhausted");
reachable.push(~"rust_eh_personality"); // referenced from .eh_frame section on some platforms
reachable.push(~"rust_eh_personality_catch"); // referenced from rt/rust_try.ll

return CrateTranslation {
context: llcx,
Expand Down
3 changes: 0 additions & 3 deletions src/librustc/middle/trans/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// except according to those terms.


use back::{upcall};
use driver::session;
use lib::llvm::{ContextRef, ModuleRef, ValueRef};
use lib::llvm::{llvm, TargetData, TypeNames};
Expand Down Expand Up @@ -105,7 +104,6 @@ pub struct CrateContext {
tcx: ty::ctxt,
maps: astencode::Maps,
stats: @mut Stats,
upcalls: @upcall::Upcalls,
tydesc_type: Type,
int_type: Type,
opaque_vec_type: Type,
Expand Down Expand Up @@ -233,7 +231,6 @@ impl CrateContext {
llvm_insns: HashMap::new(),
fn_stats: ~[]
},
upcalls: upcall::declare_upcalls(targ_cfg, llmod),
tydesc_type: tydesc_type,
int_type: int_type,
opaque_vec_type: opaque_vec_type,
Expand Down
3 changes: 3 additions & 0 deletions src/libstd/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ mod local_ptr;
/// Bindings to pthread/windows thread-local storage.
mod thread_local_storage;

/// Stack unwinding
pub mod unwind;

/// Just stuff
mod util;

Expand Down
68 changes: 2 additions & 66 deletions src/libstd/rt/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ use super::local_heap::LocalHeap;
use prelude::*;

use borrow;
use cast::transmute;
use cleanup;
use io::Writer;
use libc::{c_void, uintptr_t, c_char, size_t};
use libc::{c_char, size_t};
use local_data;
use option::{Option, Some, None};
use rt::borrowck::BorrowRecord;
Expand All @@ -33,8 +32,8 @@ use rt::local::Local;
use rt::logging::StdErrLogger;
use rt::sched::{Scheduler, SchedHandle};
use rt::stack::{StackSegment, StackPool};
use rt::unwind::Unwinder;
use send_str::SendStr;
use task::TaskResult;
use unstable::finally::Finally;
use unstable::mutex::Mutex;

Expand Down Expand Up @@ -91,21 +90,6 @@ pub enum SchedHome {
pub struct GarbageCollector;
pub struct LocalStorage(Option<local_data::Map>);

pub struct Unwinder {
unwinding: bool,
cause: Option<~Any>
}

impl Unwinder {
fn result(&mut self) -> TaskResult {
if self.unwinding {
Err(self.cause.take().unwrap())
} else {
Ok(())
}
}
}

impl Task {

// A helper to build a new task using the dynamically found
Expand Down Expand Up @@ -452,54 +436,6 @@ impl Coroutine {

}


// Just a sanity check to make sure we are catching a Rust-thrown exception
static UNWIND_TOKEN: uintptr_t = 839147;

impl Unwinder {
pub fn try(&mut self, f: ||) {
use unstable::raw::Closure;

unsafe {
let closure: Closure = transmute(f);
let code = transmute(closure.code);
let env = transmute(closure.env);

let token = rust_try(try_fn, code, env);
assert!(token == 0 || token == UNWIND_TOKEN);
}

extern fn try_fn(code: *c_void, env: *c_void) {
unsafe {
let closure: Closure = Closure {
code: transmute(code),
env: transmute(env),
};
let closure: || = transmute(closure);
closure();
}
}

extern {
fn rust_try(f: extern "C" fn(*c_void, *c_void),
code: *c_void,
data: *c_void) -> uintptr_t;
}
}

pub fn begin_unwind(&mut self, cause: ~Any) -> ! {
self.unwinding = true;
self.cause = Some(cause);
unsafe {
rust_begin_unwind(UNWIND_TOKEN);
return transmute(());
}
extern {
fn rust_begin_unwind(token: uintptr_t);
}
}
}

/// This function is invoked from rust's current __morestack function. Segmented
/// stacks are currently not enabled as segmented stacks, but rather one giant
/// stack segment. This means that whenever we run out of stack, we want to
Expand Down
Loading

0 comments on commit 32e730f

Please sign in to comment.