Skip to content

Commit

Permalink
Fix review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Jan 19, 2018
1 parent 2d241f6 commit ace502a
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 38 deletions.
81 changes: 78 additions & 3 deletions src/librustc_driver/lib.rs
Expand Up @@ -189,6 +189,81 @@ pub mod rustc_trans {
pub fn print_passes() {}
}

fn load_backend_from_dylib(sess: &Session, backend_name: &str) -> Box<TransCrate> {
use std::sync::mpsc;
use std::path::Path;
use syntax::symbol::Symbol;
use rustc::session::config::OutputFilenames;
use rustc::ty::TyCtxt;
use rustc::ty::maps::Providers;
use rustc::middle::cstore::MetadataLoader;
use rustc::dep_graph::DepGraph;
use rustc_metadata::dynamic_lib::DynamicLibrary;
/// This prevents the dylib from being unloaded when there is still a TransCrate open
struct ExternTransCrate {
_lib: DynamicLibrary,
trans: Box<TransCrate>,
}
impl TransCrate for ExternTransCrate {
fn print(&self, req: PrintRequest, sess: &Session) {
self.trans.print(req, sess);
}
fn target_features(&self, sess: &Session) -> Vec<Symbol> {
self.trans.target_features((sess))
}

fn metadata_loader(&self) -> Box<MetadataLoader> {
self.trans.metadata_loader()
}
fn provide(&self, providers: &mut Providers) {
self.trans.provide(providers)
}
fn provide_extern(&self, providers: &mut Providers) {
self.trans.provide_extern(providers)
}
fn trans_crate<'a, 'tcx>(
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
rx: mpsc::Receiver<Box<Any + Send>>
) -> Box<Any> {
self.trans.trans_crate(tcx, rx)
}

fn join_trans_and_link(
&self,
trans: Box<Any>,
sess: &Session,
dep_graph: &DepGraph,
outputs: &OutputFilenames,
) -> Result<(), CompileIncomplete> {
self.trans.join_trans_and_link(trans, sess, dep_graph, outputs)
}
}

match DynamicLibrary::open(Some(Path::new(backend_name))) {
Ok(lib) => {
unsafe {
let trans = {
let __rustc_codegen_backend: unsafe fn(&Session) -> Box<TransCrate>;
__rustc_codegen_backend = match lib.symbol("__rustc_codegen_backend") {
Ok(f) => ::std::mem::transmute::<*mut u8, _>(f),
Err(e) => sess.fatal(&format!("Couldnt load codegen backend as it\
doesn't export the __rustc_backend_new symbol: {:?}", e)),
};
__rustc_codegen_backend(sess)
};
Box::new(ExternTransCrate {
_lib: lib,
trans
})
}
}
Err(err) => {
sess.fatal(&format!("Couldnt load codegen backend {:?}: {:?}", backend_name, err));
}
}
}

pub fn get_trans(sess: &Session) -> Box<TransCrate> {
let trans_name = sess.opts.debugging_opts.codegen_backend.clone();
match trans_name.as_ref().map(|s|&**s) {
Expand All @@ -197,10 +272,10 @@ pub fn get_trans(sess: &Session) -> Box<TransCrate> {
Some("metadata_only") => {
rustc_trans_utils::trans_crate::MetadataOnlyTransCrate::new(&sess)
}
Some(filename) if filename.starts_with("/") => {
rustc_trans_utils::trans_crate::link_extern_backend(&sess, filename)
Some(filename) if filename.contains(".") => {
load_backend_from_dylib(&sess, &filename)
}
Some(trans_name) => sess.fatal(&format!("Invalid trans {}", trans_name)),
Some(trans_name) => sess.fatal(&format!("Unknown codegen backend {}", trans_name)),
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/librustc_trans/lib.rs
Expand Up @@ -56,7 +56,6 @@ extern crate rustc_demangle;
extern crate rustc_incremental;
extern crate rustc_llvm as llvm;
extern crate rustc_platform_intrinsics as intrinsics;
#[macro_use]
extern crate rustc_trans_utils;

#[macro_use] extern crate log;
Expand Down Expand Up @@ -251,7 +250,11 @@ impl TransCrate for LlvmTransCrate {
}
}

hot_pluggable_trans_crate!(|sess| { LlvmTransCrate::new(sess) });
/// This is the entrypoint for a hot plugged rustc_trans
#[no_mangle]
pub extern "C" fn __rustc_codegen_backend(sess: &Session) -> Box<TransCrate> {
LlvmTransCrate::new(sess)
}

struct ModuleTranslation {
/// The name of the module. When the crate may be saved between
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_trans_utils/lib.rs
Expand Up @@ -31,7 +31,6 @@ extern crate ar;
extern crate flate2;
#[macro_use]
extern crate log;
extern crate libloading;

#[macro_use]
extern crate rustc;
Expand All @@ -53,7 +52,6 @@ use rustc::util::nodemap::NodeSet;

pub mod diagnostics;
pub mod link;
#[macro_export]
pub mod trans_crate;
pub mod symbol_names;
pub mod symbol_names_test;
Expand Down
32 changes: 1 addition & 31 deletions src/librustc_trans_utils/trans_crate.rs
Expand Up @@ -24,7 +24,6 @@
use std::any::Any;
use std::io::prelude::*;
use std::io::{self, Cursor};
use std::ffi::OsStr;
use std::fs::File;
use std::path::Path;
use std::sync::mpsc;
Expand All @@ -41,7 +40,7 @@ use rustc::session::config::{CrateType, OutputFilenames, PrintRequest};
use rustc::ty::TyCtxt;
use rustc::ty::maps::Providers;
use rustc::middle::cstore::EncodedMetadata;
use rustc::middle::cstore::MetadataLoader as MetadataLoader;
use rustc::middle::cstore::MetadataLoader;
use rustc::dep_graph::DepGraph;
use rustc_back::target::Target;
use rustc_mir::monomorphize::collector;
Expand Down Expand Up @@ -74,35 +73,6 @@ pub trait TransCrate {
) -> Result<(), CompileIncomplete>;
}

#[macro_export]
macro_rules! hot_pluggable_trans_crate {
(|$sess:ident| { $body:expr }) => {
#[no_mangle]
pub fn __rustc_backend_new($sess: &Session) -> Box<TransCrate> {
{ $body }
}
}
}

pub fn link_extern_backend<P: AsRef<OsStr>>(sess: &Session, filename: P) -> Box<TransCrate> {
use libloading::*;
let filename = filename.as_ref();
match Library::new(filename) {
Ok(lib) => {
unsafe {
let __rustc_backend_new: Symbol<unsafe fn(&Session) -> Box<TransCrate>>;
__rustc_backend_new = lib.get(b"__rustc_backend_new")
.expect("Couldnt load codegen backend as it\
doesnt export the __rustc_backend_new symbol");
__rustc_backend_new(sess)
}
}
Err(err) => {
sess.fatal(&format!("Couldnt load codegen backend {:?}: {:?}", filename, err));
}
}
}

pub struct DummyTransCrate;

impl TransCrate for DummyTransCrate {
Expand Down

0 comments on commit ace502a

Please sign in to comment.