2020extern crate proc_macro;
2121
2222use proc_macro:: TokenStream ;
23- use quote:: quote;
23+ use quote:: { quote, ToTokens } ;
2424use syn:: parse_macro_input;
2525use syn:: spanned:: Spanned ;
2626
@@ -34,38 +34,57 @@ pub fn plugin_init(_args: TokenStream, input: TokenStream) -> TokenStream {
3434 let f = parse_macro_input ! ( input as syn:: ItemFn ) ;
3535 let f_vis = & f. vis ;
3636 let f_block = & f. block ;
37- let f_decl = & f. decl ;
38- let f_inputs = & f_decl . inputs ;
37+ let f_sig = & f. sig ;
38+ let f_inputs = & f_sig . inputs ;
3939
4040 // check the function signature
41- let valid_signature = f . constness . is_none ( )
41+ let valid_signature = f_sig . constness . is_none ( )
4242 && match f_vis {
4343 syn:: Visibility :: Inherited => true ,
4444 _ => false ,
4545 }
46- && f . abi . is_none ( )
46+ && f_sig . abi . is_none ( )
4747 && f_inputs. len ( ) == 0
48- && f. decl . generics . where_clause . is_none ( )
49- && f. decl . variadic . is_none ( ) ;
48+ && f_sig. generics . where_clause . is_none ( )
49+ && f_sig. variadic . is_none ( )
50+ && check_return_type ( & f) ;
5051
5152 if !valid_signature {
5253 return syn:: parse:: Error :: new (
5354 f. span ( ) ,
54- "`#[plugin_init]` function must have signature `fn()`" ,
55+ "`#[plugin_init]` function must have signature `fn() -> optee_teec::Result<()> `" ,
5556 )
5657 . to_compile_error ( )
5758 . into ( ) ;
5859 }
5960
6061 quote ! (
6162 #[ no_mangle]
62- pub fn _plugin_init( ) -> optee_teec:: Result <( ) > {
63- #f_block
64- Ok ( ( ) )
63+ pub fn _plugin_init( ) -> optee_teec:: optee_teec_sys:: TEEC_Result {
64+ fn inner( ) -> optee_teec:: Result <( ) > {
65+ #f_block
66+ }
67+ match inner( ) {
68+ Ok ( ( ) ) => optee_teec:: optee_teec_sys:: TEEC_SUCCESS ,
69+ Err ( err) => err. raw_code( ) ,
70+ }
6571 }
6672 )
6773 . into ( )
74+ }
6875
76+ // check if return_type of the function is `optee_teec::Result<()>`
77+ fn check_return_type ( item_fn : & syn:: ItemFn ) -> bool {
78+ if let syn:: ReturnType :: Type ( _, return_type) = item_fn. sig . output . to_owned ( ) {
79+ if let syn:: Type :: Path ( path) = return_type. as_ref ( ) {
80+ let expected_type = quote ! { optee_teec:: Result <( ) > } ;
81+ let actual_type = path. path . to_token_stream ( ) ;
82+ if expected_type. to_string ( ) == actual_type. to_string ( ) {
83+ return true ;
84+ }
85+ }
86+ }
87+ return false ;
6988}
7089
7190/// Attribute to declare the invoke function of a plugin
@@ -78,50 +97,62 @@ pub fn plugin_invoke(_args: TokenStream, input: TokenStream) -> TokenStream {
7897 let f = parse_macro_input ! ( input as syn:: ItemFn ) ;
7998 let f_vis = & f. vis ;
8099 let f_block = & f. block ;
81- let f_decl = & f. decl ;
82- let f_inputs = & f_decl . inputs ;
100+ let f_sig = & f. sig ;
101+ let f_inputs = & f_sig . inputs ;
83102
84103 // check the function signature
85- let valid_signature = f . constness . is_none ( )
104+ let valid_signature = f_sig . constness . is_none ( )
86105 && match f_vis {
87106 syn:: Visibility :: Inherited => true ,
88107 _ => false ,
89108 }
90- && f . abi . is_none ( )
109+ && f_sig . abi . is_none ( )
91110 && f_inputs. len ( ) == 1
92- && f. decl . generics . where_clause . is_none ( )
93- && f. decl . variadic . is_none ( ) ;
111+ && f_sig. generics . where_clause . is_none ( )
112+ && f_sig. variadic . is_none ( )
113+ && check_return_type ( & f) ;
94114
95115 if !valid_signature {
96116 return syn:: parse:: Error :: new (
97117 f. span ( ) ,
98- "`#[plugin_invoke]` function must have signature `fn(params: &mut PluginParamters)`" ,
118+ concat ! (
119+ "`#[plugin_invoke]` function must have signature" ,
120+ " `fn(params: &mut PluginParameters) -> optee_teec::Result<()>`"
121+ ) ,
99122 )
100123 . to_compile_error ( )
101124 . into ( ) ;
102125 }
103126
127+ let params = f_inputs
128+ . first ( )
129+ . expect ( "we have already verified its len" )
130+ . into_token_stream ( ) ;
131+
104132 quote ! (
105133 #[ no_mangle]
106134 pub fn _plugin_invoke(
107135 cmd: u32 ,
108136 sub_cmd: u32 ,
109- data: * mut c_char,
137+ data: * mut core :: ffi :: c_char,
110138 in_len: u32 ,
111139 out_len: * mut u32
112- ) -> optee_teec:: Result <( ) > {
140+ ) -> optee_teec:: optee_teec_sys:: TEEC_Result {
141+ fn inner( #params) -> optee_teec:: Result <( ) > {
142+ #f_block
143+ }
113144 let mut inbuf = unsafe { std:: slice:: from_raw_parts_mut( data, in_len as usize ) } ;
114- let mut params = PluginParameters :: new( cmd, sub_cmd, inbuf) ;
115- #f_block
145+ let mut params = optee_teec:: PluginParameters :: new( cmd, sub_cmd, inbuf) ;
146+ if let Err ( err) = inner( & mut params) {
147+ return err. raw_code( ) ;
148+ } ;
116149 let outslice = params. get_out_slice( ) ;
117150 unsafe {
118151 * out_len = outslice. len( ) as u32 ;
119152 std:: ptr:: copy( outslice. as_ptr( ) , data, outslice. len( ) ) ;
120- }
121-
122- Ok ( ( ) )
153+ } ;
154+ return optee_teec:: optee_teec_sys:: TEEC_SUCCESS ;
123155 }
124156 )
125157 . into ( )
126-
127158}
0 commit comments