Skip to content

Commit 6759a94

Browse files
committed
feat: use macro's "tco" feature
1 parent ce6981c commit 6759a94

File tree

2 files changed

+93
-54
lines changed

2 files changed

+93
-54
lines changed

crates/vm/derive/src/lib.rs

Lines changed: 93 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,25 @@ pub fn executor_derive(input: TokenStream) -> TokenStream {
158158
where_clause
159159
.predicates
160160
.push(syn::parse_quote! { #inner_ty: ::openvm_circuit::arch::Executor<F> });
161+
162+
// We use the macro's feature to decide whether to generate the impl or not. This avoids
163+
// the target crate needing the "tco" feature defined.
164+
#[cfg(feature = "tco")]
165+
let handler = quote! {
166+
fn handler<Ctx>(
167+
&self,
168+
pc: u32,
169+
inst: &::openvm_circuit::arch::instructions::instruction::Instruction<F>,
170+
data: &mut [u8],
171+
) -> Result<::openvm_circuit::arch::Handler<F, Ctx>, ::openvm_circuit::arch::StaticProgramError>
172+
where
173+
Ctx: ::openvm_circuit::arch::execution_mode::ExecutionCtxTrait, {
174+
self.0.handler(pc, inst, data)
175+
}
176+
};
177+
#[cfg(not(feature = "tco"))]
178+
let handler = quote! {};
179+
161180
quote! {
162181
impl #impl_generics ::openvm_circuit::arch::Executor<F> for #name #ty_generics #where_clause {
163182
#[inline(always)]
@@ -176,17 +195,7 @@ pub fn executor_derive(input: TokenStream) -> TokenStream {
176195
self.0.pre_compute(pc, inst, data)
177196
}
178197

179-
#[cfg(feature = "tco")]
180-
fn handler<Ctx>(
181-
&self,
182-
pc: u32,
183-
inst: &::openvm_circuit::arch::instructions::instruction::Instruction<F>,
184-
data: &mut [u8],
185-
) -> Result<::openvm_circuit::arch::Handler<F, Ctx>, ::openvm_circuit::arch::StaticProgramError>
186-
where
187-
Ctx: ::openvm_circuit::arch::execution_mode::ExecutionCtxTrait, {
188-
self.0.handler(pc, inst, data)
189-
}
198+
#handler
190199
}
191200
}
192201
.into()
@@ -220,7 +229,7 @@ pub fn executor_derive(input: TokenStream) -> TokenStream {
220229
});
221230
// Use full path ::openvm_circuit... so it can be used either within or outside the vm
222231
// crate. Assume F is already generic of the field.
223-
let (pre_compute_size_arms, pre_compute_arms, handler_arms, where_predicates): (Vec<_>, Vec<_>, Vec<_>, Vec<_>) = multiunzip(variants.iter().map(|(variant_name, field)| {
232+
let (pre_compute_size_arms, pre_compute_arms, _handler_arms, where_predicates): (Vec<_>, Vec<_>, Vec<_>, Vec<_>) = multiunzip(variants.iter().map(|(variant_name, field)| {
224233
let field_ty = &field.ty;
225234
let pre_compute_size_arm = quote! {
226235
#name::#variant_name(x) => <#field_ty as ::openvm_circuit::arch::Executor<#first_ty_generic>>::pre_compute_size(x)
@@ -240,6 +249,26 @@ pub fn executor_derive(input: TokenStream) -> TokenStream {
240249
for predicate in where_predicates {
241250
where_clause.predicates.push(predicate);
242251
}
252+
// We use the macro's feature to decide whether to generate the impl or not. This avoids
253+
// the target crate needing the "tco" feature defined.
254+
#[cfg(feature = "tco")]
255+
let handler = quote! {
256+
fn handler<Ctx>(
257+
&self,
258+
pc: u32,
259+
instruction: &::openvm_circuit::arch::instructions::instruction::Instruction<F>,
260+
data: &mut [u8],
261+
) -> Result<::openvm_circuit::arch::Handler<F, Ctx>, ::openvm_circuit::arch::StaticProgramError>
262+
where
263+
Ctx: ::openvm_circuit::arch::execution_mode::ExecutionCtxTrait, {
264+
match self {
265+
#(#_handler_arms,)*
266+
}
267+
}
268+
};
269+
#[cfg(not(feature = "tco"))]
270+
let handler = quote! {};
271+
243272
// Don't use these ty_generics because it might have extra "F"
244273
let (impl_generics, _, where_clause) = new_generics.split_for_impl();
245274

@@ -266,19 +295,7 @@ pub fn executor_derive(input: TokenStream) -> TokenStream {
266295
}
267296
}
268297

269-
#[cfg(feature = "tco")]
270-
fn handler<Ctx>(
271-
&self,
272-
pc: u32,
273-
instruction: &::openvm_circuit::arch::instructions::instruction::Instruction<F>,
274-
data: &mut [u8],
275-
) -> Result<::openvm_circuit::arch::Handler<F, Ctx>, ::openvm_circuit::arch::StaticProgramError>
276-
where
277-
Ctx: ::openvm_circuit::arch::execution_mode::ExecutionCtxTrait, {
278-
match self {
279-
#(#handler_arms,)*
280-
}
281-
}
298+
#handler
282299
}
283300
}
284301
.into()
@@ -314,6 +331,26 @@ pub fn metered_executor_derive(input: TokenStream) -> TokenStream {
314331
where_clause
315332
.predicates
316333
.push(syn::parse_quote! { #inner_ty: ::openvm_circuit::arch::MeteredExecutor<F> });
334+
335+
// We use the macro's feature to decide whether to generate the impl or not. This avoids
336+
// the target crate needing the "tco" feature defined.
337+
#[cfg(feature = "tco")]
338+
let metered_handler = quote! {
339+
fn metered_handler<Ctx>(
340+
&self,
341+
chip_idx: usize,
342+
pc: u32,
343+
inst: &::openvm_circuit::arch::instructions::instruction::Instruction<F>,
344+
data: &mut [u8],
345+
) -> Result<::openvm_circuit::arch::Handler<F, Ctx>, ::openvm_circuit::arch::StaticProgramError>
346+
where
347+
Ctx: ::openvm_circuit::arch::execution_mode::MeteredExecutionCtxTrait, {
348+
self.0.metered_handler(chip_idx, pc, inst, data)
349+
}
350+
};
351+
#[cfg(not(feature = "tco"))]
352+
let metered_handler = quote! {};
353+
317354
quote! {
318355
impl #impl_generics ::openvm_circuit::arch::MeteredExecutor<F> for #name #ty_generics #where_clause {
319356
#[inline(always)]
@@ -332,18 +369,7 @@ pub fn metered_executor_derive(input: TokenStream) -> TokenStream {
332369
Ctx: ::openvm_circuit::arch::execution_mode::MeteredExecutionCtxTrait, {
333370
self.0.metered_pre_compute(chip_idx, pc, inst, data)
334371
}
335-
#[cfg(feature = "tco")]
336-
fn metered_handler<Ctx>(
337-
&self,
338-
chip_idx: usize,
339-
pc: u32,
340-
inst: &::openvm_circuit::arch::instructions::instruction::Instruction<F>,
341-
data: &mut [u8],
342-
) -> Result<::openvm_circuit::arch::Handler<F, Ctx>, ::openvm_circuit::arch::StaticProgramError>
343-
where
344-
Ctx: ::openvm_circuit::arch::execution_mode::MeteredExecutionCtxTrait, {
345-
self.0.metered_handler(chip_idx, pc, inst, data)
346-
}
372+
#metered_handler
347373
}
348374
}
349375
.into()
@@ -377,7 +403,7 @@ pub fn metered_executor_derive(input: TokenStream) -> TokenStream {
377403
});
378404
// Use full path ::openvm_circuit... so it can be used either within or outside the vm
379405
// crate. Assume F is already generic of the field.
380-
let (pre_compute_size_arms, metered_pre_compute_arms, metered_handler_arms, where_predicates): (Vec<_>, Vec<_>, Vec<_>, Vec<_>) = multiunzip(variants.iter().map(|(variant_name, field)| {
406+
let (pre_compute_size_arms, metered_pre_compute_arms, _metered_handler_arms, where_predicates): (Vec<_>, Vec<_>, Vec<_>, Vec<_>) = multiunzip(variants.iter().map(|(variant_name, field)| {
381407
let field_ty = &field.ty;
382408
let pre_compute_size_arm = quote! {
383409
#name::#variant_name(x) => <#field_ty as ::openvm_circuit::arch::MeteredExecutor<#first_ty_generic>>::metered_pre_compute_size(x)
@@ -400,6 +426,28 @@ pub fn metered_executor_derive(input: TokenStream) -> TokenStream {
400426
// Don't use these ty_generics because it might have extra "F"
401427
let (impl_generics, _, where_clause) = new_generics.split_for_impl();
402428

429+
// We use the macro's feature to decide whether to generate the impl or not. This avoids
430+
// the target crate needing the "tco" feature defined.
431+
#[cfg(feature = "tco")]
432+
let metered_handler = quote! {
433+
fn metered_handler<Ctx>(
434+
&self,
435+
chip_idx: usize,
436+
pc: u32,
437+
instruction: &::openvm_circuit::arch::instructions::instruction::Instruction<F>,
438+
data: &mut [u8],
439+
) -> Result<::openvm_circuit::arch::Handler<F, Ctx>, ::openvm_circuit::arch::StaticProgramError>
440+
where
441+
Ctx: ::openvm_circuit::arch::execution_mode::MeteredExecutionCtxTrait,
442+
{
443+
match self {
444+
#(#_metered_handler_arms,)*
445+
}
446+
}
447+
};
448+
#[cfg(not(feature = "tco"))]
449+
let metered_handler = quote! {};
450+
403451
quote! {
404452
impl #impl_generics ::openvm_circuit::arch::MeteredExecutor<#first_ty_generic> for #name #ty_generics #where_clause {
405453
#[inline(always)]
@@ -424,20 +472,7 @@ pub fn metered_executor_derive(input: TokenStream) -> TokenStream {
424472
}
425473
}
426474

427-
#[cfg(feature = "tco")]
428-
fn metered_handler<Ctx>(
429-
&self,
430-
chip_idx: usize,
431-
pc: u32,
432-
instruction: &::openvm_circuit::arch::instructions::instruction::Instruction<F>,
433-
data: &mut [u8],
434-
) -> Result<::openvm_circuit::arch::Handler<F, Ctx>, ::openvm_circuit::arch::StaticProgramError>
435-
where
436-
Ctx: ::openvm_circuit::arch::execution_mode::MeteredExecutionCtxTrait, {
437-
match self {
438-
#(#metered_handler_arms,)*
439-
}
440-
}
475+
#metered_handler
441476
}
442477
}
443478
.into()
@@ -563,7 +598,12 @@ fn generate_config_traits_impl(name: &Ident, inner: &DataStruct) -> syn::Result<
563598
.iter()
564599
.filter(|f| f.attrs.iter().any(|attr| attr.path().is_ident("config")))
565600
.exactly_one()
566-
.expect("Exactly one field must have the #[config] attribute");
601+
.map_err(|_| {
602+
syn::Error::new(
603+
name.span(),
604+
"Exactly one field must have the #[config] attribute",
605+
)
606+
})?;
567607
let (source_name, source_name_upper) =
568608
gen_name_with_uppercase_idents(source_field.ident.as_ref().unwrap());
569609

crates/vm/derive/src/tco.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ pub fn tco_impl(item: TokenStream) -> TokenStream {
3737

3838
// Generate the TCO handler function
3939
let handler_fn = quote! {
40-
#[cfg(feature = "tco")]
4140
#[inline(never)]
4241
unsafe fn #handler_name #handler_generics (
4342
interpreter: &::openvm_circuit::arch::interpreter::InterpretedInstance<#f_type, #ctx_type>,

0 commit comments

Comments
 (0)