rustc: use a simpler scheme for plugin registrar symbol names.

This commit is contained in:
Eduard Burtescu 2016-05-10 23:21:18 +03:00
parent dd6e8d45e1
commit 7462da5c38
5 changed files with 27 additions and 14 deletions

View File

@ -9,6 +9,8 @@
// except according to those terms.
use dep_graph::DepGraph;
use hir::def_id::DefIndex;
use hir::svh::Svh;
use lint;
use middle::cstore::CrateStore;
use middle::dependency_format;
@ -312,6 +314,14 @@ impl Session {
pub fn nonzeroing_move_hints(&self) -> bool {
self.opts.debugging_opts.enable_nonzeroing_move_hints
}
/// Returns the symbol name for the registrar function,
/// given the crate Svh and the function DefIndex.
pub fn generate_plugin_registrar_symbol(&self, svh: &Svh, index: DefIndex)
-> String {
format!("__rustc_plugin_registrar__{}_{}", svh, index.as_usize())
}
pub fn sysroot<'a>(&'a self) -> &'a Path {
match self.opts.maybe_sysroot {
Some (ref sysroot) => sysroot,

View File

@ -17,6 +17,7 @@ use cstore::{self, CStore, CrateSource, MetadataBlob};
use decoder;
use loader::{self, CratePaths};
use rustc::hir::def_id::DefIndex;
use rustc::hir::svh::Svh;
use rustc::dep_graph::{DepGraph, DepNode};
use rustc::session::{config, Session};
@ -610,9 +611,10 @@ impl<'a> CrateReader<'a> {
macros
}
/// Look for a plugin registrar. Returns library path and symbol name.
/// Look for a plugin registrar. Returns library path, crate
/// SVH and DefIndex of the registrar function.
pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
-> Option<(PathBuf, String)> {
-> Option<(PathBuf, Svh, DefIndex)> {
let ekrate = self.read_extension_crate(span, &CrateInfo {
name: name.to_string(),
ident: name.to_string(),
@ -630,12 +632,14 @@ impl<'a> CrateReader<'a> {
span_fatal!(self.sess, span, E0456, "{}", &message[..]);
}
let svh = decoder::get_crate_hash(ekrate.metadata.as_slice());
let registrar =
decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice())
.map(|id| decoder::get_symbol_from_buf(ekrate.metadata.as_slice(), id));
decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice());
match (ekrate.dylib.as_ref(), registrar) {
(Some(dylib), Some(reg)) => Some((dylib.to_path_buf(), reg)),
(Some(dylib), Some(reg)) => {
Some((dylib.to_path_buf(), svh, reg))
}
(None, Some(_)) => {
span_err!(self.sess, span, E0457,
"plugin `{}` only found in rlib format, but must be available \

View File

@ -644,14 +644,6 @@ pub fn get_symbol(cdata: Cmd, id: DefIndex) -> String {
return item_symbol(cdata.lookup_item(id));
}
/// If you have a crate_metadata, call get_symbol instead
pub fn get_symbol_from_buf(data: &[u8], id: DefIndex) -> String {
let index = load_index(data);
let pos = index.lookup_item(data, id).unwrap();
let doc = reader::doc_at(data, pos as usize).unwrap().doc;
item_symbol(doc)
}
/// Iterates over the language items in the given crate.
pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
F: FnMut(DefIndex, usize) -> bool,

View File

@ -101,7 +101,8 @@ impl<'a> PluginLoader<'a> {
fn load_plugin(&mut self, span: Span, name: &str, args: Vec<P<ast::MetaItem>>) {
let registrar = self.reader.find_plugin_registrar(span, name);
if let Some((lib, symbol)) = registrar {
if let Some((lib, svh, index)) = registrar {
let symbol = self.sess.generate_plugin_registrar_symbol(&svh, index);
let fun = self.dylink_registrar(span, lib, symbol);
self.plugins.push(PluginRegistrar {
fun: fun,

View File

@ -2443,6 +2443,12 @@ pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-> String {
let id = ccx.tcx().map.as_local_node_id(instance.def).unwrap();
if ccx.sess().plugin_registrar_fn.get() == Some(id) {
let svh = &ccx.link_meta().crate_hash;
let idx = instance.def.index;
return ccx.sess().generate_plugin_registrar_symbol(svh, idx);
}
match ccx.external_srcs().borrow().get(&id) {
Some(&did) => {
let sym = ccx.sess().cstore.item_symbol(did);