From cfbb5eefff4975dbb8a7b418f81e23d7fde2324f Mon Sep 17 00:00:00 2001 From: James Wilson Date: Fri, 8 Aug 2025 10:59:49 +0100 Subject: [PATCH] First pass integrated new mode bits --- crates/core/src/main.rs | 9 +-- crates/format/src/metadata.rs | 2 +- crates/format/src/mode.rs | 119 +++------------------------------- 3 files changed, 15 insertions(+), 115 deletions(-) diff --git a/crates/core/src/main.rs b/crates/core/src/main.rs index 8b28599..76ace65 100644 --- a/crates/core/src/main.rs +++ b/crates/core/src/main.rs @@ -34,7 +34,7 @@ use revive_dt_format::{ corpus::Corpus, input::Input, metadata::{ContractInstance, ContractPathAndIdent, Metadata, MetadataFile}, - mode::Mode, + mode::{Mode, ModePipeline, ModeOptimizerSetting}, }; use revive_dt_node::pool::NodePool; use revive_dt_report::reporter::{Report, Span}; @@ -145,7 +145,7 @@ where .enumerate() .flat_map(move |(case_idx, case)| { metadata - .test_modes() + .solc_modes() .into_iter() .map(move |solc_mode| (path, metadata, case_idx, case, solc_mode)) }) @@ -356,7 +356,7 @@ async fn handle_case_driver<'a, L, F>( metadata: &'a Metadata, case_idx: CaseIdx, case: &Case, - mode: SolcMode, + mode: Mode, config: &Arguments, compilation_cache: CompilationCache<'a>, leader_node: &L::Blockchain, @@ -661,7 +661,8 @@ async fn compile_contracts( let compiler = Compiler::::new() .with_allow_path(metadata.directory()?) - .with_optimization(mode.solc_optimize()); + .with_optimization(mode.optimize_setting != ModeOptimizerSetting::M0) + .with_via_ir(mode.pipeline == ModePipeline::Y); let mut compiler = metadata .files_to_compile()? .try_fold(compiler, |compiler, path| compiler.with_source(&path))?; diff --git a/crates/format/src/metadata.rs b/crates/format/src/metadata.rs index db8ec54..4dc456f 100644 --- a/crates/format/src/metadata.rs +++ b/crates/format/src/metadata.rs @@ -57,7 +57,7 @@ pub struct Metadata { impl Metadata { /// Returns the modes that we should test from this metadata. - pub fn test_modes(&self) -> Vec { + pub fn solc_modes(&self) -> Vec { match &self.modes { Some(modes) => Mode::from_parsed_modes(modes.iter()).collect(), None => Mode::all().collect() diff --git a/crates/format/src/mode.rs b/crates/format/src/mode.rs index cb0c71e..9c97587 100644 --- a/crates/format/src/mode.rs +++ b/crates/format/src/mode.rs @@ -51,6 +51,15 @@ impl Mode { } .to_test_modes() } + + /// Resolves the [`Mode`]'s solidity version requirement into a [`VersionOrRequirement`] if + /// the requirement is present on the object. Otherwise, the passed default version is used. + pub fn compiler_version_to_use(&self, default: Version) -> VersionOrRequirement { + match self.version { + Some(ref requirement) => requirement.clone().into(), + None => default.into(), + } + } } /// This represents a mode that has been parsed from test metadata. @@ -412,113 +421,3 @@ mod tests { } } - - - -/* - - - -/// Specifies the compilation mode of the test artifact. -#[derive(Hash, Debug, Clone, Eq, PartialEq)] -pub enum Mode { - Solidity(SolcMode), - Unknown(String), -} - -/// Specify Solidity specific compiler options. -#[derive(Hash, Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize)] -pub struct SolcMode { - pub solc_version: Option, - solc_optimize: Option, - pub llvm_optimizer_settings: Vec, -} - -impl SolcMode { - /// Try to parse a mode string into a solc mode. - /// Returns `None` if the string wasn't a solc YUL mode string. - /// - /// The mode string is expected to start with the `Y` ID (YUL ID), - /// optionally followed by `+` or `-` for the solc optimizer settings. - /// - /// Options can be separated by a whitespace contain the following - /// - A solc `SemVer version requirement` string - /// - One or more `-OX` where X is a supposed to be an LLVM opt mode - pub fn parse_from_mode_string(mode_string: &str) -> Option { - let mut result = Self::default(); - - let mut parts = mode_string.trim().split(" "); - - match parts.next()? { - "Y" => {} - "Y+" => result.solc_optimize = Some(true), - "Y-" => result.solc_optimize = Some(false), - _ => return None, - } - - for part in parts { - if let Ok(solc_version) = semver::VersionReq::parse(part) { - result.solc_version = Some(solc_version); - continue; - } - if let Some(level) = part.strip_prefix("-O") { - result.llvm_optimizer_settings.push(level.to_string()); - continue; - } - panic!("the YUL mode string {mode_string} failed to parse, invalid part: {part}") - } - - Some(result) - } - - /// Returns whether to enable the solc optimizer. - pub fn solc_optimize(&self) -> bool { - self.solc_optimize.unwrap_or(true) - } - - /// Calculate the latest matching solc patch version. Returns: - /// - `latest_supported` if no version request was specified. - /// - A matching version with the same minor version as `latest_supported`, if any. - /// - `None` if no minor version of the `latest_supported` version matches. - pub fn last_patch_version(&self, latest_supported: &Version) -> Option { - let Some(version_req) = self.solc_version.as_ref() else { - return Some(latest_supported.to_owned()); - }; - - // lgtm - for patch in (0..latest_supported.patch + 1).rev() { - let version = Version::new(0, latest_supported.minor, patch); - if version_req.matches(&version) { - return Some(version); - } - } - - None - } - - /// Resolves the [`SolcMode`]'s solidity version requirement into a [`VersionOrRequirement`] if - /// the requirement is present on the object. Otherwise, the passed default version is used. - pub fn compiler_version_to_use(&self, default: Version) -> VersionOrRequirement { - match self.solc_version { - Some(ref requirement) => requirement.clone().into(), - None => default.into(), - } - } -} - -impl<'de> Deserialize<'de> for Mode { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let mode_string = String::deserialize(deserializer)?; - - if let Some(solc_mode) = SolcMode::parse_from_mode_string(&mode_string) { - return Ok(Self::Solidity(solc_mode)); - } - - Ok(Self::Unknown(mode_string)) - } -} - -*/ \ No newline at end of file