Skip to content

Commit

Permalink
crates/sel4/sys: Add wrappers for sel4test
Browse files Browse the repository at this point in the history
  • Loading branch information
nspin committed Feb 10, 2024
1 parent 3298f5f commit d4256d0
Show file tree
Hide file tree
Showing 18 changed files with 944 additions and 25 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ members = [
"crates/sel4/config/generic/types",
"crates/sel4/config/macros",
"crates/sel4/sys",
"crates/sel4/sys/wrappers",
]

[patch.crates-io.ring]
Expand Down
3 changes: 3 additions & 0 deletions crates/sel4/sys/Cargo.nix
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ mk {
sel4-config-data
;
};
features = {
wrappers = [];
};
}
3 changes: 3 additions & 0 deletions crates/sel4/sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ build = "build/main.rs"
edition = "2021"
license = "BSD-2-Clause"

[features]
wrappers = []

[dependencies]
log = "0.4.17"
sel4-bitfield-ops = { path = "../bitfield-ops" }
Expand Down
106 changes: 99 additions & 7 deletions crates/sel4/sys/build/bf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::fs;
use std::path::Path;

use proc_macro2::{Literal, TokenStream};
use quote::{format_ident, quote};
use quote::{format_ident, quote, IdentFragment};
use syn::Ident;

mod simplified;
Expand All @@ -17,7 +17,7 @@ use simplified::*;
pub fn generate_rust(
blocklist_for_bindgen: &mut Vec<String>,
bf_path: impl AsRef<Path>,
) -> TokenStream {
) -> (TokenStream, TokenStream) {
let text = fs::read_to_string(bf_path).unwrap();
let file = sel4_bitfield_parser::parse(&text);
let file = simplify(&file);
Expand All @@ -28,19 +28,21 @@ pub fn generate_rust(
for tagged_union in file.tagged_unions.iter() {
generator.generate_tagged_union(tagged_union);
}
generator.toks
(generator.native_toks, generator.wrapper_toks)
}

struct BitfieldGenerator<'a> {
blocklist_for_bindgen: &'a mut Vec<String>,
toks: TokenStream,
native_toks: TokenStream,
wrapper_toks: TokenStream,
}

impl<'a> BitfieldGenerator<'a> {
fn new(blocklist_for_bindgen: &'a mut Vec<String>) -> Self {
Self {
blocklist_for_bindgen,
toks: quote!(),
native_toks: quote!(),
wrapper_toks: quote!(),
}
}

Expand All @@ -60,6 +62,7 @@ impl<'a> BitfieldGenerator<'a> {

self.blocklist_for_bindgen.push(name_ident.to_string());

let qualified_name = quote!(crate::#name_ident);
let unpacked_ident = format_ident!("{}_Unpacked", name_ident);

let primitive_type = backing_type.primitive();
Expand All @@ -70,6 +73,7 @@ impl<'a> BitfieldGenerator<'a> {
let mut unpack_field_assignments = vec![];
let mut new_body = quote!();
let mut methods = quote!();
let mut wrapper_functions = quote!();

for field in fields.iter() {
let field_name_ident = format_ident!("{}", field.name);
Expand Down Expand Up @@ -124,6 +128,37 @@ impl<'a> BitfieldGenerator<'a> {
#field_range_end - #field_range_start
}
});

let wrapper_get_prefix =
mk_wrapper_prefix(format!("{}_get_{}", name_ident, field.name));
let wrapper_set_prefix =
mk_wrapper_prefix(format!("{}_set_{}", name_ident, field.name));
let wrapper_ptr_get_prefix =
mk_wrapper_prefix(format!("{}_ptr_get_{}", name_ident, field.name));
let wrapper_ptr_set_prefix =
mk_wrapper_prefix(format!("{}_ptr_set_{}", name_ident, field.name));

if !is_tag {
wrapper_functions.extend(quote! {
#wrapper_get_prefix(this: #qualified_name) -> #primitive_type {
this.#get_method_ident()
}
#wrapper_set_prefix(mut this: #qualified_name, #field_name_ident: #primitive_type) -> #qualified_name {
this.#set_method_ident(#field_name_ident);
this
}
#wrapper_ptr_get_prefix(this: *mut #qualified_name) -> #primitive_type {
unsafe {
(&*this).#get_method_ident()
}
}
#wrapper_ptr_set_prefix(this: *mut #qualified_name, #field_name_ident: #primitive_type) {
unsafe {
(&mut *this).#set_method_ident(#field_name_ident);
}
}
})
}
}

