Reduce allocations when looking up proc macro decl

This commit is contained in:
Laurențiu Nicola 2020-04-17 11:12:05 +03:00
parent 8d296be109
commit 02b96d522c

View file

@ -16,55 +16,53 @@ fn invalid_data_err(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> I
IoError::new(IoErrorKind::InvalidData, e) IoError::new(IoErrorKind::InvalidData, e)
} }
fn get_symbols_from_lib(file: &Path) -> Result<Vec<String>, IoError> { fn is_derive_registrar_symbol(symbol: &str) -> bool {
symbol.contains(NEW_REGISTRAR_SYMBOL)
}
fn find_registrar_symbol(file: &Path) -> Result<Option<String>, IoError> {
let buffer = std::fs::read(file)?; let buffer = std::fs::read(file)?;
let object = Object::parse(&buffer).map_err(invalid_data_err)?; let object = Object::parse(&buffer).map_err(invalid_data_err)?;
match object { match object {
Object::Elf(elf) => { Object::Elf(elf) => {
let symbols = elf.dynstrtab.to_vec().map_err(invalid_data_err)?; let symbols = elf.dynstrtab.to_vec().map_err(invalid_data_err)?;
let names = symbols.iter().map(|s| s.to_string()).collect(); let name =
Ok(names) symbols.iter().find(|s| is_derive_registrar_symbol(s)).map(|s| s.to_string());
Ok(name)
} }
Object::PE(pe) => { Object::PE(pe) => {
let symbol_names = let name = pe
pe.exports.iter().flat_map(|s| s.name).map(|n| n.to_string()).collect(); .exports
Ok(symbol_names) .iter()
.flat_map(|s| s.name)
.find(|s| is_derive_registrar_symbol(s))
.map(|s| s.to_string());
Ok(name)
} }
Object::Mach(mach) => match mach { Object::Mach(Mach::Binary(binary)) => {
Mach::Binary(binary) => { let exports = binary.exports().map_err(invalid_data_err)?;
let exports = binary.exports().map_err(invalid_data_err)?; let name = exports
let names = exports .iter()
.into_iter() .map(|s| {
.map(|s| { // In macos doc:
// In macos doc: // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be
// Unlike other dyld API's, the symbol name passed to dlsym() must NOT be // prepended with an underscore.
// prepended with an underscore. if s.name.starts_with("_") {
if s.name.starts_with("_") { &s.name[1..]
s.name[1..].to_string() } else {
} else { &s.name
s.name }
} })
}) .find(|s| is_derive_registrar_symbol(&s))
.collect(); .map(|s| s.to_string());
Ok(names) Ok(name)
} }
Mach::Fat(_) => Ok(vec![]), _ => Ok(None),
},
Object::Archive(_) | Object::Unknown(_) => Ok(vec![]),
} }
} }
fn is_derive_registrar_symbol(symbol: &str) -> bool {
symbol.contains(NEW_REGISTRAR_SYMBOL)
}
fn find_registrar_symbol(file: &Path) -> Result<Option<String>, IoError> {
let symbols = get_symbols_from_lib(file)?;
Ok(symbols.into_iter().find(|s| is_derive_registrar_symbol(s)))
}
/// Loads dynamic library in platform dependent manner. /// Loads dynamic library in platform dependent manner.
/// ///
/// For unix, you have to use RTLD_DEEPBIND flag to escape problems described /// For unix, you have to use RTLD_DEEPBIND flag to escape problems described