Skip to content

Commit

Permalink
librustc::plugin : make PluginLoader usable for loading argument-spec…
Browse files Browse the repository at this point in the history
…ified plugins
  • Loading branch information
Manishearth committed Jan 8, 2015
1 parent efaf613 commit 9f5f706
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/librustc/metadata/creader.rs
Expand Up @@ -516,6 +516,7 @@ impl<'a> CrateReader<'a> {
}
}

#[deriving(Copy)]
pub enum CrateOrString<'a> {
Krate(&'a ast::ViewItem),
Str(&'a str)
Expand Down
56 changes: 39 additions & 17 deletions src/librustc/plugin/load.rs
Expand Up @@ -160,6 +160,21 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
}
}

self.load_plugin(CrateOrString::Krate(vi), plugin_attr, macro_selection, reexport)
}

fn visit_mac(&mut self, _: &ast::Mac) {
// bummer... can't see plugins inside macros.
// do nothing.
}
}

impl<'a> PluginLoader<'a> {
pub fn load_plugin<'b>(&mut self,
c: CrateOrString<'b>,
plugin_attr: Option<P<ast::MetaItem>>,
macro_selection: Option<HashSet<token::InternedString>>,
reexport: HashSet<token::InternedString>) {
let mut macros = vec![];
let mut registrar = None;

Expand All @@ -169,13 +184,15 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
};
let load_registrar = plugin_attr.is_some();

if load_macros && !self.span_whitelist.contains(&vi.span) {
self.sess.span_err(vi.span, "an `extern crate` loading macros must be at \
the crate root");
}
if let CrateOrString::Krate(vi) = c {
if load_macros && !self.span_whitelist.contains(&vi.span) {
self.sess.span_err(vi.span, "an `extern crate` loading macros must be at \
the crate root");
}
}

if load_macros || load_registrar {
let pmd = self.reader.read_plugin_metadata(CrateOrString::Krate(vi));
let pmd = self.reader.read_plugin_metadata(c);
if load_macros {
macros = pmd.exported_macros();
}
Expand All @@ -195,24 +212,17 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
}

if let Some((lib, symbol)) = registrar {
let fun = self.dylink_registrar(vi, lib, symbol);
let fun = self.dylink_registrar(c, lib, symbol);
self.plugins.registrars.push(PluginRegistrar {
fun: fun,
args: plugin_attr.unwrap(),
});
}
}

fn visit_mac(&mut self, _: &ast::Mac) {
// bummer... can't see plugins inside macros.
// do nothing.
}
}

impl<'a> PluginLoader<'a> {
// Dynamically link a registrar function into the compiler process.
fn dylink_registrar(&mut self,
vi: &ast::ViewItem,
fn dylink_registrar<'b>(&mut self,
c: CrateOrString<'b>,
path: Path,
symbol: String) -> PluginRegistrarFun {
// Make sure the path contains a / or the linker will search for it.
Expand All @@ -223,7 +233,13 @@ impl<'a> PluginLoader<'a> {
// this is fatal: there are almost certainly macros we need
// inside this crate, so continue would spew "macro undefined"
// errors
Err(err) => self.sess.span_fatal(vi.span, &err[])
Err(err) => {
if let CrateOrString::Krate(cr) = c {
self.sess.span_fatal(cr.span, &err[])
} else {
self.sess.fatal(&err[])
}
}
};

unsafe {
Expand All @@ -233,7 +249,13 @@ impl<'a> PluginLoader<'a> {
mem::transmute::<*mut u8,PluginRegistrarFun>(registrar)
}
// again fatal if we can't register macros
Err(err) => self.sess.span_fatal(vi.span, &err[])
Err(err) => {
if let CrateOrString::Krate(cr) = c {
self.sess.span_fatal(cr.span, &err[])
} else {
self.sess.fatal(&err[])
}
}
};

// Intentionally leak the dynamic library. We can't ever unload it
Expand Down

0 comments on commit 9f5f706

Please sign in to comment.