@@ -113,6 +113,104 @@ pub fn instruction_executor_derive(input: TokenStream) -> TokenStream {
113
113
}
114
114
}
115
115
116
+ #[ proc_macro_derive( InsExecutorE1 ) ]
117
+ pub fn ins_executor_e1_executor_derive ( input : TokenStream ) -> TokenStream {
118
+ let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
119
+
120
+ let name = & ast. ident ;
121
+ let generics = & ast. generics ;
122
+ let ( impl_generics, ty_generics, _) = generics. split_for_impl ( ) ;
123
+
124
+ match & ast. data {
125
+ Data :: Struct ( inner) => {
126
+ // Check if the struct has only one unnamed field
127
+ let inner_ty = match & inner. fields {
128
+ Fields :: Unnamed ( fields) => {
129
+ if fields. unnamed . len ( ) != 1 {
130
+ panic ! ( "Only one unnamed field is supported" ) ;
131
+ }
132
+ fields. unnamed . first ( ) . unwrap ( ) . ty . clone ( )
133
+ }
134
+ _ => panic ! ( "Only unnamed fields are supported" ) ,
135
+ } ;
136
+ // Use full path ::openvm_circuit... so it can be used either within or outside the vm
137
+ // crate. Assume F is already generic of the field.
138
+ let mut new_generics = generics. clone ( ) ;
139
+ let where_clause = new_generics. make_where_clause ( ) ;
140
+ where_clause
141
+ . predicates
142
+ . push ( syn:: parse_quote! { #inner_ty: :: openvm_circuit:: arch:: InsExecutorE1 <F > } ) ;
143
+ quote ! {
144
+ impl #impl_generics :: openvm_circuit:: arch:: InsExecutorE1 <F > for #name #ty_generics #where_clause {
145
+ fn execute_e1<Mem , Ctx >(
146
+ & mut self ,
147
+ state: :: openvm_circuit:: arch:: execution:: VmStateMut <Mem , Ctx >,
148
+ instruction: & :: openvm_circuit:: arch:: instructions:: instruction:: Instruction <F >,
149
+ ) -> :: openvm_circuit:: arch:: Result <( ) >
150
+ where
151
+ Mem : :: openvm_circuit:: system:: memory:: online:: GuestMemory ,
152
+ F : :: openvm_stark_backend:: p3_field:: PrimeField32
153
+ {
154
+ self . 0 . execute_e1( state, instruction)
155
+ }
156
+ }
157
+ }
158
+ . into ( )
159
+ }
160
+ Data :: Enum ( e) => {
161
+ let variants = e
162
+ . variants
163
+ . iter ( )
164
+ . map ( |variant| {
165
+ let variant_name = & variant. ident ;
166
+
167
+ let mut fields = variant. fields . iter ( ) ;
168
+ let field = fields. next ( ) . unwrap ( ) ;
169
+ assert ! ( fields. next( ) . is_none( ) , "Only one field is supported" ) ;
170
+ ( variant_name, field)
171
+ } )
172
+ . collect :: < Vec < _ > > ( ) ;
173
+ let first_ty_generic = ast
174
+ . generics
175
+ . params
176
+ . first ( )
177
+ . and_then ( |param| match param {
178
+ GenericParam :: Type ( type_param) => Some ( & type_param. ident ) ,
179
+ _ => None ,
180
+ } )
181
+ . expect ( "First generic must be type for Field" ) ;
182
+ // Use full path ::openvm_circuit... so it can be used either within or outside the vm
183
+ // crate. Assume F is already generic of the field.
184
+ let execute_arms = variants. iter ( ) . map ( |( variant_name, field) | {
185
+ let field_ty = & field. ty ;
186
+ quote ! {
187
+ #name:: #variant_name( x) => <#field_ty as :: openvm_circuit:: arch:: InsExecutorE1 <#first_ty_generic>>:: execute_e1( x, state, instruction)
188
+ }
189
+ } ) . collect :: < Vec < _ > > ( ) ;
190
+
191
+ quote ! {
192
+ impl #impl_generics :: openvm_circuit:: arch:: InsExecutorE1 <#first_ty_generic> for #name #ty_generics {
193
+ fn execute_e1<Mem , Ctx >(
194
+ & mut self ,
195
+ state: :: openvm_circuit:: arch:: execution:: VmStateMut <Mem , Ctx >,
196
+ instruction: & :: openvm_circuit:: arch:: instructions:: instruction:: Instruction <#first_ty_generic>,
197
+ ) -> :: openvm_circuit:: arch:: Result <( ) >
198
+ where
199
+ Mem : :: openvm_circuit:: system:: memory:: online:: GuestMemory ,
200
+ #first_ty_generic: :: openvm_stark_backend:: p3_field:: PrimeField32
201
+ {
202
+ match self {
203
+ #( #execute_arms, ) *
204
+ }
205
+ }
206
+ }
207
+ }
208
+ . into ( )
209
+ }
210
+ Data :: Union ( _) => unimplemented ! ( "Unions are not supported" ) ,
211
+ }
212
+ }
213
+
116
214
/// Derives `AnyEnum` trait on an enum type.
117
215
/// By default an enum arm will just return `self` as `&dyn Any`.
118
216
///
@@ -347,7 +445,7 @@ pub fn vm_generic_config_derive(input: proc_macro::TokenStream) -> proc_macro::T
347
445
let periphery_type = Ident :: new ( & format ! ( "{}Periphery" , name) , name. span ( ) ) ;
348
446
349
447
TokenStream :: from ( quote ! {
350
- #[ derive( :: openvm_circuit:: circuit_derive:: ChipUsageGetter , :: openvm_circuit:: circuit_derive:: Chip , :: openvm_circuit:: derive:: InstructionExecutor , :: derive_more:: derive:: From , :: openvm_circuit:: derive:: AnyEnum ) ]
448
+ #[ derive( :: openvm_circuit:: circuit_derive:: ChipUsageGetter , :: openvm_circuit:: circuit_derive:: Chip , :: openvm_circuit:: derive:: InstructionExecutor , :: openvm_circuit :: derive :: InsExecutorE1 , :: derive_more:: derive:: From , :: openvm_circuit:: derive:: AnyEnum ) ]
351
449
pub enum #executor_type<F : PrimeField32 > {
352
450
#[ any_enum]
353
451
#source_name_upper( #source_executor_type<F >) ,
0 commit comments