Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gccjit"
version = "3.0.0"
version = "3.1.0"
authors = ["Sean Gillespie <[email protected]>", "Antoni Boucher <[email protected]>"]
description = "Higher-level Rust bindings for libgccjit."
keywords = ["compiler", "jit", "gcc"]
Expand All @@ -14,7 +14,7 @@ master = ["gccjit_sys/master"]
dlopen = ["gccjit_sys/dlopen"]

[dependencies]
gccjit_sys = { version = "1.0.0", path = "gccjit_sys" }
gccjit_sys = { version = "1.1.0", path = "gccjit_sys" }

[package.metadata.docs.rs]
features = ["master"]
2 changes: 1 addition & 1 deletion gccjit_sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "gccjit_sys"
version = "1.0.0"
version = "1.1.0"
authors = ["Sean Gillespie <[email protected]>", "Antoni Boucher <[email protected]>"]
#links = "gccjit"
description = "Raw bindings to libgccjit. Companion to the gccjit crate."
Expand Down
36 changes: 23 additions & 13 deletions gccjit_sys/src/dynload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ pub use self::platform::Library;

#[cfg(unix)]
mod platform {
use std::ffi::{CStr, c_int, c_void};
use std::ffi::{CStr, c_char, c_int, c_void};

#[link(name="dl")]
extern "C" {
fn dlopen(filename: *const i8, flag: c_int) -> *mut c_void;
fn dlsym(handle: *mut c_void, symbol: *const i8) -> *mut c_void;
fn dlclose(handle: *mut c_void) -> c_int;
fn dlerror() -> *const c_char;
}

pub struct Library(*mut c_void);
Expand All @@ -19,26 +20,35 @@ mod platform {
unsafe impl Sync for Library {}

impl Library {
pub unsafe fn open(path: &CStr) -> Option<Self> {
pub unsafe fn open(path: &CStr) -> Result<Self, String> {
const RTLD_NOW: c_int = 2;
let handle = dlopen(path.as_ptr(), RTLD_NOW);
if handle.is_null() {
None
Self::error()
}
else {
Some(Self(handle))
Ok(Self(handle))
}
}

pub unsafe fn get(&self, sym: &CStr) -> Option<*mut ()> {
pub unsafe fn get(&self, sym: &CStr) -> Result<*mut (), String> {
let ptr = dlsym(self.0, sym.as_ptr());
if ptr.is_null() {
None
Self::error()
}
else {
Some(ptr.cast())
Ok(ptr.cast())
}
}

unsafe fn error<T>() -> Result<T, String> {
let cstr = dlerror();
let cstr = CStr::from_ptr(cstr);
let string = cstr.to_str()
.map_err(|error| error.to_string())?
.to_string();
Err(string)
}
}

impl Drop for Library {
Expand Down Expand Up @@ -66,26 +76,26 @@ mod platform {
unsafe impl Sync for Library {}

impl Library {
pub unsafe fn open(path: &CStr) -> Option<Self> {
pub unsafe fn open(path: &CStr) -> Result<Self, String> {
let path = path.to_str().unwrap();
let path = OsString::from(path);
let w: Vec<u16> = path.encode_wide().collect();
let handle = LoadLibraryW(w.as_ptr());
if handle.is_null() {
None
Err("cannot load library".to_string())
}
else {
Some(Self(handle))
Ok(Self(handle))
}
}

pub unsafe fn get(&self, sym: &CStr) -> Option<*mut ()> {
pub unsafe fn get(&self, sym: &CStr) -> Result<*mut (), String> {
let ptr = GetProcAddress(self.0, sym.as_ptr() as *const _);
if ptr.is_null() {
None
Some("cannot load symbol".to_string())
}
else {
Some(ptr.cast())
Ok(ptr.cast())
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions gccjit_sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,15 +338,15 @@ macro_rules! extern_maybe_dlopen {
}

#[cfg(feature="dlopen")]
pub unsafe fn open(path: &CStr) -> Option<Self> {
pub unsafe fn open(path: &CStr) -> Result<Self, String> {
let lib = unsafe { dynload::Library::open(path)? };

Some(Self {
Ok(Self {
$(
$(#[cfg($attr_name=$attr_value)])?
$func_name: unsafe { std::mem::transmute::<*mut (), unsafe extern "C" fn($($arg_type),*) $(-> $return_type)?>(
lib.get(CStr::from_bytes_with_nul_unchecked(concat!(stringify!($func_name), "\0").as_bytes())
)?) },
lib.get(CStr::from_bytes_with_nul_unchecked(concat!(stringify!($func_name), "\0").as_bytes()))?
)},
)*
_lib: lib,
})
Expand Down
19 changes: 13 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,19 @@ fn with_lib<T, F: Fn(&Libgccjit) -> T>(callback: F) -> T {

/// Returns true if the library was loaded correctly, false otherwise.
#[cfg(feature="dlopen")]
pub fn load(path: &CStr) -> bool {
let lib =
LIB.get_or_init(|| {
unsafe { Libgccjit::open(path) }
});
lib.is_some()
pub fn load(path: &CStr) -> Result<(), String> {
let mut result = Ok(());
LIB.get_or_init(|| {
let lib = unsafe { Libgccjit::open(path) };
match lib {
Ok(lib) => Some(lib),
Err(error) => {
result = Err(error);
None
},
}
});
result
}

#[cfg(feature="dlopen")]
Expand Down
Loading