Skip to content

Commit 126ee19

Browse files
committed
Merge branch 'jstracer-impl' of https://github.com/Soubhik-10/foundry into jstracer-impl
2 parents 7fa0c24 + bf9e9dd commit 126ee19

File tree

15 files changed

+783
-89
lines changed

15 files changed

+783
-89
lines changed

crates/cheatcodes/src/inspector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub trait CheatcodesExecutor {
111111
}
112112

113113
/// Returns a mutable reference to the tracing inspector if it is available.
114-
fn tracing_inspector(&mut self) -> Option<&mut Option<TracingInspector>> {
114+
fn tracing_inspector(&mut self) -> Option<&mut Option<Box<TracingInspector>>> {
115115
None
116116
}
117117
}

crates/config/src/lint.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ pub enum Severity {
4545
Low,
4646
Info,
4747
Gas,
48+
CodeSize,
4849
}
4950

5051
impl Severity {
@@ -55,6 +56,7 @@ impl Severity {
5556
Self::Low => Paint::yellow(message).bold().to_string(),
5657
Self::Info => Paint::cyan(message).bold().to_string(),
5758
Self::Gas => Paint::green(message).bold().to_string(),
59+
Self::CodeSize => Paint::green(message).bold().to_string(),
5860
}
5961
}
6062
}
@@ -63,7 +65,7 @@ impl From<Severity> for Level {
6365
fn from(severity: Severity) -> Self {
6466
match severity {
6567
Severity::High | Severity::Med | Severity::Low => Self::Warning,
66-
Severity::Info | Severity::Gas => Self::Note,
68+
Severity::Info | Severity::Gas | Severity::CodeSize => Self::Note,
6769
}
6870
}
6971
}
@@ -76,6 +78,7 @@ impl fmt::Display for Severity {
7678
Self::Low => self.color("Low"),
7779
Self::Info => self.color("Info"),
7880
Self::Gas => self.color("Gas"),
81+
Self::CodeSize => self.color("CodeSize"),
7982
};
8083
write!(f, "{colored}")
8184
}
@@ -102,8 +105,9 @@ impl FromStr for Severity {
102105
"low" => Ok(Self::Low),
103106
"info" => Ok(Self::Info),
104107
"gas" => Ok(Self::Gas),
108+
"size" | "codesize" | "code-size" => Ok(Self::CodeSize),
105109
_ => Err(format!(
106-
"unknown variant: found `{s}`, expected `one of `High`, `Med`, `Low`, `Info`, `Gas``"
110+
"unknown variant: found `{s}`, expected `one of `High`, `Med`, `Low`, `Info`, `Gas`, `CodeSize`"
107111
)),
108112
}
109113
}

crates/evm/evm/src/executors/invariant/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,8 +609,11 @@ impl<'a> InvariantExecutor<'a> {
609609
));
610610
}
611611

612-
self.executor.inspector_mut().fuzzer =
613-
Some(Fuzzer { call_generator, fuzz_state: fuzz_state.clone(), collect: true });
612+
self.executor.inspector_mut().set_fuzzer(Fuzzer {
613+
call_generator,
614+
fuzz_state: fuzz_state.clone(),
615+
collect: true,
616+
});
614617

615618
// Let's make sure the invariant is sound before actually starting the run:
616619
// We'll assert the invariant in its initial state, and if it fails, we'll

