-
Notifications
You must be signed in to change notification settings - Fork 14k
Allow runtime switching between trans backends #45684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
74c92c5
af0f173
2af0f0d
bd2e808
6dffaa9
9315ed4
2d241f6
ace502a
4ef16d7
d2c53f8
77dec3b
c044424
a09aebe
cc4deb2
82ac9f7
a4854e8
a30232f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,179 +77,28 @@ pub trait TransCrate { | |
| #[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)) | ||
| pub fn __rustc_backend_new($sess: &Session) -> Box<TransCrate> { | ||
| { $body } | ||
|
||
| } | ||
|
|
||
| #[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)); | ||
| 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) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| 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 _ | ||
| )) | ||
| Err(err) => { | ||
| sess.fatal(&format!("Couldnt load codegen backend {:?}: {:?}", filename, err)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, can you move that function here? I think
rustc_drivershould be the one with thelibloadingdependency.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, if you move that here you can get rid of the
libloadingdependency by usingrustc_metadata::dynamic_lib.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didnt know about
rustc_metadata::dynamic_lib.