parent
cca1cf613b
commit
6b784bacbf
@ -121,12 +121,10 @@ fn register_native_lib(sess: &Session,
|
||||
sess.cstore.add_used_library(name, kind);
|
||||
}
|
||||
|
||||
pub struct PluginMetadata<'a> {
|
||||
sess: &'a Session,
|
||||
// Extra info about a crate loaded for plugins or exported macros.
|
||||
struct ExtensionCrate {
|
||||
metadata: PMDSource,
|
||||
dylib: Option<Path>,
|
||||
info: CrateInfo,
|
||||
vi_span: Span,
|
||||
target_only: bool,
|
||||
}
|
||||
|
||||
@ -451,21 +449,7 @@ fn resolve_crate_deps(&mut self,
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn read_plugin_metadata<'b>(&'b mut self,
|
||||
krate: CrateOrString<'b>) -> PluginMetadata<'b> {
|
||||
let (info, span) = match krate {
|
||||
CrateOrString::Krate(c) => {
|
||||
(self.extract_crate_info(c).unwrap(), c.span)
|
||||
}
|
||||
CrateOrString::Str(sp, s) => {
|
||||
(CrateInfo {
|
||||
name: s.to_string(),
|
||||
ident: s.to_string(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
should_link: false,
|
||||
}, sp)
|
||||
}
|
||||
};
|
||||
fn read_extension_crate(&mut self, span: Span, info: &CrateInfo) -> ExtensionCrate {
|
||||
let target_triple = &self.sess.opts.target_triple[];
|
||||
let is_cross = target_triple != config::host_triple();
|
||||
let mut should_link = info.should_link && !is_cross;
|
||||
@ -517,30 +501,21 @@ pub fn read_plugin_metadata<'b>(&'b mut self,
|
||||
PMDSource::Owned(library.metadata)
|
||||
};
|
||||
|
||||
PluginMetadata {
|
||||
sess: self.sess,
|
||||
ExtensionCrate {
|
||||
metadata: metadata,
|
||||
dylib: dylib.map(|p| p.0),
|
||||
info: info,
|
||||
vi_span: span,
|
||||
target_only: target_only,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy)]
|
||||
pub enum CrateOrString<'a> {
|
||||
Krate(&'a ast::Item),
|
||||
Str(Span, &'a str)
|
||||
}
|
||||
/// Read exported macros.
|
||||
pub fn read_exported_macros(&mut self, krate: &ast::Item) -> Vec<ast::MacroDef> {
|
||||
let ci = self.extract_crate_info(krate).unwrap();
|
||||
let ekrate = self.read_extension_crate(krate.span, &ci);
|
||||
|
||||
impl<'a> PluginMetadata<'a> {
|
||||
/// Read exported macros
|
||||
pub fn exported_macros(&self) -> Vec<ast::MacroDef> {
|
||||
let imported_from = Some(token::intern(&self.info.ident[]).ident());
|
||||
let source_name = format!("<{} macros>", &self.info.ident[]);
|
||||
let source_name = format!("<{} macros>", krate.ident);
|
||||
let mut macros = vec![];
|
||||
decoder::each_exported_macro(self.metadata.as_slice(),
|
||||
decoder::each_exported_macro(ekrate.metadata.as_slice(),
|
||||
&*self.sess.cstore.intr,
|
||||
|name, attrs, body| {
|
||||
// NB: Don't use parse::parse_tts_from_source_str because it parses with
|
||||
@ -558,7 +533,7 @@ pub fn exported_macros(&self) -> Vec<ast::MacroDef> {
|
||||
attrs: attrs,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: span,
|
||||
imported_from: imported_from,
|
||||
imported_from: Some(krate.ident),
|
||||
// overridden in plugin/load.rs
|
||||
export: false,
|
||||
use_locally: false,
|
||||
@ -572,28 +547,35 @@ pub fn exported_macros(&self) -> Vec<ast::MacroDef> {
|
||||
}
|
||||
|
||||
/// Look for a plugin registrar. Returns library path and symbol name.
|
||||
pub fn plugin_registrar(&self) -> Option<(Path, String)> {
|
||||
if self.target_only {
|
||||
pub fn find_plugin_registrar(&mut self, span: Span, name: &str) -> Option<(Path, String)> {
|
||||
let ekrate = self.read_extension_crate(span, &CrateInfo {
|
||||
name: name.to_string(),
|
||||
ident: name.to_string(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
should_link: false,
|
||||
});
|
||||
|
||||
if ekrate.target_only {
|
||||
// Need to abort before syntax expansion.
|
||||
let message = format!("plugin crate `{}` is not available for triple `{}` \
|
||||
let message = format!("plugin `{}` is not available for triple `{}` \
|
||||
(only found {})",
|
||||
self.info.ident,
|
||||
name,
|
||||
config::host_triple(),
|
||||
self.sess.opts.target_triple);
|
||||
self.sess.span_err(self.vi_span, &message[]);
|
||||
self.sess.span_err(span, &message[]);
|
||||
self.sess.abort_if_errors();
|
||||
}
|
||||
|
||||
let registrar = decoder::get_plugin_registrar_fn(self.metadata.as_slice())
|
||||
.map(|id| decoder::get_symbol(self.metadata.as_slice(), id));
|
||||
let registrar = decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice())
|
||||
.map(|id| decoder::get_symbol(ekrate.metadata.as_slice(), id));
|
||||
|
||||
match (self.dylib.as_ref(), registrar) {
|
||||
match (ekrate.dylib.as_ref(), registrar) {
|
||||
(Some(dylib), Some(reg)) => Some((dylib.clone(), reg)),
|
||||
(None, Some(_)) => {
|
||||
let message = format!("plugin crate `{}` only found in rlib format, \
|
||||
let message = format!("plugin `{}` only found in rlib format, \
|
||||
but must be available in dylib format",
|
||||
self.info.ident);
|
||||
self.sess.span_err(self.vi_span, &message[]);
|
||||
name);
|
||||
self.sess.span_err(span, &message[]);
|
||||
// No need to abort because the loading code will just ignore this
|
||||
// empty dylib.
|
||||
None
|
||||
|
@ -11,7 +11,7 @@
|
||||
//! Used by `rustc` when loading a plugin, or a crate with exported macros.
|
||||
|
||||
use session::Session;
|
||||
use metadata::creader::{CrateOrString, CrateReader};
|
||||
use metadata::creader::CrateReader;
|
||||
use plugin::registry::Registry;
|
||||
|
||||
use std::mem;
|
||||
@ -102,14 +102,13 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
|
||||
}
|
||||
|
||||
let args = plugin.meta_item_list().map(ToOwned::to_owned).unwrap_or_default();
|
||||
loader.load_plugin(CrateOrString::Str(plugin.span, &*plugin.name()),
|
||||
args);
|
||||
loader.load_plugin(plugin.span, &*plugin.name(), args);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(plugins) = addl_plugins {
|
||||
for plugin in plugins {
|
||||
loader.load_plugin(CrateOrString::Str(COMMAND_LINE_SP, &plugin), vec![]);
|
||||
loader.load_plugin(COMMAND_LINE_SP, &plugin, vec![]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,10 +210,10 @@ pub fn load_macros<'b>(&mut self,
|
||||
return;
|
||||
}
|
||||
|
||||
let pmd = self.reader.read_plugin_metadata(CrateOrString::Krate(vi));
|
||||
|
||||
let macros = self.reader.read_exported_macros(vi);
|
||||
let mut seen = HashSet::new();
|
||||
for mut def in pmd.exported_macros() {
|
||||
|
||||
for mut def in macros {
|
||||
let name = token::get_ident(def.ident);
|
||||
seen.insert(name.clone());
|
||||
|
||||
@ -241,16 +240,11 @@ pub fn load_macros<'b>(&mut self,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_plugin<'b>(&mut self,
|
||||
c: CrateOrString<'b>,
|
||||
args: Vec<P<ast::MetaItem>>) {
|
||||
let registrar = {
|
||||
let pmd = self.reader.read_plugin_metadata(c);
|
||||
pmd.plugin_registrar()
|
||||
};
|
||||
pub 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 {
|
||||
let fun = self.dylink_registrar(c, lib, symbol);
|
||||
let fun = self.dylink_registrar(span, lib, symbol);
|
||||
self.plugins.registrars.push(PluginRegistrar {
|
||||
fun: fun,
|
||||
args: args,
|
||||
@ -259,8 +253,8 @@ pub fn load_plugin<'b>(&mut self,
|
||||
}
|
||||
|
||||
// Dynamically link a registrar function into the compiler process.
|
||||
fn dylink_registrar<'b>(&mut self,
|
||||
c: CrateOrString<'b>,
|
||||
fn dylink_registrar(&mut self,
|
||||
span: Span,
|
||||
path: Path,
|
||||
symbol: String) -> PluginRegistrarFun {
|
||||
// Make sure the path contains a / or the linker will search for it.
|
||||
@ -272,11 +266,7 @@ fn dylink_registrar<'b>(&mut self,
|
||||
// inside this crate, so continue would spew "macro undefined"
|
||||
// errors
|
||||
Err(err) => {
|
||||
if let CrateOrString::Krate(cr) = c {
|
||||
self.sess.span_fatal(cr.span, &err[])
|
||||
} else {
|
||||
self.sess.fatal(&err[])
|
||||
}
|
||||
self.sess.span_fatal(span, &err[])
|
||||
}
|
||||
};
|
||||
|
||||
@ -288,11 +278,7 @@ fn dylink_registrar<'b>(&mut self,
|
||||
}
|
||||
// again fatal if we can't register macros
|
||||
Err(err) => {
|
||||
if let CrateOrString::Krate(cr) = c {
|
||||
self.sess.span_fatal(cr.span, &err[])
|
||||
} else {
|
||||
self.sess.fatal(&err[])
|
||||
}
|
||||
self.sess.span_fatal(span, &err[])
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,6 @@
|
||||
|
||||
#![feature(plugin)]
|
||||
#![plugin(rlib_crate_test)]
|
||||
//~^ ERROR: plugin crate `rlib_crate_test` only found in rlib format, but must be available in dylib format
|
||||
//~^ ERROR: plugin `rlib_crate_test` only found in rlib format, but must be available in dylib format
|
||||
|
||||
fn main() {}
|
||||
|
Loading…
Reference in New Issue
Block a user