pub mod core;
pub mod execution_engine;
pub mod lljit;
pub mod target;
use llvm_sys::prelude::LLVMBool;
use std::{
borrow::Cow,
ffi::{CStr, CString},
mem::MaybeUninit,
};
unsafe fn uninitialized_vec<T>(len: usize) -> MaybeUninit<Vec<T>> {
let mut v = MaybeUninit::new(Vec::with_capacity(len));
unsafe {
v.assume_init_mut().set_len(len);
}
v
}
fn cstr_to_string(ptr: *const ::core::ffi::c_char) -> Option<String> {
if ptr.is_null() {
return None;
}
Some(
unsafe { CStr::from_ptr(ptr) }
.to_str()
.expect("CStr not UTF-8")
.to_owned(),
)
}
fn sized_cstr_to_string(ptr: *const ::core::ffi::c_char, len: usize) -> Option<String> {
if ptr.is_null() {
return None;
}
let slice = unsafe { std::slice::from_raw_parts(ptr as *const u8, len) };
Some(
std::str::from_utf8(slice)
.expect("CStr not UTF-8")
.to_owned(),
)
}
fn c_array_to_vec<T: Clone>(ptr: *const T, len: usize) -> Vec<T> {
unsafe { std::slice::from_raw_parts(ptr, len).to_vec() }
}
trait ToBool {
fn to_bool(&self) -> bool;
}
impl ToBool for LLVMBool {
fn to_bool(&self) -> bool {
*self != 0
}
}
fn to_c_str(mut s: &str) -> Cow<'_, CStr> {
if s.is_empty() {
s = "\0";
}
if !s.chars().rev().any(|ch| ch == '\0') {
return Cow::from(CString::new(s).expect("unreachable since null bytes are checked"));
}
unsafe { Cow::from(CStr::from_ptr(s.as_ptr() as *const _)) }
}
#[cfg(test)]
pub(crate) mod tests {
use std::borrow::Cow;
use crate::llvm_sys::to_c_str;
#[test]
fn test_to_c_str() {
assert!(matches!(to_c_str("my string"), Cow::Owned(_)));
assert!(matches!(to_c_str("my string\0"), Cow::Borrowed(_)));
}
}