let alias_stmt = if tag_info.is_none() {
Expand All @@ -136,7 +171,7 @@ impl<'a> BitfieldGenerator<'a> {
quote!()
};

self.toks.extend(quote! {
self.native_toks.extend(quote! {
#[repr(transparent)]
#[derive(Clone, Eq, PartialEq)]
pub struct #name_ident(pub #bitfield_type);
Expand Down Expand Up @@ -180,10 +215,28 @@ impl<'a> BitfieldGenerator<'a> {
}
}
});

let wrapper_new_prefix = mk_wrapper_prefix(format!("{name_ident}_new"));
let wrapper_ptr_new_prefix = mk_wrapper_prefix(format!("{name_ident}_ptr_new"));

self.wrapper_toks.extend(quote! {
#wrapper_new_prefix(#(#non_tag_fields_with_types,)*) -> #qualified_name {
#qualified_name::new(#(#non_tag_fields,)*)
}

#wrapper_ptr_new_prefix(this: *mut #qualified_name, #(#non_tag_fields_with_types,)*) {
unsafe {
*this = #qualified_name::new(#(#non_tag_fields,)*);
}
}

#wrapper_functions
});
}

fn generate_tagged_union(&mut self, tagged_union: &TaggedUnion) {
let name_ident = format_ident!("{}", tagged_union.name);
let qualified_name = quote!(crate::#name_ident);
let splayed_ident = format_ident!("{}_Splayed", tagged_union.name);
let primitive_type = tagged_union.backing_type.primitive();
let bitfield_type = tagged_union.backing_type.bitfield();
Expand Down Expand Up @@ -250,7 +303,7 @@ impl<'a> BitfieldGenerator<'a> {
let tag_range_start = tagged_union.tag_range.start;
let tag_range_end = tagged_union.tag_range.end;

self.toks.extend(quote! {
self.native_toks.extend(quote! {
pub mod #tag_values_module_ident {
#(#tag_value_consts;)*
}
Expand Down Expand Up @@ -295,6 +348,37 @@ impl<'a> BitfieldGenerator<'a> {

#block_unsplay_toks
});

let wrapper_get_tag_prefix = mk_wrapper_prefix(format!(
"{}_get_{}",
tagged_union.name, tagged_union.tag_name
));
let wrapper_ptr_get_tag_prefix = mk_wrapper_prefix(format!(
"{}_ptr_get_{}",
tagged_union.name, tagged_union.tag_name
));
let wrapper_tag_equals_prefix = mk_wrapper_prefix(format!(
"{}_{}_equals",
tagged_union.name, tagged_union.tag_name
));

let c_int = quote!(::core::ffi::c_int);

self.wrapper_toks.extend(quote! {
#wrapper_get_tag_prefix(this: #qualified_name) -> #primitive_type {
this.get_tag()
}

#wrapper_ptr_get_tag_prefix(this: *mut #qualified_name) -> #primitive_type {
unsafe {
(&*this).get_tag()
}
}

#wrapper_tag_equals_prefix(this: #qualified_name, tag: #primitive_type) -> #c_int {
(this.get_tag() == tag) as #c_int
}
});
}
}

Expand Down Expand Up @@ -322,3 +406,11 @@ fn mk_tagged_union_variant_block_type_ident(tagged_union_name: &str, tag_name: &
fn mk_tag_values_module_ident(tagged_union_name: &str) -> Ident {
format_ident!("{}_tag", tagged_union_name)
}

fn mk_wrapper_prefix(fn_name: impl IdentFragment) -> TokenStream {
let fn_ident = format_ident!("{}", fn_name);
quote! {
#[no_mangle]
pub extern "C" fn #fn_ident
}
}
21 changes: 14 additions & 7 deletions crates/sel4/sys/build/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ fn main() {
.unwrap()
.map(Result::unwrap)
{
let fragment = bf::generate_rust(&mut blocklist_for_bindgen, &f);
out_dir.write_file(fragment, f.with_extension("rs").file_name().unwrap());
let (native_fragment, wrappers_fragment) =
bf::generate_rust(&mut blocklist_for_bindgen, &f);
out_dir.write_file(native_fragment, f.with_extension("rs").file_name().unwrap());
out_dir.write_file(
wrappers_fragment,
f.with_extension("wrappers.rs").file_name().unwrap(),
);
}
}

Expand All @@ -59,13 +64,15 @@ fn main() {
),
];

let (invocation_labels_fragment, invocations_fragment) = xml::invocations::generate_rust(
&mut blocklist_for_bindgen,
&interface_definition_files,
);
let (invocation_labels_fragment, native_fragment, wrappers_fragment) =
xml::invocations::generate_rust(
&mut blocklist_for_bindgen,
&interface_definition_files,
);

out_dir.write_file(invocation_labels_fragment, "invocation_labels.rs");
out_dir.write_file(invocations_fragment, "invocations.rs");
out_dir.write_file(native_fragment, "invocations.rs");
out_dir.write_file(wrappers_fragment, "invocations.wrappers.rs");
}

{
Expand Down
Loading

0 comments on commit d4256d0

Please sign in to comment.