Skip to content

Commit ace502a

Browse files
committed
Fix review comments
1 parent 2d241f6 commit ace502a

File tree

4 files changed

+84
-38
lines changed

4 files changed

+84
-38
lines changed

src/librustc_driver/lib.rs

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,81 @@ pub mod rustc_trans {
189189
pub fn print_passes() {}
190190
}
191191

192+
fn load_backend_from_dylib(sess: &Session, backend_name: &str) -> Box<TransCrate> {
193+
use std::sync::mpsc;
194+
use std::path::Path;
195+
use syntax::symbol::Symbol;
196+
use rustc::session::config::OutputFilenames;
197+
use rustc::ty::TyCtxt;
198+
use rustc::ty::maps::Providers;
199+
use rustc::middle::cstore::MetadataLoader;
200+
use rustc::dep_graph::DepGraph;
201+
use rustc_metadata::dynamic_lib::DynamicLibrary;
202+
/// This prevents the dylib from being unloaded when there is still a TransCrate open
203+
struct ExternTransCrate {
204+
_lib: DynamicLibrary,
205+
trans: Box<TransCrate>,
206+
}
207+
impl TransCrate for ExternTransCrate {
208+
fn print(&self, req: PrintRequest, sess: &Session) {
209+
self.trans.print(req, sess);
210+
}
211+
fn target_features(&self, sess: &Session) -> Vec<Symbol> {
212+
self.trans.target_features((sess))
213+
}
214+
215+
fn metadata_loader(&self) -> Box<MetadataLoader> {
216+
self.trans.metadata_loader()
217+
}
218+
fn provide(&self, providers: &mut Providers) {
219+
self.trans.provide(providers)
220+
}
221+
fn provide_extern(&self, providers: &mut Providers) {
222+
self.trans.provide_extern(providers)
223+
}
224+
fn trans_crate<'a, 'tcx>(
225+
&self,
226+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
227+
rx: mpsc::Receiver<Box<Any + Send>>
228+
) -> Box<Any> {
229+
self.trans.trans_crate(tcx, rx)
230+
}
231+
232+
fn join_trans_and_link(
233+
&self,
234+
trans: Box<Any>,
235+
sess: &Session,
236+
dep_graph: &DepGraph,
237+
outputs: &OutputFilenames,
238+
) -> Result<(), CompileIncomplete> {
239+
self.trans.join_trans_and_link(trans, sess, dep_graph, outputs)
240+
}
241+
}
242+
243+
match DynamicLibrary::open(Some(Path::new(backend_name))) {
244+
Ok(lib) => {
245+
unsafe {
246+
let trans = {
247+
let __rustc_codegen_backend: unsafe fn(&Session) -> Box<TransCrate>;
248+
__rustc_codegen_backend = match lib.symbol("__rustc_codegen_backend") {
249+
Ok(f) => ::std::mem::transmute::<*mut u8, _>(f),
250+
Err(e) => sess.fatal(&format!("Couldnt load codegen backend as it\
251+
doesn't export the __rustc_backend_new symbol: {:?}", e)),
252+
};
253+
__rustc_codegen_backend(sess)
254+
};
255+
Box::new(ExternTransCrate {
256+
_lib: lib,
257+
trans
258+
})
259+
}
260+
}
261+
Err(err) => {
262+
sess.fatal(&format!("Couldnt load codegen backend {:?}: {:?}", backend_name, err));
263+
}
264+
}
265+
}
266+
192267
pub fn get_trans(sess: &Session) -> Box<TransCrate> {
193268
let trans_name = sess.opts.debugging_opts.codegen_backend.clone();
194269
match trans_name.as_ref().map(|s|&**s) {
@@ -197,10 +272,10 @@ pub fn get_trans(sess: &Session) -> Box<TransCrate> {
197272
Some("metadata_only") => {
198273
rustc_trans_utils::trans_crate::MetadataOnlyTransCrate::new(&sess)
199274
}
200-
Some(filename) if filename.starts_with("/") => {
201-
rustc_trans_utils::trans_crate::link_extern_backend(&sess, filename)
275+
Some(filename) if filename.contains(".") => {
276+
load_backend_from_dylib(&sess, &filename)
202277
}
203-
Some(trans_name) => sess.fatal(&format!("Invalid trans {}", trans_name)),
278+
Some(trans_name) => sess.fatal(&format!("Unknown codegen backend {}", trans_name)),
204279
}
205280
}
206281

src/librustc_trans/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ extern crate rustc_demangle;
5656
extern crate rustc_incremental;
5757
extern crate rustc_llvm as llvm;
5858
extern crate rustc_platform_intrinsics as intrinsics;
59-
#[macro_use]
6059
extern crate rustc_trans_utils;
6160

6261
#[macro_use] extern crate log;
@@ -251,7 +250,11 @@ impl TransCrate for LlvmTransCrate {
251250
}
252251
}
253252

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

256259
struct ModuleTranslation {
257260
/// The name of the module. When the crate may be saved between

src/librustc_trans_utils/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ extern crate ar;
3131
extern crate flate2;
3232
#[macro_use]
3333
extern crate log;
34-
extern crate libloading;
3534

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

5453
pub mod diagnostics;
5554
pub mod link;
56-
#[macro_export]
5755
pub mod trans_crate;
5856
pub mod symbol_names;
5957
pub mod symbol_names_test;

src/librustc_trans_utils/trans_crate.rs

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
use std::any::Any;
2525
use std::io::prelude::*;
2626
use std::io::{self, Cursor};
27-
use std::ffi::OsStr;
2827
use std::fs::File;
2928
use std::path::Path;
3029
use std::sync::mpsc;
@@ -41,7 +40,7 @@ use rustc::session::config::{CrateType, OutputFilenames, PrintRequest};
4140
use rustc::ty::TyCtxt;
4241
use rustc::ty::maps::Providers;
4342
use rustc::middle::cstore::EncodedMetadata;
44-
use rustc::middle::cstore::MetadataLoader as MetadataLoader;
43+
use rustc::middle::cstore::MetadataLoader;
4544
use rustc::dep_graph::DepGraph;
4645
use rustc_back::target::Target;
4746
use rustc_mir::monomorphize::collector;
@@ -74,35 +73,6 @@ pub trait TransCrate {
7473
) -> Result<(), CompileIncomplete>;
7574
}
7675

77-
#[macro_export]
78-
macro_rules! hot_pluggable_trans_crate {
79-
(|$sess:ident| { $body:expr }) => {
80-
#[no_mangle]
81-
pub fn __rustc_backend_new($sess: &Session) -> Box<TransCrate> {
82-
{ $body }
83-
}
84-
}
85-
}
86-
87-
pub fn link_extern_backend<P: AsRef<OsStr>>(sess: &Session, filename: P) -> Box<TransCrate> {
88-
use libloading::*;
89-
let filename = filename.as_ref();
90-
match Library::new(filename) {
91-
Ok(lib) => {
92-
unsafe {
93-
let __rustc_backend_new: Symbol<unsafe fn(&Session) -> Box<TransCrate>>;
94-
__rustc_backend_new = lib.get(b"__rustc_backend_new")
95-
.expect("Couldnt load codegen backend as it\
96-
doesnt export the __rustc_backend_new symbol");
97-
__rustc_backend_new(sess)
98-
}
99-
}
100-
Err(err) => {
101-
sess.fatal(&format!("Couldnt load codegen backend {:?}: {:?}", filename, err));
102-
}
103-
}
104-
}
105-
10676
pub struct DummyTransCrate;
10777

10878
impl TransCrate for DummyTransCrate {

0 commit comments

Comments
 (0)