version = "0.0.0"
dependencies = [
"rustc 0.0.0",
- "rustc_back 0.0.0",
"rustc_errors 0.0.0",
"rustc_metadata 0.0.0",
"syntax 0.0.0",
+++ /dev/null
-// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Dynamic library facilities.
-//!
-//! A simple wrapper over the platform's dynamic library facilities
-
-use std::ffi::CString;
-use std::path::Path;
-
-pub struct DynamicLibrary {
- handle: *mut u8
-}
-
-impl Drop for DynamicLibrary {
- fn drop(&mut self) {
- unsafe {
- dl::close(self.handle)
- }
- }
-}
-
-impl DynamicLibrary {
- /// Lazily open a dynamic library. When passed None it gives a
- /// handle to the calling process
- pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
- let maybe_library = dl::open(filename.map(|path| path.as_os_str()));
-
- // The dynamic library must not be constructed if there is
- // an error opening the library so the destructor does not
- // run.
- match maybe_library {
- Err(err) => Err(err),
- Ok(handle) => Ok(DynamicLibrary { handle: handle })
- }
- }
-
- /// Returns the environment variable for this process's dynamic library
- /// search path
- pub fn envvar() -> &'static str {
- if cfg!(windows) {
- "PATH"
- } else if cfg!(target_os = "macos") {
- "DYLD_LIBRARY_PATH"
- } else if cfg!(target_os = "haiku") {
- "LIBRARY_PATH"
- } else {
- "LD_LIBRARY_PATH"
- }
- }
-
- /// Accesses the value at the symbol of the dynamic library.
- pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
- // This function should have a lifetime constraint of 'a on
- // T but that feature is still unimplemented
-
- let raw_string = CString::new(symbol).unwrap();
- let maybe_symbol_value = dl::symbol(self.handle, raw_string.as_ptr());
-
- // The value must not be constructed if there is an error so
- // the destructor does not run.
- match maybe_symbol_value {
- Err(err) => Err(err),
- Ok(symbol_value) => Ok(symbol_value as *mut T)
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use libc;
- use std::mem;
-
- #[test]
- fn test_loading_cosine() {
- if cfg!(windows) {
- return
- }
-
- // The math library does not need to be loaded since it is already
- // statically linked in
- let libm = match DynamicLibrary::open(None) {
- Err(error) => panic!("Could not load self as module: {}", error),
- Ok(libm) => libm
- };
-
- let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
- match libm.symbol("cos") {
- Err(error) => panic!("Could not load function cos: {}", error),
- Ok(cosine) => mem::transmute::<*mut u8, _>(cosine)
- }
- };
-
- let argument = 0.0;
- let expected_result = 1.0;
- let result = cosine(argument);
- if result != expected_result {
- panic!("cos({}) != {} but equaled {} instead", argument,
- expected_result, result)
- }
- }
-
- #[test]
- fn test_errors_do_not_crash() {
- use std::path::Path;
-
- if !cfg!(unix) {
- return
- }
-
- // Open /dev/null as a library to get an error, and make sure
- // that only causes an error, and not a crash.
- let path = Path::new("/dev/null");
- match DynamicLibrary::open(Some(&path)) {
- Err(_) => {}
- Ok(_) => panic!("Successfully opened the empty library.")
- }
- }
-}
-
-#[cfg(unix)]
-mod dl {
- use libc;
- use std::ffi::{CStr, OsStr, CString};
- use std::os::unix::prelude::*;
- use std::ptr;
- use std::str;
-
- pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
- check_for_errors_in(|| {
- unsafe {
- match filename {
- Some(filename) => open_external(filename),
- None => open_internal(),
- }
- }
- })
- }
-
- const LAZY: libc::c_int = 1;
-
- unsafe fn open_external(filename: &OsStr) -> *mut u8 {
- let s = CString::new(filename.as_bytes()).unwrap();
- libc::dlopen(s.as_ptr(), LAZY) as *mut u8
- }
-
- unsafe fn open_internal() -> *mut u8 {
- libc::dlopen(ptr::null(), LAZY) as *mut u8
- }
-
- pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
- F: FnOnce() -> T,
- {
- use std::sync::{Mutex, Once, ONCE_INIT};
- static INIT: Once = ONCE_INIT;
- static mut LOCK: *mut Mutex<()> = 0 as *mut _;
- unsafe {
- INIT.call_once(|| {
- LOCK = Box::into_raw(Box::new(Mutex::new(())));
- });
- // dlerror isn't thread safe, so we need to lock around this entire
- // sequence
- let _guard = (*LOCK).lock();
- let _old_error = libc::dlerror();
-
- let result = f();
-
- let last_error = libc::dlerror() as *const _;
- let ret = if ptr::null() == last_error {
- Ok(result)
- } else {
- let s = CStr::from_ptr(last_error).to_bytes();
- Err(str::from_utf8(s).unwrap().to_owned())
- };
-
- ret
- }
- }
-
- pub unsafe fn symbol(handle: *mut u8,
- symbol: *const libc::c_char)
- -> Result<*mut u8, String> {
- check_for_errors_in(|| {
- libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8
- })
- }
- pub unsafe fn close(handle: *mut u8) {
- libc::dlclose(handle as *mut libc::c_void); ()
- }
-}
-
-#[cfg(windows)]
-mod dl {
- use std::ffi::OsStr;
- use std::io;
- use std::os::windows::prelude::*;
- use std::ptr;
-
- use libc::{c_uint, c_void, c_char};
-
- type DWORD = u32;
- type HMODULE = *mut u8;
- type BOOL = i32;
- type LPCWSTR = *const u16;
- type LPCSTR = *const i8;
-
- extern "system" {
- fn SetThreadErrorMode(dwNewMode: DWORD,
- lpOldMode: *mut DWORD) -> c_uint;
- fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
- fn GetModuleHandleExW(dwFlags: DWORD,
- name: LPCWSTR,
- handle: *mut HMODULE) -> BOOL;
- fn GetProcAddress(handle: HMODULE,
- name: LPCSTR) -> *mut c_void;
- fn FreeLibrary(handle: HMODULE) -> BOOL;
- }
-
- pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
- // disable "dll load failed" error dialog.
- let prev_error_mode = unsafe {
- // SEM_FAILCRITICALERRORS 0x01
- let new_error_mode = 1;
- let mut prev_error_mode = 0;
- let result = SetThreadErrorMode(new_error_mode,
- &mut prev_error_mode);
- if result == 0 {
- return Err(io::Error::last_os_error().to_string())
- }
- prev_error_mode
- };
-
- let result = match filename {
- Some(filename) => {
- let filename_str: Vec<_> =
- filename.encode_wide().chain(Some(0)).collect();
- let result = unsafe {
- LoadLibraryW(filename_str.as_ptr())
- };
- ptr_result(result)
- }
- None => {
- let mut handle = ptr::null_mut();
- let succeeded = unsafe {
- GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle)
- };
- if succeeded == 0 {
- Err(io::Error::last_os_error().to_string())
- } else {
- Ok(handle as *mut u8)
- }
- }
- };
-
- unsafe {
- SetThreadErrorMode(prev_error_mode, ptr::null_mut());
- }
-
- result
- }
-
- pub unsafe fn symbol(handle: *mut u8,
- symbol: *const c_char)
- -> Result<*mut u8, String> {
- let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8;
- ptr_result(ptr)
- }
-
- pub unsafe fn close(handle: *mut u8) {
- FreeLibrary(handle as HMODULE);
- }
-
- fn ptr_result<T>(ptr: *mut T) -> Result<*mut T, String> {
- if ptr.is_null() {
- Err(io::Error::last_os_error().to_string())
- } else {
- Ok(ptr)
- }
- }
-}
#![feature(box_syntax)]
#![feature(const_fn)]
-#![feature(libc)]
extern crate syntax;
-extern crate libc;
extern crate rand;
extern crate serialize;
#[macro_use] extern crate log;
pub mod tempdir;
pub mod target;
-pub mod dynamic_lib;
use std::str::FromStr;
use std::{env, mem};
use proc_macro::TokenStream;
use proc_macro::__internal::Registry;
- use rustc_back::dynamic_lib::DynamicLibrary;
+ use dynamic_lib::DynamicLibrary;
use syntax_ext::deriving::custom::ProcMacroDerive;
use syntax_ext::proc_macro_impl::{AttrProcMacro, BangProcMacro};
--- /dev/null
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Dynamic library facilities.
+//!
+//! A simple wrapper over the platform's dynamic library facilities
+
+use std::ffi::CString;
+use std::path::Path;
+
+pub struct DynamicLibrary {
+ handle: *mut u8
+}
+
+impl Drop for DynamicLibrary {
+ fn drop(&mut self) {
+ unsafe {
+ dl::close(self.handle)
+ }
+ }
+}
+
+impl DynamicLibrary {
+ /// Lazily open a dynamic library. When passed None it gives a
+ /// handle to the calling process
+ pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
+ let maybe_library = dl::open(filename.map(|path| path.as_os_str()));
+
+ // The dynamic library must not be constructed if there is
+ // an error opening the library so the destructor does not
+ // run.
+ match maybe_library {
+ Err(err) => Err(err),
+ Ok(handle) => Ok(DynamicLibrary { handle: handle })
+ }
+ }
+
+ /// Returns the environment variable for this process's dynamic library
+ /// search path
+ pub fn envvar() -> &'static str {
+ if cfg!(windows) {
+ "PATH"
+ } else if cfg!(target_os = "macos") {
+ "DYLD_LIBRARY_PATH"
+ } else if cfg!(target_os = "haiku") {
+ "LIBRARY_PATH"
+ } else {
+ "LD_LIBRARY_PATH"
+ }
+ }
+
+ /// Accesses the value at the symbol of the dynamic library.
+ pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
+ // This function should have a lifetime constraint of 'a on
+ // T but that feature is still unimplemented
+
+ let raw_string = CString::new(symbol).unwrap();
+ let maybe_symbol_value = dl::symbol(self.handle, raw_string.as_ptr());
+
+ // The value must not be constructed if there is an error so
+ // the destructor does not run.
+ match maybe_symbol_value {
+ Err(err) => Err(err),
+ Ok(symbol_value) => Ok(symbol_value as *mut T)
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use libc;
+ use std::mem;
+
+ #[test]
+ fn test_loading_cosine() {
+ if cfg!(windows) {
+ return
+ }
+
+ // The math library does not need to be loaded since it is already
+ // statically linked in
+ let libm = match DynamicLibrary::open(None) {
+ Err(error) => panic!("Could not load self as module: {}", error),
+ Ok(libm) => libm
+ };
+
+ let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
+ match libm.symbol("cos") {
+ Err(error) => panic!("Could not load function cos: {}", error),
+ Ok(cosine) => mem::transmute::<*mut u8, _>(cosine)
+ }
+ };
+
+ let argument = 0.0;
+ let expected_result = 1.0;
+ let result = cosine(argument);
+ if result != expected_result {
+ panic!("cos({}) != {} but equaled {} instead", argument,
+ expected_result, result)
+ }
+ }
+
+ #[test]
+ fn test_errors_do_not_crash() {
+ use std::path::Path;
+
+ if !cfg!(unix) {
+ return
+ }
+
+ // Open /dev/null as a library to get an error, and make sure
+ // that only causes an error, and not a crash.
+ let path = Path::new("/dev/null");
+ match DynamicLibrary::open(Some(&path)) {
+ Err(_) => {}
+ Ok(_) => panic!("Successfully opened the empty library.")
+ }
+ }
+}
+
+#[cfg(unix)]
+mod dl {
+ use libc;
+ use std::ffi::{CStr, OsStr, CString};
+ use std::os::unix::prelude::*;
+ use std::ptr;
+ use std::str;
+
+ pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
+ check_for_errors_in(|| {
+ unsafe {
+ match filename {
+ Some(filename) => open_external(filename),
+ None => open_internal(),
+ }
+ }
+ })
+ }
+
+ const LAZY: libc::c_int = 1;
+
+ unsafe fn open_external(filename: &OsStr) -> *mut u8 {
+ let s = CString::new(filename.as_bytes()).unwrap();
+ libc::dlopen(s.as_ptr(), LAZY) as *mut u8
+ }
+
+ unsafe fn open_internal() -> *mut u8 {
+ libc::dlopen(ptr::null(), LAZY) as *mut u8
+ }
+
+ pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
+ F: FnOnce() -> T,
+ {
+ use std::sync::{Mutex, Once, ONCE_INIT};
+ static INIT: Once = ONCE_INIT;
+ static mut LOCK: *mut Mutex<()> = 0 as *mut _;
+ unsafe {
+ INIT.call_once(|| {
+ LOCK = Box::into_raw(Box::new(Mutex::new(())));
+ });
+ // dlerror isn't thread safe, so we need to lock around this entire
+ // sequence
+ let _guard = (*LOCK).lock();
+ let _old_error = libc::dlerror();
+
+ let result = f();
+
+ let last_error = libc::dlerror() as *const _;
+ let ret = if ptr::null() == last_error {
+ Ok(result)
+ } else {
+ let s = CStr::from_ptr(last_error).to_bytes();
+ Err(str::from_utf8(s).unwrap().to_owned())
+ };
+
+ ret
+ }
+ }
+
+ pub unsafe fn symbol(handle: *mut u8,
+ symbol: *const libc::c_char)
+ -> Result<*mut u8, String> {
+ check_for_errors_in(|| {
+ libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8
+ })
+ }
+ pub unsafe fn close(handle: *mut u8) {
+ libc::dlclose(handle as *mut libc::c_void); ()
+ }
+}
+
+#[cfg(windows)]
+mod dl {
+ use std::ffi::OsStr;
+ use std::io;
+ use std::os::windows::prelude::*;
+ use std::ptr;
+
+ use libc::{c_uint, c_void, c_char};
+
+ type DWORD = u32;
+ type HMODULE = *mut u8;
+ type BOOL = i32;
+ type LPCWSTR = *const u16;
+ type LPCSTR = *const i8;
+
+ extern "system" {
+ fn SetThreadErrorMode(dwNewMode: DWORD,
+ lpOldMode: *mut DWORD) -> c_uint;
+ fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
+ fn GetModuleHandleExW(dwFlags: DWORD,
+ name: LPCWSTR,
+ handle: *mut HMODULE) -> BOOL;
+ fn GetProcAddress(handle: HMODULE,
+ name: LPCSTR) -> *mut c_void;
+ fn FreeLibrary(handle: HMODULE) -> BOOL;
+ }
+
+ pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
+ // disable "dll load failed" error dialog.
+ let prev_error_mode = unsafe {
+ // SEM_FAILCRITICALERRORS 0x01
+ let new_error_mode = 1;
+ let mut prev_error_mode = 0;
+ let result = SetThreadErrorMode(new_error_mode,
+ &mut prev_error_mode);
+ if result == 0 {
+ return Err(io::Error::last_os_error().to_string())
+ }
+ prev_error_mode
+ };
+
+ let result = match filename {
+ Some(filename) => {
+ let filename_str: Vec<_> =
+ filename.encode_wide().chain(Some(0)).collect();
+ let result = unsafe {
+ LoadLibraryW(filename_str.as_ptr())
+ };
+ ptr_result(result)
+ }
+ None => {
+ let mut handle = ptr::null_mut();
+ let succeeded = unsafe {
+ GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle)
+ };
+ if succeeded == 0 {
+ Err(io::Error::last_os_error().to_string())
+ } else {
+ Ok(handle as *mut u8)
+ }
+ }
+ };
+
+ unsafe {
+ SetThreadErrorMode(prev_error_mode, ptr::null_mut());
+ }
+
+ result
+ }
+
+ pub unsafe fn symbol(handle: *mut u8,
+ symbol: *const c_char)
+ -> Result<*mut u8, String> {
+ let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8;
+ ptr_result(ptr)
+ }
+
+ pub unsafe fn close(handle: *mut u8) {
+ FreeLibrary(handle as HMODULE);
+ }
+
+ fn ptr_result<T>(ptr: *mut T) -> Result<*mut T, String> {
+ if ptr.is_null() {
+ Err(io::Error::last_os_error().to_string())
+ } else {
+ Ok(ptr)
+ }
+ }
+}
#![feature(box_patterns)]
#![feature(conservative_impl_trait)]
#![feature(i128_type)]
+#![feature(libc)]
#![feature(proc_macro_internals)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(specialization)]
#![feature(rustc_private)]
+extern crate libc;
#[macro_use]
extern crate log;
#[macro_use]
pub mod creader;
pub mod cstore;
+pub mod dynamic_lib;
pub mod locator;
__build_diagnostic_array! { librustc_metadata, DIAGNOSTICS }
[dependencies]
rustc = { path = "../librustc" }
-rustc_back = { path = "../librustc_back" }
rustc_metadata = { path = "../librustc_metadata" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
#[macro_use] extern crate syntax;
extern crate rustc;
-extern crate rustc_back;
extern crate rustc_metadata;
extern crate syntax_pos;
extern crate rustc_errors as errors;
span: Span,
path: PathBuf,
symbol: String) -> PluginRegistrarFun {
- use rustc_back::dynamic_lib::DynamicLibrary;
+ use rustc_metadata::dynamic_lib::DynamicLibrary;
// Make sure the path contains a / or the linker will search for it.
let path = env::current_dir().unwrap().join(&path);
use std::string::String;
use std::path::PathBuf;
-use rustc_back::dynamic_lib as dl;
+use rustc_metadata::dynamic_lib as dl;
pub type PluginResult = clean::Crate;
pub type PluginCallback = fn (clean::Crate) -> PluginResult;
use rustc::session::{self, CompileIncomplete, config};
use rustc::session::config::{OutputType, OutputTypes, Externs};
use rustc::session::search_paths::{SearchPaths, PathKind};
-use rustc_back::dynamic_lib::DynamicLibrary;
+use rustc_metadata::dynamic_lib::DynamicLibrary;
use rustc_back::tempdir::TempDir;
use rustc_driver::{self, driver, Compilation};
use rustc_driver::driver::phase_2_configure_and_expand;
#![feature(rustc_private)]
-extern crate rustc_back;
+extern crate rustc_metadata;
-use rustc_back::dynamic_lib::DynamicLibrary;
+use rustc_metadata::dynamic_lib::DynamicLibrary;
use std::path::Path;
pub fn main() {
// do the runtime check that these functions aren't exported.
#![allow(private_no_mangle_fns)]
-extern crate rustc_back;
+extern crate rustc_metadata;
-use rustc_back::dynamic_lib::DynamicLibrary;
+use rustc_metadata::dynamic_lib::DynamicLibrary;
#[no_mangle]
pub fn foo() { bar(); }