Skip to content

Commit 21c494a

Browse files
authored
Merge pull request betrusted-io#581 from betrusted-io/xobs/flatipc-0.1.2
flatipc: release 0.1.2
2 parents 222f86d + 8e27dce commit 21c494a

File tree

4 files changed

+267
-39
lines changed

4 files changed

+267
-39
lines changed

libs/flatipc-derive/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
edition = "2021"
33
name = "flatipc-derive"
4-
version = "0.1.0"
4+
version = "0.1.2"
55
authors = ["Sean Cross <sean@xobs.io>"]
66
description = "Custom derive for traits from the flatipc crate"
77
license = "BSD-2-Clause OR Apache-2.0 OR MIT"
@@ -11,8 +11,8 @@ repository = "https://github.com/betrusted/xous-flatipc"
1111
proc-macro = true
1212

1313
[dependencies]
14-
proc-macro2 = "*"
15-
quote = "*"
14+
proc-macro2 = "1"
15+
quote = "1"
1616
syn = { version = "2", features = ["parsing", "extra-traits"] }
1717

1818
[features]

libs/flatipc-derive/src/lib.rs

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,22 @@ use proc_macro::TokenStream;
44
use quote::{format_ident, quote};
55
use syn::{parse_macro_input, spanned::Spanned, DeriveInput};
66

7-
fn ast_hash(ast: &syn::DeriveInput) -> u32 {
7+
fn ast_hash(ast: &syn::DeriveInput) -> usize {
88
use std::hash::{Hash, Hasher};
99
let mut hasher = std::collections::hash_map::DefaultHasher::new();
1010
ast.hash(&mut hasher);
1111
let full_hash = hasher.finish();
12-
((full_hash >> 32) as u32) ^ (full_hash as u32)
12+
13+
#[cfg(target_pointer_width = "64")]
14+
{
15+
full_hash as usize
16+
}
17+
#[cfg(target_pointer_width = "32")]
18+
{
19+
(((full_hash >> 32) as u32) ^ (full_hash as u32)) as usize
20+
}
21+
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
22+
compile_error!("Unsupported target_pointer_width");
1323
}
1424

1525
#[proc_macro_derive(IpcSafe)]
@@ -52,11 +62,10 @@ fn derive_ipc_inner(ast: DeriveInput) -> Result<proc_macro2::TokenStream, proc_m
5262
syn::Data::Union(r#union) => generate_transmittable_checks_union(&ast, r#union)?,
5363
};
5464

55-
let padded_version = generate_padded_version(&ast)?;
56-
65+
let ipc_struct = generate_ipc_struct(&ast)?;
5766
Ok(quote! {
5867
#transmittable_checks
59-
#padded_version
68+
#ipc_struct
6069
})
6170
}
6271

@@ -222,10 +231,10 @@ fn generate_transmittable_checks_union(
222231
})
223232
}
224233

