@@ -4,12 +4,22 @@ use proc_macro::TokenStream;
4
4
use quote:: { format_ident, quote} ;
5
5
use syn:: { parse_macro_input, spanned:: Spanned , DeriveInput } ;
6
6
7
- fn ast_hash ( ast : & syn:: DeriveInput ) -> u32 {
7
+ fn ast_hash ( ast : & syn:: DeriveInput ) -> usize {
8
8
use std:: hash:: { Hash , Hasher } ;
9
9
let mut hasher = std:: collections:: hash_map:: DefaultHasher :: new ( ) ;
10
10
ast. hash ( & mut hasher) ;
11
11
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" ) ;
13
23
}
14
24
15
25
#[ proc_macro_derive( IpcSafe ) ]
@@ -52,11 +62,10 @@ fn derive_ipc_inner(ast: DeriveInput) -> Result<proc_macro2::TokenStream, proc_m
52
62
syn:: Data :: Union ( r#union) => generate_transmittable_checks_union ( & ast, r#union) ?,
53
63
} ;
54
64
55
- let padded_version = generate_padded_version ( & ast) ?;
56
-
65
+ let ipc_struct = generate_ipc_struct ( & ast) ?;
57
66
Ok ( quote ! {
58
67
#transmittable_checks
59
- #padded_version
68
+ #ipc_struct
60
69
} )
61
70
}
62
71
@@ -222,10 +231,10 @@ fn generate_transmittable_checks_union(
222
231
} )
223
232
}
224
233
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 > {
226
235
let visibility = ast. vis . clone ( ) ;
227
236
let ident = ast. ident . clone ( ) ;
228
- let padded_ident = format_ident ! ( "Ipc{}" , ast. ident) ;
237
+ let ipc_ident = format_ident ! ( "Ipc{}" , ast. ident) ;
229
238
let ident_size = quote ! { core:: mem:: size_of:: < #ident >( ) } ;
230
239
let padded_size = quote ! { ( #ident_size + ( 4096 - 1 ) ) & !( 4096 - 1 ) } ;
231
240
let padding_size = quote ! { #padded_size - #ident_size } ;
@@ -286,96 +295,124 @@ fn generate_padded_version(ast: &DeriveInput) -> Result<proc_macro2::TokenStream
286
295
}
287
296
} ;
288
297
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
+
289
326
Ok ( quote ! {
290
327
#[ repr( C , align( 4096 ) ) ]
291
- #visibility struct #padded_ident {
328
+ #visibility struct #ipc_ident {
292
329
original: #ident,
293
330
padding: [ u8 ; #padding_size] ,
294
331
}
295
332
296
- impl core:: ops:: Deref for #padded_ident {
333
+ impl core:: ops:: Deref for #ipc_ident {
297
334
type Target = #ident ;
298
335
fn deref( & self ) -> & Self :: Target {
299
336
& self . original
300
337
}
301
338
}
302
339
303
- impl core:: ops:: DerefMut for #padded_ident {
340
+ impl core:: ops:: DerefMut for #ipc_ident {
304
341
fn deref_mut( & mut self ) -> & mut Self :: Target {
305
342
& mut self . original
306
343
}
307
344
}
308
345
309
346
impl flatipc:: IntoIpc for #ident {
310
- type IpcType = #padded_ident ;
347
+ type IpcType = #ipc_ident ;
311
348
fn into_ipc( self ) -> Self :: IpcType {
312
- #padded_ident {
349
+ #ipc_ident {
313
350
original: self ,
314
351
padding: [ 0 ; #padding_size] ,
315
352
}
316
353
}
317
354
}
318
355
319
- impl flatipc:: Ipc for #padded_ident {
356
+ unsafe impl flatipc:: Ipc for #ipc_ident {
320
357
type Original = #ident ;
321
358
322
359
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 >( ) {
324
361
return None ;
325
362
}
326
- if signature as u32 != #hash {
363
+ if signature != #hash {
327
364
return None ;
328
365
}
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 ) ) }
330
367
}
331
368
332
369
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 )
334
371
}
335
372
336
373
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 >( ) {
338
375
return None ;
339
376
}
340
- if signature as u32 != #hash {
377
+ if signature != #hash {
341
378
return None ;
342
379
}
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 ) ) }
344
381
}
345
382
346
383
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 ) }
348
385
}
349
386
350
387
fn lend( & self , connection: flatipc:: CID , opcode: usize ) -> Result <( ) , flatipc:: Error > {
351
- let signature = self . signature( ) as usize ;
388
+ let signature = self . signature( ) ;
352
389
let data = unsafe {
353
390
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 >( ) ,
356
393
)
357
394
} ;
358
395
#lend
359
396
Ok ( ( ) )
360
397
}
361
398
362
399
fn try_lend( & self , connection: flatipc:: CID , opcode: usize ) -> Result <( ) , flatipc:: Error > {
363
- let signature = self . signature( ) as usize ;
400
+ let signature = self . signature( ) ;
364
401
let data = unsafe {
365
402
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 >( ) ,
368
405
)
369
406
} ;
370
407
#try_lend
371
408
Ok ( ( ) )
372
409
}
373
410
374
411
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( ) ;
376
413
let mut data = unsafe {
377
414
core:: slice:: from_raw_parts_mut(
378
- self as * mut #padded_ident as * mut u8 ,
415
+ self as * mut #ipc_ident as * mut u8 ,
379
416
#padded_size,
380
417
)
381
418
} ;
@@ -384,10 +421,10 @@ fn generate_padded_version(ast: &DeriveInput) -> Result<proc_macro2::TokenStream
384
421
}
385
422
386
423
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( ) ;
388
425
let mut data = unsafe {
389
426
core:: slice:: from_raw_parts_mut(
390
- self as * mut #padded_ident as * mut u8 ,
427
+ self as * mut #ipc_ident as * mut u8 ,
391
428
#padded_size,
392
429
)
393
430
} ;
@@ -407,9 +444,11 @@ fn generate_padded_version(ast: &DeriveInput) -> Result<proc_macro2::TokenStream
407
444
self . original
408
445
}
409
446
410
- fn signature( & self ) -> u32 {
447
+ fn signature( & self ) -> usize {
411
448
#hash
412
449
}
450
+
451
+ #memory_messages
413
452
}
414
453
} )
415
454
}
0 commit comments