@@ -14,7 +14,9 @@ pub struct InstrEncoder {
14
14
/// The list of constructed instructions and their parameters.
15
15
instrs : Vec < Instruction > ,
16
16
/// The fuel costs of instructions.
17
- fuel_costs : FuelCostsProvider ,
17
+ ///
18
+ /// This is `Some` if fuel metering is enabled, otherwise `None`.
19
+ fuel_costs : Option < FuelCostsProvider > ,
18
20
}
19
21
20
22
impl ReusableAllocations for InstrEncoder {
@@ -49,9 +51,14 @@ impl Reset for InstrEncoder {
49
51
impl InstrEncoder {
50
52
/// Creates a new [`InstrEncoder`].
51
53
pub fn new ( engine : & Engine , alloc : InstrEncoderAllocations ) -> Self {
54
+ let config = engine. config ( ) ;
55
+ let fuel_costs = config
56
+ . get_consume_fuel ( )
57
+ . then ( || config. fuel_costs ( ) )
58
+ . cloned ( ) ;
52
59
Self {
53
60
instrs : alloc. instrs ,
54
- fuel_costs : engine . config ( ) . fuel_costs ( ) . clone ( ) ,
61
+ fuel_costs,
55
62
}
56
63
}
57
64
@@ -66,14 +73,17 @@ impl InstrEncoder {
66
73
/// # Note
67
74
///
68
75
/// The pushes [`Instruction::ConsumeFuel`] is initialized with base fuel costs.
69
- pub fn push_consume_fuel_instr ( & mut self ) -> Result < Instr , Error > {
70
- let base_costs = self . fuel_costs . base ( ) ;
76
+ pub fn push_consume_fuel_instr ( & mut self ) -> Result < Option < Instr > , Error > {
77
+ let Some ( fuel_costs) = & self . fuel_costs else {
78
+ return Ok ( None ) ;
79
+ } ;
80
+ let base_costs = fuel_costs. base ( ) ;
71
81
let Ok ( base_costs) = u32:: try_from ( base_costs) else {
72
82
panic ! ( "out of bounds base fuel costs: {base_costs}" ) ;
73
83
} ;
74
84
let instr = self . next_instr ( ) ;
75
85
self . instrs . push ( Instruction :: consume_fuel ( base_costs) ) ;
76
- Ok ( instr)
86
+ Ok ( Some ( instr) )
77
87
}
78
88
79
89
/// Pushes an [`Instruction`] to the [`InstrEncoder`].
@@ -126,10 +136,17 @@ impl InstrEncoder {
126
136
consume_fuel : Option < Instr > ,
127
137
f : impl FnOnce ( & FuelCostsProvider ) -> u64 ,
128
138
) -> Result < ( ) , Error > {
129
- let Some ( consume_fuel) = consume_fuel else {
130
- return Ok ( ( ) ) ;
139
+ let ( fuel_costs, consume_fuel) = match ( & self . fuel_costs , consume_fuel) {
140
+ ( None , None ) => return Ok ( ( ) ) ,
141
+ ( Some ( fuel_costs) , Some ( consume_fuel) ) => ( fuel_costs, consume_fuel) ,
142
+ _ => {
143
+ panic ! (
144
+ "fuel metering state mismatch: fuel_costs: {:?}, fuel_instr: {:?}" ,
145
+ self . fuel_costs, consume_fuel,
146
+ ) ;
147
+ }
131
148
} ;
132
- let fuel_consumed = f ( & self . fuel_costs ) ;
149
+ let fuel_consumed = f ( fuel_costs) ;
133
150
self . get_mut ( consume_fuel)
134
151
. bump_fuel_consumption ( fuel_consumed) ?;
135
152
Ok ( ( ) )
0 commit comments