Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add casting of fundamental types to memory mapping #140

Merged
merged 5 commits into from
Apr 29, 2020
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
10 changes: 6 additions & 4 deletions crates/mun/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,16 @@ fn compiler_options(matches: &ArgMatches) -> Result<mun_compiler::CompilerOption
}

fn runtime(matches: &ArgMatches) -> Result<Runtime, failure::Error> {
let mut builder = RuntimeBuilder::new(
let builder = RuntimeBuilder::new(
matches.value_of("LIBRARY").unwrap(), // Safe because its a required arg
);

if let Some(delay) = matches.value_of("delay") {
let builder = if let Some(delay) = matches.value_of("delay") {
let delay: u64 = delay.parse()?;
builder.set_delay(Duration::from_millis(delay));
}
builder.set_delay(Duration::from_millis(delay))
} else {
builder
};

builder.spawn()
}
5 changes: 5 additions & 0 deletions crates/mun_abi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ homepage = "https://mun-lang.org"
repository = "https://github.com/mun-lang/mun"
license = "MIT OR Apache-2.0"
description = "Rust wrapper for the Mun ABI"

[dependencies]
md5 = "0.7.0"
once_cell = "1.3.1"
parking_lot = "0.10"
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
use std::ffi::CString;
use std::ptr;

use crate::type_info::HasStaticTypeInfo;
use crate::{FunctionInfo, FunctionSignature, HasStaticTypeInfo, Privacy, TypeInfo};
use std::{ffi::CString, ptr};

/// Owned storage for C-style `FunctionInfo`.
pub struct FunctionInfoStorage {
_name: CString,
_type_infos: Vec<&'static abi::TypeInfo>,
_type_infos: Vec<&'static TypeInfo>,
}

impl FunctionInfoStorage {
/// Constructs a new `FunctionInfo`, the data of which is stored in a `FunctionInfoStorage`.
pub fn new_function(
name: &str,
args: &[&'static abi::TypeInfo],
ret: Option<&'static abi::TypeInfo>,
privacy: abi::Privacy,
args: &[&'static TypeInfo],
ret: Option<&'static TypeInfo>,
privacy: Privacy,
fn_ptr: *const std::ffi::c_void,
) -> (abi::FunctionInfo, FunctionInfoStorage) {
) -> (FunctionInfo, FunctionInfoStorage) {
let name = CString::new(name).unwrap();
let type_infos: Vec<&'static abi::TypeInfo> = args.iter().copied().collect();
let type_infos: Vec<&'static TypeInfo> = args.iter().copied().collect();

let num_arg_types = type_infos.len() as u16;
let return_type = if let Some(ty) = ret {
Expand All @@ -26,8 +26,8 @@ impl FunctionInfoStorage {
ptr::null()
};

let fn_info = abi::FunctionInfo {
signature: abi::FunctionSignature {
let fn_info = FunctionInfo {
signature: FunctionSignature {
name: name.as_ptr(),
arg_types: type_infos.as_ptr() as *const *const _,
return_type,
Expand All @@ -49,11 +49,7 @@ impl FunctionInfoStorage {
/// A value-to-`FunctionInfo` conversion that consumes the input value.
pub trait IntoFunctionInfo {
/// Performs the conversion.
fn into<S: AsRef<str>>(
self,
name: S,
privacy: abi::Privacy,
) -> (abi::FunctionInfo, FunctionInfoStorage);
fn into<S: AsRef<str>>(self, name: S, privacy: Privacy) -> (FunctionInfo, FunctionInfoStorage);
}

macro_rules! into_function_info_impl {
Expand All @@ -64,7 +60,7 @@ macro_rules! into_function_info_impl {
impl<$R: HasStaticTypeInfo, $($T: HasStaticTypeInfo,)*> IntoFunctionInfo
for extern "C" fn($($T),*) -> $R
{
fn into<S: AsRef<str>>(self, name: S, privacy: abi::Privacy) -> (abi::FunctionInfo, FunctionInfoStorage) {
fn into<S: AsRef<str>>(self, name: S, privacy: Privacy) -> (FunctionInfo, FunctionInfoStorage) {
FunctionInfoStorage::new_function(
name.as_ref(),
&[$($T::type_info(),)*],
Expand All @@ -78,7 +74,7 @@ macro_rules! into_function_info_impl {
impl<$($T: HasStaticTypeInfo,)*> IntoFunctionInfo
for extern "C" fn($($T),*)
{
fn into<S: AsRef<str>>(self, name: S, privacy: abi::Privacy) -> (abi::FunctionInfo, FunctionInfoStorage) {
fn into<S: AsRef<str>>(self, name: S, privacy: Privacy) -> (FunctionInfo, FunctionInfoStorage) {
FunctionInfoStorage::new_function(
name.as_ref(),
&[$($T::type_info(),)*],
Expand Down
7 changes: 6 additions & 1 deletion crates/mun_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@
// Bindings can be manually generated by running `cargo gen-abi`.
mod autogen;
mod autogen_impl;
mod function_info;
mod static_type_map;
mod type_info;

pub use autogen::*;
pub use function_info::{FunctionInfoStorage, IntoFunctionInfo};
pub use type_info::HasStaticTypeInfo;

/// The Mun ABI prelude
///
/// The *prelude* contains imports that are used almost every time.
pub mod prelude {
pub use crate::autogen::*;
pub use crate::{Privacy, StructMemoryKind, TypeGroup};
pub use crate::{HasStaticTypeInfo, IntoFunctionInfo, Privacy, StructMemoryKind, TypeGroup};
}

/// Represents the kind of memory management a struct uses.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use super::static_type_map::StaticTypeMap;
use crate::{static_type_map::StaticTypeMap, Guid, TypeGroup, TypeInfo};
use once_cell::sync::OnceCell;
use std::convert::TryInto;
use std::ffi::{CStr, CString};
use std::sync::Once;

/// A trait that defines that for a type we can statically return a abi::TypeInfo
/// A trait that defines that for a type we can statically return a `TypeInfo`.
pub trait HasStaticTypeInfo {
/// Returns a reference to the TypeInfo for the type
fn type_info() -> &'static abi::TypeInfo;
fn type_info() -> &'static TypeInfo;
}

/// A trait that defines that for a type we can statically return the name that would be used in a
/// abi::TypeInfo. This is useful for opaque types that we do not know the full details of but we
/// could use it as a pointer type
/// `TypeInfo`. This is useful for opaque types that we do not know the full details of but we could
/// use it as a pointer type
pub trait HasStaticTypeInfoName {
/// Returns the type info name for the type
fn type_name() -> &'static CStr;
Expand All @@ -27,8 +27,8 @@ impl<T: HasStaticTypeInfo> HasStaticTypeInfoName for T {

/// Every type that has at least a type name also has a valid pointer type name
impl<T: HasStaticTypeInfoName + 'static> HasStaticTypeInfo for *const T {
fn type_info() -> &'static abi::TypeInfo {
static mut VALUE: Option<StaticTypeMap<(CString, abi::TypeInfo)>> = None;
fn type_info() -> &'static TypeInfo {
static mut VALUE: Option<StaticTypeMap<(CString, TypeInfo)>> = None;
static INIT: Once = Once::new();

let map = unsafe {
Expand All @@ -41,16 +41,16 @@ impl<T: HasStaticTypeInfoName + 'static> HasStaticTypeInfo for *const T {
&map.call_once::<T, _>(|| {
let name =
CString::new(format!("*const {}", T::type_name().to_str().unwrap())).unwrap();
let guid = abi::Guid {
let guid = Guid {
b: md5::compute(&name.as_bytes()).0,
};
let name_ptr = name.as_ptr();
(
name,
abi::TypeInfo {
TypeInfo {
guid,
name: name_ptr,
group: abi::TypeGroup::FundamentalTypes,
group: TypeGroup::FundamentalTypes,
size_in_bits: (std::mem::size_of::<*const T>() * 8)
.try_into()
.expect("size of T is larger than the maximum allowed ABI size. Please file a bug."),
Expand All @@ -66,8 +66,8 @@ impl<T: HasStaticTypeInfoName + 'static> HasStaticTypeInfo for *const T {

/// Every type that has at least a type name also has a valid pointer type name
impl<T: HasStaticTypeInfoName + 'static> HasStaticTypeInfo for *mut T {
fn type_info() -> &'static abi::TypeInfo {
static mut VALUE: Option<StaticTypeMap<(CString, abi::TypeInfo)>> = None;
fn type_info() -> &'static TypeInfo {
static mut VALUE: Option<StaticTypeMap<(CString, TypeInfo)>> = None;
static INIT: Once = Once::new();

let map = unsafe {
Expand All @@ -79,16 +79,16 @@ impl<T: HasStaticTypeInfoName + 'static> HasStaticTypeInfo for *mut T {

&map.call_once::<T, _>(|| {
let name = CString::new(format!("*mut {}", T::type_name().to_str().unwrap())).unwrap();
let guid = abi::Guid {
let guid = Guid {
b: md5::compute(&name.as_bytes()).0,
};
let name_ptr = name.as_ptr();
(
name,
abi::TypeInfo {
TypeInfo {
guid,
name: name_ptr,
group: abi::TypeGroup::FundamentalTypes,
group: TypeGroup::FundamentalTypes,
size_in_bits: (std::mem::size_of::<*const T>() * 8)
.try_into()
.expect("size of T is larger than the maximum allowed ABI size. Please file a bug."),
Expand All @@ -108,17 +108,17 @@ macro_rules! impl_basic_type_info {
),+) => {
$(
impl HasStaticTypeInfo for $ty {
fn type_info() -> &'static abi::TypeInfo {
static TYPE_INFO: OnceCell<abi::TypeInfo> = OnceCell::new();
fn type_info() -> &'static TypeInfo {
static TYPE_INFO: OnceCell<TypeInfo> = OnceCell::new();
TYPE_INFO.get_or_init(|| {
static TYPE_INFO_NAME: OnceCell<CString> = OnceCell::new();
let type_info_name: &'static CString = TYPE_INFO_NAME
.get_or_init(|| CString::new(format!("core::{}", stringify!($ty))).unwrap());

abi::TypeInfo {
guid: abi::Guid{ b: md5::compute(&type_info_name.as_bytes()).0 },
TypeInfo {
guid: Guid{ b: md5::compute(&type_info_name.as_bytes()).0 },
name: type_info_name.as_ptr(),
group: abi::TypeGroup::FundamentalTypes,
group: TypeGroup::FundamentalTypes,
size_in_bits: (std::mem::size_of::<$ty>() * 8)
.try_into()
.expect("size of T is larger than the maximum allowed ABI size. Please file a bug."),
Expand Down Expand Up @@ -153,33 +153,34 @@ macro_rules! impl_has_type_info_name {
impl_basic_type_info!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, f64, bool);

impl_has_type_info_name!(
std::ffi::c_void => "core::void"
std::ffi::c_void => "core::void",
TypeInfo => "TypeInfo"
);

#[cfg(target_pointer_width = "64")]
impl HasStaticTypeInfo for usize {
fn type_info() -> &'static abi::TypeInfo {
fn type_info() -> &'static TypeInfo {
u64::type_info()
}
}

#[cfg(target_pointer_width = "64")]
impl HasStaticTypeInfo for isize {
fn type_info() -> &'static abi::TypeInfo {
fn type_info() -> &'static TypeInfo {
i64::type_info()
}
}

#[cfg(target_pointer_width = "32")]
impl HasStaticTypeInfo for usize {
fn type_info() -> &'static abi::TypeInfo {
fn type_info() -> &'static TypeInfo {
u32::type_info()
}
}

#[cfg(target_pointer_width = "32")]
impl HasStaticTypeInfo for isize {
fn type_info() -> &'static abi::TypeInfo {
fn type_info() -> &'static TypeInfo {
i32::type_info()
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/mun_memory/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ edition = "2018"
abi = { path = "../mun_abi", package = "mun_abi" }
once_cell = "1.3.1"
parking_lot = "0.10"
lazy_static = "1.4.0"

[dev-dependencies]
paste = "0.1"
Loading