225-
fn generate_padded_version(ast: &DeriveInput) -> Result<proc_macro2::TokenStream, proc_macro2::TokenStream> {
234+
fn generate_ipc_struct(ast: &DeriveInput) -> Result<proc_macro2::TokenStream, proc_macro2::TokenStream> {
226235
let visibility = ast.vis.clone();
227236
let ident = ast.ident.clone();
228-
let padded_ident = format_ident!("Ipc{}", ast.ident);
237+
let ipc_ident = format_ident!("Ipc{}", ast.ident);
229238
let ident_size = quote! { core::mem::size_of::< #ident >() };
230239
let padded_size = quote! { (#ident_size + (4096 - 1)) & !(4096 - 1) };
231240
let padding_size = quote! { #padded_size - #ident_size };
@@ -286,96 +295,124 @@ fn generate_padded_version(ast: &DeriveInput) -> Result<proc_macro2::TokenStream
286295
}
287296
};
288297

298+
let memory_messages = if cfg!(feature = "xous") {
299+
quote! {
300+
fn from_memory_message<'a>(msg: &'a xous::MemoryMessage) -> Option<&'a Self> {
301+
if msg.buf.len() < core::mem::size_of::< #ipc_ident >() {
302+
return None;
303+
}
304+
let signature = msg.offset.map(|offset| offset.get()).unwrap_or_default();
305+
if signature != #hash {
306+
return None;
307+
}
308+
unsafe { Some(&*(msg.buf.as_ptr() as *const #ipc_ident)) }
309+
}
310+
311+
fn from_memory_message_mut<'a>(msg: &'a mut xous::MemoryMessage) -> Option<&'a mut Self> {
312+
if msg.buf.len() < core::mem::size_of::< #ipc_ident >() {
313+
return None;
314+
}
315+
let signature = msg.offset.map(|offset| offset.get()).unwrap_or_default();
316+
if signature != #hash {
317+
return None;
318+
}
319+
unsafe { Some(&mut *(msg.buf.as_mut_ptr() as *mut #ipc_ident)) }
320+
}
321+
}
322+
} else {
323+
quote! {}
324+
};
325+
289326
Ok(quote! {
290327
#[repr(C, align(4096))]
291-
#visibility struct #padded_ident {
328+
#visibility struct #ipc_ident {
292329
original: #ident,
293330
padding: [u8; #padding_size],
294331
}
295332

296-
impl core::ops::Deref for #padded_ident {
333+
impl core::ops::Deref for #ipc_ident {
297334
type Target = #ident ;
298335
fn deref(&self) -> &Self::Target {
299336
&self.original
300337
}
301338
}
302339

303-
impl core::ops::DerefMut for #padded_ident {
340+
impl core::ops::DerefMut for #ipc_ident {
304341
fn deref_mut(&mut self) -> &mut Self::Target {
305342
&mut self.original
306343
}
307344
}
308345

309346
impl flatipc::IntoIpc for #ident {
310-
type IpcType = #padded_ident;
347+
type IpcType = #ipc_ident;
311348
fn into_ipc(self) -> Self::IpcType {
312-
#padded_ident {
349+
#ipc_ident {
313350
original: self,
314351
padding: [0; #padding_size],
315352
}
316353
}
317354
}
318355

319-
impl flatipc::Ipc for #padded_ident {
356+
unsafe impl flatipc::Ipc for #ipc_ident {
320357
type Original = #ident ;
321358

322359
fn from_slice<'a>(data: &'a [u8], signature: usize) -> Option<&'a Self> {
323-
if data.len() < core::mem::size_of::< #padded_ident >() {
360+
if data.len() < core::mem::size_of::< #ipc_ident >() {
324361
return None;
325362
}
326-
if signature as u32 != #hash {
363+
if signature != #hash {
327364
return None;
328365
}
329-
unsafe { Some(&*(data.as_ptr() as *const u8 as *const #padded_ident)) }
366+
unsafe { Some(&*(data.as_ptr() as *const u8 as *const #ipc_ident)) }
330367
}
331368

332369
unsafe fn from_buffer_unchecked<'a>(data: &'a [u8]) -> &'a Self {
333-
&*(data.as_ptr() as *const u8 as *const #padded_ident)
370+
&*(data.as_ptr() as *const u8 as *const #ipc_ident)
334371
}
335372

336373
fn from_slice_mut<'a>(data: &'a mut [u8], signature: usize) -> Option<&'a mut Self> {
337-
if data.len() < core::mem::size_of::< #padded_ident >() {
374+
if data.len() < core::mem::size_of::< #ipc_ident >() {
338375
return None;
339376
}
340-
if signature as u32 != #hash {
377+
if signature != #hash {
341378
return None;
342379
}
343-
unsafe { Some(&mut *(data.as_mut_ptr() as *mut u8 as *mut #padded_ident)) }
380+
unsafe { Some(&mut *(data.as_mut_ptr() as *mut u8 as *mut #ipc_ident)) }
344381
}
345382

346383
unsafe fn from_buffer_mut_unchecked<'a>(data: &'a mut [u8]) -> &'a mut Self {
347-
unsafe { &mut *(data.as_mut_ptr() as *mut u8 as *mut #padded_ident) }
384+
unsafe { &mut *(data.as_mut_ptr() as *mut u8 as *mut #ipc_ident) }
348385
}
349386

350387
fn lend(&self, connection: flatipc::CID, opcode: usize) -> Result<(), flatipc::Error> {
351-
let signature = self.signature() as usize;
388+
let signature = self.signature();
352389
let data = unsafe {
353390
core::slice::from_raw_parts(
354-
self as *const #padded_ident as *const u8,
355-
core::mem::size_of::< #padded_ident >(),
391+
self as *const #ipc_ident as *const u8,
392+
core::mem::size_of::< #ipc_ident >(),
356393
)
357394
};
358395
#lend
359396
Ok(())
360397
}
361398

362399
fn try_lend(&self, connection: flatipc::CID, opcode: usize) -> Result<(), flatipc::Error> {
363-
let signature = self.signature() as usize;
400+
let signature = self.signature();
364401
let data = unsafe {
365402
core::slice::from_raw_parts(
366-
self as *const #padded_ident as *const u8,
367-
core::mem::size_of::< #padded_ident >(),
403+
self as *const #ipc_ident as *const u8,
404+
core::mem::size_of::< #ipc_ident >(),
368405
)
369406
};
370407
#try_lend
371408
Ok(())
372409
}
373410

374411
fn lend_mut(&mut self, connection: flatipc::CID, opcode: usize) -> Result<(), flatipc::Error> {
375-
let signature = self.signature() as usize;
412+
let signature = self.signature();
376413
let mut data = unsafe {
377414
core::slice::from_raw_parts_mut(
378-
self as *mut #padded_ident as *mut u8,
415+
self as *mut #ipc_ident as *mut u8,
379416
#padded_size,
380417
)
381418
};
@@ -384,10 +421,10 @@ fn generate_padded_version(ast: &DeriveInput) -> Result<proc_macro2::TokenStream
384421
}
385422

386423
fn try_lend_mut(&mut self, connection: flatipc::CID, opcode: usize) -> Result<(), flatipc::Error> {
387-
let signature = self.signature() as usize;
424+
let signature = self.signature();
388425
let mut data = unsafe {
389426
core::slice::from_raw_parts_mut(
390-
self as *mut #padded_ident as *mut u8,
427+
self as *mut #ipc_ident as *mut u8,
391428
#padded_size,
392429
)
393430
};
@@ -407,9 +444,11 @@ fn generate_padded_version(ast: &DeriveInput) -> Result<proc_macro2::TokenStream
407444
self.original
408445
}
409446

410-
fn signature(&self) -> u32 {
447+
fn signature(&self) -> usize {
411448
#hash
412449
}
450+
451+
#memory_messages
413452
}
414453
})
415454
}

0 commit comments

Comments
 (0)