crates/evm/evm/src/executors/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ pub struct RawCallResult {
842842
/// The `revm::Env` after the call
843843
pub env: Env,
844844
/// The cheatcode states after execution
845-
pub cheatcodes: Option<Cheatcodes>,
845+
pub cheatcodes: Option<Box<Cheatcodes>>,
846846
/// The raw output of the execution
847847
pub out: Option<Output>,
848848
/// The chisel state

crates/evm/evm/src/inspectors/stack.rs

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ pub struct InspectorData {
262262
pub traces: Option<SparsedTraceArena>,
263263
pub line_coverage: Option<HitMaps>,
264264
pub edge_coverage: Option<Vec<u8>>,
265-
pub cheatcodes: Option<Cheatcodes>,
265+
pub cheatcodes: Option<Box<Cheatcodes>>,
266266
pub chisel_state: Option<(Vec<U256>, Vec<u8>, Option<InstructionResult>)>,
267267
pub reverter: Option<Address>,
268268
}
@@ -290,7 +290,7 @@ pub struct InnerContextData {
290290
/// collection, etc.
291291
#[derive(Clone, Debug, Default)]
292292
pub struct InspectorStack {
293-
pub cheatcodes: Option<Cheatcodes>,
293+
pub cheatcodes: Option<Box<Cheatcodes>>,
294294
pub inner: InspectorStackInner,
295295
}
296296

@@ -300,15 +300,17 @@ pub struct InspectorStack {
300300
#[derive(Default, Clone, Debug)]
301301
pub struct InspectorStackInner {
302302
// Inspectors.
303-
pub chisel_state: Option<ChiselState>,
304-
pub edge_coverage: Option<EdgeCovInspector>,
305-
pub fuzzer: Option<Fuzzer>,
306-
pub line_coverage: Option<LineCoverageCollector>,
307-
pub log_collector: Option<LogCollector>,
308-
pub printer: Option<CustomPrintTracer>,
309-
pub revert_diag: Option<RevertDiagnostic>,
310-
pub script_execution_inspector: Option<ScriptExecutionInspector>,
311-
pub tracer: Option<TracingInspector>,
303+
// These are boxed to reduce the size of the struct and slightly improve performance of the
304+
// `if let Some` checks.
305+
pub chisel_state: Option<Box<ChiselState>>,
306+
pub edge_coverage: Option<Box<EdgeCovInspector>>,
307+
pub fuzzer: Option<Box<Fuzzer>>,
308+
pub line_coverage: Option<Box<LineCoverageCollector>>,
309+
pub log_collector: Option<Box<LogCollector>>,
310+
pub printer: Option<Box<CustomPrintTracer>>,
311+
pub revert_diag: Option<Box<RevertDiagnostic>>,
312+
pub script_execution_inspector: Option<Box<ScriptExecutionInspector>>,
313+
pub tracer: Option<Box<TracingInspector>>,
312314

313315
// InspectorExt and other internal data.
314316
pub enable_isolation: bool,
@@ -335,7 +337,7 @@ impl CheatcodesExecutor for InspectorStackInner {
335337
Box::new(InspectorStackRefMut { cheatcodes: Some(cheats), inner: self })
336338
}
337339

338-
fn tracing_inspector(&mut self) -> Option<&mut Option<TracingInspector>> {
340+
fn tracing_inspector(&mut self) -> Option<&mut Option<Box<TracingInspector>>> {
339341
Some(&mut self.tracer)
340342
}
341343
}
@@ -398,19 +400,19 @@ impl InspectorStack {
398400
/// Set the cheatcodes inspector.
399401
#[inline]
400402
pub fn set_cheatcodes(&mut self, cheatcodes: Cheatcodes) {
401-
self.cheatcodes = Some(cheatcodes);
403+
self.cheatcodes = Some(cheatcodes.into());
402404
}
403405

404406
/// Set the fuzzer inspector.
405407
#[inline]
406408
pub fn set_fuzzer(&mut self, fuzzer: Fuzzer) {
407-
self.fuzzer = Some(fuzzer);
409+
self.fuzzer = Some(fuzzer.into());
408410
}
409411

410412
/// Set the Chisel inspector.
411413
#[inline]
412414
pub fn set_chisel(&mut self, final_pc: usize) {
413-
self.chisel_state = Some(ChiselState::new(final_pc));
415+
self.chisel_state = Some(ChiselState::new(final_pc).into());
414416
}
415417

416418
/// Set whether to enable the line coverage collector.
@@ -422,7 +424,8 @@ impl InspectorStack {
422424
/// Set whether to enable the edge coverage collector.
423425
#[inline]
424426
pub fn collect_edge_coverage(&mut self, yes: bool) {
425-
self.edge_coverage = yes.then(EdgeCovInspector::new); // TODO configurable edge size?
427+
// TODO: configurable edge size?
428+
self.edge_coverage = yes.then(EdgeCovInspector::new).map(Into::into);
426429
}
427430

428431
/// Set whether to enable call isolation.
@@ -459,11 +462,7 @@ impl InspectorStack {
459462
/// Revert diagnostic inspector is activated when `mode != TraceMode::None`
460463
#[inline]
461464
pub fn tracing(&mut self, mode: TraceMode) {
462-
if mode.is_none() {
463-
self.revert_diag = None;
464-
} else {
465-
self.revert_diag = Some(RevertDiagnostic::default());
466-
}
465+
self.revert_diag = (!mode.is_none()).then(RevertDiagnostic::default).map(Into::into);
467466

468467
if let Some(config) = mode.into_config() {
469468
*self.tracer.get_or_insert_with(Default::default).config_mut() = config;
@@ -480,7 +479,6 @@ impl InspectorStack {
480479
}
481480

482481
/// Collects all the data gathered during inspection into a single struct.
483-
#[inline]
484482
pub fn collect(self) -> InspectorData {
485483
let Self {
486484
mut cheatcodes,
@@ -531,7 +529,7 @@ impl InspectorStack {
531529

532530
#[inline(always)]
533531
fn as_mut(&mut self) -> InspectorStackRefMut<'_> {
534-
InspectorStackRefMut { cheatcodes: self.cheatcodes.as_mut(), inner: &mut self.inner }
532+
InspectorStackRefMut { cheatcodes: self.cheatcodes.as_deref_mut(), inner: &mut self.inner }
535533
}
536534
}
537535

@@ -740,17 +738,16 @@ impl InspectorStackRefMut<'_> {
740738
/// it.
741739
fn with_stack<O>(&mut self, f: impl FnOnce(&mut InspectorStack) -> O) -> O {
742740
let mut stack = InspectorStack {
743-
cheatcodes: self
744-
.cheatcodes
745-
.as_deref_mut()
746-
.map(|cheats| core::mem::replace(cheats, Cheatcodes::new(cheats.config.clone()))),
741+
cheatcodes: self.cheatcodes.as_deref_mut().map(|cheats| {
742+
core::mem::replace(cheats, Cheatcodes::new(cheats.config.clone())).into()
743+
}),
747744
inner: std::mem::take(self.inner),
748745
};
749746

750747
let out = f(&mut stack);
751748

752749
if let Some(cheats) = self.cheatcodes.as_deref_mut() {
753-
*cheats = stack.cheatcodes.take().unwrap();
750+
*cheats = *stack.cheatcodes.take().unwrap();
754751
}
755752

756753
*self.inner = stack.inner;
@@ -791,6 +788,11 @@ impl InspectorStackRefMut<'_> {
791788
}
792789
}
793790

791+
// We take extra care in optimizing `step` and `step_end`, as they're are likely the most
792+
// hot functions in all of Foundry.
793+
// We want to `#[inline(always)]` these functions so that `InspectorStack` does not
794+
// delegate to `InspectorStackRefMut` in this case.
795+
794796
#[inline(always)]
795797
fn step_inlined(
796798
&mut self,
@@ -799,17 +801,18 @@ impl InspectorStackRefMut<'_> {
799801
) {
800802
call_inspectors!(
801803
[
804+
// These are sorted in definition order.
805+
&mut self.edge_coverage,
802806
&mut self.fuzzer,
803-
&mut self.tracer,
804807
&mut self.line_coverage,
805-
&mut self.edge_coverage,
806-
&mut self.script_execution_inspector,
807808
&mut self.printer,
808809
&mut self.revert_diag,
810+
&mut self.script_execution_inspector,
811+
&mut self.tracer,
809812
// Keep `cheatcodes` last to make use of the tail call.
810813
&mut self.cheatcodes,
811814
],
812-
|inspector| (*inspector).step(interpreter, ecx),
815+
|inspector| (**inspector).step(interpreter, ecx),
813816
);
814817
}
815818

@@ -821,14 +824,15 @@ impl InspectorStackRefMut<'_> {
821824
) {
822825
call_inspectors!(
823826
[
824-
&mut self.tracer,
827+
// These are sorted in definition order.
825828
&mut self.chisel_state,
826829
&mut self.printer,
827830
&mut self.revert_diag,
831+
&mut self.tracer,
828832
// Keep `cheatcodes` last to make use of the tail call.
829833
&mut self.cheatcodes,
830834
],
831-
|inspector| (*inspector).step_end(interpreter, ecx),
835+
|inspector| (**inspector).step_end(interpreter, ecx),
832836
);
833837
}
834838
}

crates/evm/fuzz/src/inspector.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ use revm::{
99
/// An inspector that can fuzz and collect data for that effect.
1010
#[derive(Clone, Debug)]
1111
pub struct Fuzzer {
12-
/// Given a strategy, it generates a random call.
13-
pub call_generator: Option<RandomCallGenerator>,
1412
/// If set, it collects `stack` and `memory` values for fuzzing purposes.
1513
pub collect: bool,
14+
/// Given a strategy, it generates a random call.
15+
pub call_generator: Option<RandomCallGenerator>,
1616
/// If `collect` is set, we store the collected values in this fuzz dictionary.
1717
pub fuzz_state: EvmFuzzState,
1818
}
@@ -21,6 +21,7 @@ impl<CTX> Inspector<CTX> for Fuzzer
2121
where
2222
CTX: ContextTr<Journal: JournalExt>,
2323
{
24+
#[inline]
2425
fn step(&mut self, interp: &mut Interpreter, _context: &mut CTX) {
2526
// We only collect `stack` and `memory` data before and after calls.
2627
if self.collect {

0 commit comments

Comments
 (0)