1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use crate::{gas, visitors};
use super::{BranchTargetKind, Frame};
pub trait Config<'b> {
type GasVisitor<'s>: visitors::VisitOperatorWithOffset<'b, Output = Result<(), gas::Error>>
where
Self: 's;
fn make_visitor<'s>(&'s mut self, state: &'s mut gas::FunctionState) -> Self::GasVisitor<'s>;
fn save_outcomes(
&self,
state: &mut gas::FunctionState,
destination: &mut crate::AnalysisOutcome,
);
}
impl<'b> Config<'b> for crate::NoConfig {
type GasVisitor<'s> = visitors::NoOpVisitor<Result<(), gas::Error>>;
fn make_visitor<'s>(&'s mut self, _: &'s mut gas::FunctionState) -> Self::GasVisitor<'s> {
visitors::NoOpVisitor(Ok(()))
}
fn save_outcomes(&self, _: &mut gas::FunctionState, _: &mut crate::AnalysisOutcome) {}
}
impl<'b, V: wasmparser::VisitOperator<'b, Output = u64>> Config<'b> for V {
type GasVisitor<'s> = gas::Visitor<'s, V> where Self: 's;
fn make_visitor<'s>(&'s mut self, state: &'s mut gas::FunctionState) -> Self::GasVisitor<'s> {
gas::Visitor {
offset: 0,
model: self,
state,
}
}
fn save_outcomes(&self, state: &mut gas::FunctionState, out: &mut crate::AnalysisOutcome) {
state.optimize();
out.gas_offsets.push(state.offsets.drain(..).collect());
out.gas_kinds.push(state.kinds.drain(..).collect());
out.gas_costs.push(state.costs.drain(..).collect());
state.frame_stack.clear();
state.current_frame = Frame {
stack_polymorphic: false,
kind: BranchTargetKind::UntakenForward,
};
state.next_offset_cost = None;
}
}