Skip to content

Commit

Permalink
Merge pull request #255 from Wodann/refactor/abi
Browse files Browse the repository at this point in the history
refactor: generate C ABI from Rust code
  • Loading branch information
Wodann authored Aug 23, 2020
2 parents cfdb98e + fd717ce commit 7bc27ba
Show file tree
Hide file tree
Showing 27 changed files with 1,441 additions and 1,864 deletions.
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[submodule "crates/mun_abi/c"]
path = crates/mun_abi/c
[submodule "crates/mun_abi/ffi"]
path = crates/mun_abi/ffi
url = https://github.com/mun-lang/abi-c.git
[submodule "crates/mun_runtime_capi/ffi"]
path = crates/mun_runtime_capi/ffi
Expand Down
1 change: 0 additions & 1 deletion crates/mun_abi/c
Submodule c deleted from 4bccc4
18 changes: 18 additions & 0 deletions crates/mun_abi/cbindgen.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
language = "C"
cpp_compat = true

include_guard = "MUN_ABI_H_"
include_version = true
sys_includes = ["stdint.h"]
no_includes = true

line_length = 100
tab_width = 4

[export]
include = ["AssemblyInfo", "StructInfo"]
prefix = "Mun"
renaming_overrides_prefixing = true

[export.rename]
"ABI_VERSION" = "MUN_ABI_VERSION"
1 change: 1 addition & 0 deletions crates/mun_abi/ffi
Submodule ffi added at 4e6b54
59 changes: 59 additions & 0 deletions crates/mun_abi/src/assembly_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use crate::{DispatchTable, ModuleInfo};
use std::{ffi::CStr, os::raw::c_char, slice, str};

/// Represents an assembly declaration.
#[repr(C)]
pub struct AssemblyInfo {
/// Symbols of the top-level module
pub symbols: ModuleInfo,
/// Dispatch table
pub dispatch_table: DispatchTable,
/// Paths to assembly dependencies
pub(crate) dependencies: *const *const c_char,
/// Number of dependencies
pub num_dependencies: u32,
}

impl AssemblyInfo {
/// Returns an iterator over the assembly's dependencies.
pub fn dependencies(&self) -> impl Iterator<Item = &str> {
let dependencies = if self.num_dependencies == 0 {
&[]
} else {
unsafe { slice::from_raw_parts(self.dependencies, self.num_dependencies as usize) }
};

dependencies
.iter()
.map(|d| unsafe { str::from_utf8_unchecked(CStr::from_ptr(*d).to_bytes()) })
}
}

unsafe impl Send for AssemblyInfo {}
unsafe impl Sync for AssemblyInfo {}

#[cfg(test)]
mod tests {
use crate::test_utils::{
fake_assembly_info, fake_dispatch_table, fake_module_info, FAKE_DEPENDENCY,
FAKE_MODULE_PATH,
};
use std::ffi::CString;

#[test]
fn test_assembly_info_dependencies() {
let module_path = CString::new(FAKE_MODULE_PATH).expect("Invalid fake module path.");
let module = fake_module_info(&module_path, &[], &[]);

let dispatch_table = fake_dispatch_table(&[], &mut []);

let dependency = CString::new(FAKE_DEPENDENCY).expect("Invalid fake dependency.");
let dependencies = &[dependency.as_ptr()];
let assembly = fake_assembly_info(module, dispatch_table, dependencies);

assert_eq!(assembly.dependencies().count(), dependencies.len());
for (lhs, rhs) in assembly.dependencies().zip([FAKE_DEPENDENCY].iter()) {
assert_eq!(lhs, *rhs)
}
}
}
Loading

0 comments on commit 7bc27ba

Please sign in to comment.