Merge remote-tracking branch 'origin/main' into feature/fix-os-fd-errors

This commit is contained in:
Omar Abdulla
2025-08-16 22:48:53 +03:00
26 changed files with 1518 additions and 500 deletions
+4
View File
@@ -0,0 +1,4 @@
use semver::Version;
/// This is the first version of solc that supports the `--via-ir` flag / "viaIR" input JSON.
pub const SOLC_VERSION_SUPPORTING_VIA_YUL_IR: Version = Version::new(0, 8, 13);
+28 -8
View File
@@ -3,6 +3,8 @@
//! - Polkadot revive resolc compiler
//! - Polkadot revive Wasm compiler
mod constants;
use std::{
collections::HashMap,
hash::Hash,
@@ -19,6 +21,9 @@ use revive_dt_common::cached_fs::read_to_string;
use revive_dt_common::types::VersionOrRequirement;
use revive_dt_config::Arguments;
// Re-export this as it's a part of the compiler interface.
pub use revive_dt_common::types::{Mode, ModeOptimizerSetting, ModePipeline};
pub mod revive_js;
pub mod revive_resolc;
pub mod solc;
@@ -43,13 +48,20 @@ pub trait SolidityCompiler {
) -> impl Future<Output = anyhow::Result<PathBuf>>;
fn version(&self) -> anyhow::Result<Version>;
/// Does the compiler support the provided mode and version settings?
fn supports_mode(
compiler_version: &Version,
optimize_setting: ModeOptimizerSetting,
pipeline: ModePipeline,
) -> bool;
}
/// The generic compilation input configuration.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompilerInput {
pub enable_optimization: Option<bool>,
pub via_ir: Option<bool>,
pub pipeline: Option<ModePipeline>,
pub optimization: Option<ModeOptimizerSetting>,
pub evm_version: Option<EVMVersion>,
pub allow_paths: Vec<PathBuf>,
pub base_path: Option<PathBuf>,
@@ -85,8 +97,8 @@ where
pub fn new() -> Self {
Self {
input: CompilerInput {
enable_optimization: Default::default(),
via_ir: Default::default(),
pipeline: Default::default(),
optimization: Default::default(),
evm_version: Default::default(),
allow_paths: Default::default(),
base_path: Default::default(),
@@ -98,13 +110,13 @@ where
}
}
pub fn with_optimization(mut self, value: impl Into<Option<bool>>) -> Self {
self.input.enable_optimization = value.into();
pub fn with_optimization(mut self, value: impl Into<Option<ModeOptimizerSetting>>) -> Self {
self.input.optimization = value.into();
self
}
pub fn with_via_ir(mut self, value: impl Into<Option<bool>>) -> Self {
self.input.via_ir = value.into();
pub fn with_pipeline(mut self, value: impl Into<Option<ModePipeline>>) -> Self {
self.input.pipeline = value.into();
self
}
@@ -157,6 +169,14 @@ where
self
}
pub fn then(self, callback: impl FnOnce(Self) -> Self) -> Self {
callback(self)
}
pub fn try_then<E>(self, callback: impl FnOnce(Self) -> Result<Self, E>) -> Result<Self, E> {
callback(self)
}
pub async fn try_build(
self,
compiler_path: impl AsRef<Path>,
+25 -5
View File
@@ -15,7 +15,8 @@ use revive_solc_json_interface::{
SolcStandardJsonOutput,
};
use crate::{CompilerInput, CompilerOutput, SolidityCompiler};
use super::constants::SOLC_VERSION_SUPPORTING_VIA_YUL_IR;
use crate::{CompilerInput, CompilerOutput, ModeOptimizerSetting, ModePipeline, SolidityCompiler};
use alloy::json_abi::JsonAbi;
use anyhow::Context;
@@ -40,9 +41,8 @@ impl SolidityCompiler for Resolc {
async fn build(
&self,
CompilerInput {
enable_optimization,
// Ignored and not honored since this is required for the resolc compilation.
via_ir: _via_ir,
pipeline,
optimization,
evm_version,
allow_paths,
base_path,
@@ -54,6 +54,12 @@ impl SolidityCompiler for Resolc {
}: CompilerInput,
additional_options: Self::Options,
) -> anyhow::Result<CompilerOutput> {
if !matches!(pipeline, None | Some(ModePipeline::ViaYulIR)) {
anyhow::bail!(
"Resolc only supports the Y (via Yul IR) pipeline, but the provided pipeline is {pipeline:?}"
);
}
let input = SolcStandardJsonInput {
language: SolcStandardJsonInputLanguage::Solidity,
sources: sources
@@ -82,7 +88,9 @@ impl SolidityCompiler for Resolc {
output_selection: Some(SolcStandardJsonInputSettingsSelection::new_required()),
via_ir: Some(true),
optimizer: SolcStandardJsonInputSettingsOptimizer::new(
enable_optimization.unwrap_or(false),
optimization
.unwrap_or(ModeOptimizerSetting::M0)
.optimizations_enabled(),
None,
&Version::new(0, 0, 0),
false,
@@ -239,6 +247,18 @@ impl SolidityCompiler for Resolc {
Version::parse(version_string).map_err(Into::into)
}
fn supports_mode(
compiler_version: &Version,
_optimize_setting: ModeOptimizerSetting,
pipeline: ModePipeline,
) -> bool {
// We only support the Y (IE compile via Yul IR) mode here, which also means that we can
// only use solc version 0.8.13 and above. We must always compile via Yul IR as resolc
// needs this to translate to LLVM IR and then RISCV.
pipeline == ModePipeline::ViaYulIR
&& compiler_version >= &SOLC_VERSION_SUPPORTING_VIA_YUL_IR
}
}
#[cfg(test)]
+28 -4
View File
@@ -11,7 +11,8 @@ use revive_dt_common::types::VersionOrRequirement;
use revive_dt_config::Arguments;
use revive_dt_solc_binaries::download_solc;
use crate::{CompilerInput, CompilerOutput, SolidityCompiler};
use super::constants::SOLC_VERSION_SUPPORTING_VIA_YUL_IR;
use crate::{CompilerInput, CompilerOutput, ModeOptimizerSetting, ModePipeline, SolidityCompiler};
use anyhow::Context;
use foundry_compilers_artifacts::{
@@ -36,8 +37,8 @@ impl SolidityCompiler for Solc {
async fn build(
&self,
CompilerInput {
enable_optimization,
via_ir,
pipeline,
optimization,
evm_version,
allow_paths,
base_path,
@@ -47,6 +48,17 @@ impl SolidityCompiler for Solc {
}: CompilerInput,
_: Self::Options,
) -> anyhow::Result<CompilerOutput> {
let compiler_supports_via_ir = self.version()? >= SOLC_VERSION_SUPPORTING_VIA_YUL_IR;
// Be careful to entirely omit the viaIR field if the compiler does not support it,
// as it will error if you provide fields it does not know about. Because
// `supports_mode` is called prior to instantiating a compiler, we should never
// ask for something which is invalid.
let via_ir = match (pipeline, compiler_supports_via_ir) {
(pipeline, true) => pipeline.map(|p| p.via_yul_ir()),
(_pipeline, false) => None,
};
let input = SolcInput {
language: SolcLanguage::Solidity,
sources: Sources(
@@ -57,7 +69,7 @@ impl SolidityCompiler for Solc {
),
settings: Settings {
optimizer: Optimizer {
enabled: enable_optimization,
enabled: optimization.map(|o| o.optimizations_enabled()),
details: Some(Default::default()),
..Default::default()
},
@@ -229,6 +241,18 @@ impl SolidityCompiler for Solc {
Version::parse(version_string).map_err(Into::into)
}
fn supports_mode(
compiler_version: &Version,
_optimize_setting: ModeOptimizerSetting,
pipeline: ModePipeline,
) -> bool {
// solc 0.8.13 and above supports --via-ir, and less than that does not. Thus, we support mode E
// (ie no Yul IR) in either case, but only support Y (via Yul IR) if the compiler is new enough.
pipeline == ModePipeline::ViaEVMAssembly
|| (pipeline == ModePipeline::ViaYulIR
&& compiler_version >= &SOLC_VERSION_SUPPORTING_VIA_YUL_IR)
}
}
#[cfg(test)]