Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix hotplug backend and add test
  • Loading branch information
bjorn3 committed Jan 19, 2018
commit 4ef16d7466cca262c682fb3a9441a88a61a089df
8 changes: 8 additions & 0 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ fn load_backend_from_dylib(sess: &Session, backend_name: &str) -> Box<TransCrate
_lib: DynamicLibrary,
trans: Box<TransCrate>,
}

impl Drop for ExternTransCrate {
fn drop(&mut self) {
// Make sure trans gets dropped before _lib as bad things happen otherwise
self.trans = Box::new(::rustc_trans_utils::trans_crate::DummyTransCrate)
}
}

impl TransCrate for ExternTransCrate {
fn print(&self, req: PrintRequest, sess: &Session) {
self.trans.print(req, sess);
Expand Down
10 changes: 10 additions & 0 deletions src/test/run-make/hotplug_codegen_backend/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include ../tools.mk

all:
/bin/echo || exit 0 # This test requires /bin/echo to exist
$(RUSTC) the_backend.rs --crate-name the_backend --crate-type dylib \
-o $(TMPDIR)/the_backend.dylib
sleep 10
$(RUSTC) some_crate.rs --crate-name some_crate --crate-type bin -o $(TMPDIR)/some_crate \
-Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options
grep -x "This has been \"compiled\" succesfully." $(TMPDIR)/some_crate
3 changes: 3 additions & 0 deletions src/test/run-make/hotplug_codegen_backend/some_crate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
::std::process::exit(1);
}
72 changes: 72 additions & 0 deletions src/test/run-make/hotplug_codegen_backend/the_backend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#![feature(rustc_private)]

extern crate syntax;
extern crate rustc;
extern crate rustc_trans_utils;

use std::any::Any;
use std::sync::mpsc;
use syntax::symbol::Symbol;
use rustc::session::{Session, CompileIncomplete};
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_trans_utils::trans_crate::{TransCrate, MetadataOnlyTransCrate};

struct TheBackend(Box<TransCrate>);

impl TransCrate for TheBackend {
fn metadata_loader(&self) -> Box<MetadataLoader> {
self.0.metadata_loader()
}

fn provide(&self, providers: &mut Providers) {
self.0.provide(providers);
}

fn provide_extern(&self, providers: &mut Providers) {
self.0.provide_extern(providers);
}

fn trans_crate<'a, 'tcx>(
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_rx: mpsc::Receiver<Box<Any + Send>>
) -> Box<Any> {
use rustc::hir::def_id::LOCAL_CRATE;

Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol)
}

fn join_trans_and_link(
&self,
trans: Box<Any>,
sess: &Session,
_dep_graph: &DepGraph,
outputs: &OutputFilenames,
) -> Result<(), CompileIncomplete> {
use std::io::Write;
use rustc::session::config::CrateType;
use rustc_trans_utils::link::out_filename;
let crate_name = trans.downcast::<Symbol>()
.expect("in join_trans_and_link: trans is not a Symbol");
for &crate_type in sess.opts.crate_types.iter() {
if crate_type != CrateType::CrateTypeExecutable {
sess.fatal(&format!("Crate type is {:?}", crate_type));
}
let output_name =
out_filename(sess, crate_type, &outputs, &*crate_name.as_str());
let mut out_file = ::std::fs::File::create(output_name).unwrap();
write!(out_file, "This has been \"compiled\" succesfully.").unwrap();
}
Ok(())
}
}

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