mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-02 11:44:28 +00:00
Hot plug rustc_trans
This commit is contained in:
parent
6dffaa9175
commit
9315ed45c5
12
src/Cargo.lock
generated
12
src/Cargo.lock
generated
@ -1021,6 +1021,16 @@ dependencies = [
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
version = "0.2.6"
|
||||
@ -2128,6 +2138,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libloading 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc 0.0.0",
|
||||
"rustc_back 0.0.0",
|
||||
@ -2971,6 +2982,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b"
|
||||
"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121"
|
||||
"checksum libgit2-sys 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6eeae66e7b1c995de45cb4e65c5ab438a96a7b4077e448645d4048dc753ad357"
|
||||
"checksum libloading 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd38073de8f7965d0c17d30546d4bb6da311ab428d1c7a3fc71dff7f9d4979b9"
|
||||
"checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75"
|
||||
"checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16"
|
||||
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
|
@ -197,6 +197,9 @@ 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::ExternTransCrate::new(&sess, filename)
|
||||
}
|
||||
Some(trans_name) => sess.fatal(&format!("Invalid trans {}", trans_name)),
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ 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;
|
||||
@ -250,6 +251,8 @@ impl TransCrate for LlvmTransCrate {
|
||||
}
|
||||
}
|
||||
|
||||
hot_pluggable_trans_crate!(|sess| { LlvmTransCrate::new(sess) });
|
||||
|
||||
struct ModuleTranslation {
|
||||
/// The name of the module. When the crate may be saved between
|
||||
/// compilations, incremental compilation requires that name be
|
||||
|
@ -13,6 +13,7 @@ test = false
|
||||
ar = "0.3.0"
|
||||
flate2 = "1.0"
|
||||
log = "0.4"
|
||||
libloading = "0.4"
|
||||
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
@ -31,6 +31,7 @@ extern crate ar;
|
||||
extern crate flate2;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate libloading;
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
@ -42,6 +43,8 @@ extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
extern crate rustc_data_structures;
|
||||
|
||||
pub extern crate rustc as __rustc;
|
||||
|
||||
use rustc::ty::{TyCtxt, Instance};
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
@ -50,6 +53,7 @@ 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;
|
||||
|
@ -24,6 +24,7 @@
|
||||
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;
|
||||
@ -73,6 +74,186 @@ pub trait TransCrate {
|
||||
) -> Result<(), CompileIncomplete>;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! hot_pluggable_trans_crate {
|
||||
(|$sess:ident| { $body:expr }) => {
|
||||
use $crate::__rustc::ty::maps::Providers;
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __rustc_backend_new($sess: &Session) -> *mut Box<TransCrate> {
|
||||
let trans_crate = { $body };
|
||||
Box::into_raw(Box::new(trans_crate))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __rustc_backend_metadata_loader(
|
||||
trans_crate: *const Box<TransCrate>
|
||||
) -> *mut Box<MetadataLoader> {
|
||||
let trans_crate = unsafe { &*trans_crate };
|
||||
let metadata_loader = trans_crate.metadata_loader();
|
||||
Box::into_raw(Box::new(metadata_loader))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __rustc_backend_provide(
|
||||
trans_crate: *const Box<TransCrate>,
|
||||
providers: *mut Providers
|
||||
) {
|
||||
let trans_crate = unsafe { &*trans_crate };
|
||||
let providers = unsafe { &mut *providers };
|
||||
trans_crate.provide(providers);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __rustc_backend_provide_extern(
|
||||
trans_crate: *const Box<TransCrate>,
|
||||
providers: *mut Providers
|
||||
) {
|
||||
let trans_crate = unsafe { &*trans_crate };
|
||||
let providers = unsafe { &mut *providers };
|
||||
trans_crate.provide_extern(providers);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __rustc_backend_trans_crate<'a, 'tcx: 'a>(
|
||||
trans_crate: *const Box<TransCrate>,
|
||||
tcx: *mut TyCtxt<'a, 'tcx, 'tcx>,
|
||||
rx: *mut mpsc::Receiver<Box<Any + Send>>
|
||||
) -> *mut Box<Any> {
|
||||
let trans_crate = unsafe { &*trans_crate };
|
||||
let tcx = unsafe { *tcx };
|
||||
let rx = unsafe { *Box::from_raw(rx) };
|
||||
let trans = trans_crate.trans_crate(tcx, rx);
|
||||
Box::into_raw(Box::new(trans))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __rustc_backend_join_trans_and_link(
|
||||
trans_crate: *const Box<TransCrate>,
|
||||
trans: *mut Box<Any>,
|
||||
sess: *const Session,
|
||||
dep_graph: *const DepGraph,
|
||||
outputs: *const OutputFilenames
|
||||
) -> *mut Result<(), CompileIncomplete> {
|
||||
let trans_crate = unsafe { &*trans_crate };
|
||||
let trans = unsafe { *Box::from_raw(trans) };
|
||||
let sess = unsafe { &*sess };
|
||||
let dep_graph = unsafe { &*dep_graph };
|
||||
let outputs = unsafe { &*outputs };
|
||||
let result = trans_crate.join_trans_and_link(trans, sess, dep_graph, outputs);
|
||||
Box::into_raw(Box::new(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExternTransCrate {
|
||||
lib: ::libloading::Library,
|
||||
backend: Box<Box<TransCrate>>,
|
||||
}
|
||||
|
||||
macro_rules! get_symbol {
|
||||
(($lib:expr) . $name:ident : $type:ty) => {
|
||||
let $name: ::libloading::Symbol<$type> = $lib.get(stringify!($name).as_bytes()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl ExternTransCrate {
|
||||
pub fn new<P: AsRef<OsStr>>(sess: &Session, filename: P) -> Box<TransCrate> {
|
||||
use libloading::*;
|
||||
let filename = filename.as_ref();
|
||||
match Library::new(filename) {
|
||||
Ok(lib) => {
|
||||
let backend = unsafe {
|
||||
get_symbol!((lib).__rustc_backend_new:
|
||||
unsafe extern "C" fn(&Session) -> *mut Box<TransCrate>);
|
||||
Box::from_raw(__rustc_backend_new(sess))
|
||||
};
|
||||
Box::new(ExternTransCrate {
|
||||
lib,
|
||||
backend,
|
||||
})
|
||||
}
|
||||
Err(err) => {
|
||||
sess.fatal(&format!("Couldnt load codegen backend {:?}: {:?}", filename, err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TransCrate for ExternTransCrate {
|
||||
fn metadata_loader(&self) -> Box<MetadataLoader> {
|
||||
unsafe {
|
||||
get_symbol!((self.lib).__rustc_backend_metadata_loader:
|
||||
unsafe extern "C" fn(*const Box<TransCrate>) -> *mut Box<MetadataLoader>);
|
||||
*Box::from_raw(__rustc_backend_metadata_loader(self.backend.as_ref() as *const _))
|
||||
}
|
||||
}
|
||||
|
||||
fn provide(&self, providers: &mut Providers) {
|
||||
unsafe {
|
||||
get_symbol!((self.lib).__rustc_backend_provide:
|
||||
unsafe extern "C" fn(*const Box<TransCrate>, *mut Providers));
|
||||
__rustc_backend_provide(self.backend.as_ref() as *const _, providers as *mut _);
|
||||
}
|
||||
}
|
||||
|
||||
fn provide_extern(&self, providers: &mut Providers) {
|
||||
unsafe {
|
||||
get_symbol!((self.lib).__rustc_backend_provide_extern:
|
||||
unsafe extern "C" fn(*const Box<TransCrate>, *mut Providers));
|
||||
__rustc_backend_provide_extern(self.backend.as_ref() as *const _, providers as *mut _);
|
||||
}
|
||||
}
|
||||
|
||||
fn trans_crate<'a, 'tcx>(
|
||||
&self,
|
||||
mut tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
rx: mpsc::Receiver<Box<Any + Send>>
|
||||
) -> Box<Any> {
|
||||
unsafe {
|
||||
get_symbol!((self.lib).__rustc_backend_trans_crate:
|
||||
unsafe extern "C" fn(
|
||||
*const Box<TransCrate>,
|
||||
*mut TyCtxt<'a, 'tcx, 'tcx>,
|
||||
*mut mpsc::Receiver<Box<Any + Send>>
|
||||
) -> *mut Box<Any>
|
||||
);
|
||||
let rx = Box::new(rx);
|
||||
*Box::from_raw(__rustc_backend_trans_crate(
|
||||
self.backend.as_ref() as *const _,
|
||||
&mut tcx as *mut _,
|
||||
Box::into_raw(rx) as *mut _
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn join_trans_and_link(
|
||||
&self,
|
||||
trans: Box<Any>,
|
||||
sess: &Session,
|
||||
dep_graph: &DepGraph,
|
||||
outputs: &OutputFilenames,
|
||||
) -> Result<(), CompileIncomplete> {
|
||||
unsafe {
|
||||
get_symbol!((self.lib).__rustc_backend_join_trans_and_link:
|
||||
unsafe extern "C" fn(
|
||||
*const Box<TransCrate>,
|
||||
*mut Box<Any>,
|
||||
*const Session,
|
||||
*const DepGraph,
|
||||
*const OutputFilenames
|
||||
) -> *mut Result<(), CompileIncomplete>
|
||||
);
|
||||
*Box::from_raw(__rustc_backend_join_trans_and_link(
|
||||
self.backend.as_ref() as *const _,
|
||||
Box::into_raw(Box::new(trans)) as *mut _,
|
||||
sess as *const _,
|
||||
dep_graph as *const _,
|
||||
outputs as *const _
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DummyTransCrate;
|
||||
|
||||
impl TransCrate for DummyTransCrate {
|
||||
|
Loading…
Reference in New Issue
Block a user