diff --git a/Cargo.lock b/Cargo.lock index 24315ad..05180b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7980,6 +7980,7 @@ dependencies = [ "colored", "hex", "inkwell", + "libc", "md5", "mimalloc", "num", diff --git a/crates/llvm-context/src/debug_config/ir_type.rs b/crates/llvm-context/src/debug_config/ir_type.rs index e479392..2ea88f9 100644 --- a/crates/llvm-context/src/debug_config/ir_type.rs +++ b/crates/llvm-context/src/debug_config/ir_type.rs @@ -15,6 +15,9 @@ pub enum IRType { LLVM, /// Whether to dump the assembly code. Assembly, + /// Whether to jump JSON + #[cfg(debug_assertions)] + JSON, } impl IRType { @@ -26,6 +29,8 @@ impl IRType { Self::EVMLA => revive_common::EXTENSION_EVMLA, Self::LLVM => revive_common::EXTENSION_LLVM_SOURCE, Self::Assembly => revive_common::EXTENSION_POLKAVM_ASSEMBLY, + #[cfg(debug_assertions)] + Self::JSON => revive_common::EXTENSION_JSON, } } } diff --git a/crates/llvm-context/src/debug_config/mod.rs b/crates/llvm-context/src/debug_config/mod.rs index bcd6b2c..49c31ac 100644 --- a/crates/llvm-context/src/debug_config/mod.rs +++ b/crates/llvm-context/src/debug_config/mod.rs @@ -94,6 +94,22 @@ impl DebugConfig { Ok(()) } + /// Dumps the stage output as a json file suitable for use with --recursive-process + #[cfg(debug_assertions)] + pub fn dump_stage_output( + &self, + contract_path: &str, + contract_suffix: Option<&str>, + stage_json: &Vec, + ) -> anyhow::Result<()> { + let mut file_path = self.output_directory.to_owned(); + let full_file_name = Self::full_file_name(contract_path, contract_suffix, IRType::JSON); + file_path.push(full_file_name); + std::fs::write(file_path, stage_json)?; + + Ok(()) + } + /// Creates a full file name, given the contract full path, suffix, and extension. fn full_file_name(contract_path: &str, suffix: Option<&str>, ir_type: IRType) -> String { let mut full_file_name = contract_path.replace('/', "_").replace(':', "."); diff --git a/crates/solidity/Cargo.toml b/crates/solidity/Cargo.toml index 29a79fc..c4fb5b1 100644 --- a/crates/solidity/Cargo.toml +++ b/crates/solidity/Cargo.toml @@ -19,7 +19,6 @@ doctest = false [dependencies] clap = { workspace = true } -structopt = { workspace = true } colored = { workspace = true } thiserror = { workspace = true } anyhow = { workspace = true } diff --git a/crates/solidity/src/build/mod.rs b/crates/solidity/src/build/mod.rs index 5dd5d7e..430c2ca 100644 --- a/crates/solidity/src/build/mod.rs +++ b/crates/solidity/src/build/mod.rs @@ -5,9 +5,9 @@ pub mod contract; use std::collections::BTreeMap; use std::path::Path; -use crate::solc::combined_json::CombinedJson; -use crate::solc::standard_json::output::Output as StandardJsonOutput; -use crate::solc::version::Version as SolcVersion; +use crate::compiler::combined_json::CombinedJson; +use crate::compiler::standard_json::output::Output as StandardJsonOutput; +use crate::compiler::version::Version as SolcVersion; use crate::ResolcVersion; use self::contract::Contract; diff --git a/crates/solidity/src/lib.rs b/crates/solidity/src/lib.rs index 286c097..89ac917 100644 --- a/crates/solidity/src/lib.rs +++ b/crates/solidity/src/lib.rs @@ -8,7 +8,6 @@ pub(crate) mod evmla; pub(crate) mod missing_libraries; pub(crate) mod process; pub(crate) mod project; -pub(crate) mod solc; pub(crate) mod version; pub(crate) mod warning; pub(crate) mod yul; @@ -48,24 +47,6 @@ pub use self::process::Process; pub use self::project::contract::Contract as ProjectContract; pub use self::project::Project; pub use self::r#const::*; -pub use self::solc::combined_json::contract::Contract as SolcCombinedJsonContract; -pub use self::solc::combined_json::CombinedJson as SolcCombinedJson; -pub use self::solc::pipeline::Pipeline as SolcPipeline; -pub use self::solc::standard_json::input::language::Language as SolcStandardJsonInputLanguage; -pub use self::solc::standard_json::input::settings::metadata::Metadata as SolcStandardJsonInputSettingsMetadata; -pub use self::solc::standard_json::input::settings::optimizer::Optimizer as SolcStandardJsonInputSettingsOptimizer; -pub use self::solc::standard_json::input::settings::selection::file::flag::Flag as SolcStandardJsonInputSettingsSelectionFileFlag; -pub use self::solc::standard_json::input::settings::selection::file::File as SolcStandardJsonInputSettingsSelectionFile; -pub use self::solc::standard_json::input::settings::selection::Selection as SolcStandardJsonInputSettingsSelection; -pub use self::solc::standard_json::input::settings::Settings as SolcStandardJsonInputSettings; -pub use self::solc::standard_json::input::source::Source as SolcStandardJsonInputSource; -pub use self::solc::standard_json::input::Input as SolcStandardJsonInput; -pub use self::solc::standard_json::output::contract::evm::bytecode::Bytecode as SolcStandardJsonOutputContractEVMBytecode; -pub use self::solc::standard_json::output::contract::evm::EVM as SolcStandardJsonOutputContractEVM; -pub use self::solc::standard_json::output::contract::Contract as SolcStandardJsonOutputContract; -pub use self::solc::standard_json::output::Output as SolcStandardJsonOutput; -pub use self::solc::version::Version as SolcVersion; -pub use self::solc::Compiler as SolcCompiler; pub use self::version::Version as ResolcVersion; pub use self::warning::Warning; #[cfg(target_os = "emscripten")] @@ -94,7 +75,7 @@ pub fn yul( ), }; - if solc.version()?.default != SolcCompiler::LAST_SUPPORTED_VERSION { + if solc.version()?.default != compiler::LAST_SUPPORTED_VERSION { anyhow::bail!( "The Yul mode is only supported with the most recent version of the Solidity compiler: {}", compiler::LAST_SUPPORTED_VERSION, diff --git a/crates/solidity/src/missing_libraries.rs b/crates/solidity/src/missing_libraries.rs index f14927f..496a3be 100644 --- a/crates/solidity/src/missing_libraries.rs +++ b/crates/solidity/src/missing_libraries.rs @@ -3,8 +3,8 @@ use std::collections::BTreeMap; use std::collections::HashSet; -use crate::solc::standard_json::output::Output as StandardJsonOutput; -use crate::solc::version::Version as SolcVersion; +use crate::compiler::standard_json::output::Output as StandardJsonOutput; +use crate::compiler::version::Version as SolcVersion; use crate::ResolcVersion; /// The missing Solidity libraries. diff --git a/crates/solidity/src/process/mod.rs b/crates/solidity/src/process/mod.rs index 52bfe8e..18244d6 100644 --- a/crates/solidity/src/process/mod.rs +++ b/crates/solidity/src/process/mod.rs @@ -11,6 +11,6 @@ use self::input::Input; use self::output::Output; pub trait Process { - fn run() -> anyhow::Result<()>; + fn run(input_file: Option<&mut std::fs::File>) -> anyhow::Result<()>; fn call(input: Input) -> anyhow::Result; } diff --git a/crates/solidity/src/process/native_process.rs b/crates/solidity/src/process/native_process.rs index dfd6751..8070a2b 100644 --- a/crates/solidity/src/process/native_process.rs +++ b/crates/solidity/src/process/native_process.rs @@ -18,26 +18,36 @@ pub struct NativeProcess; impl Process for NativeProcess { /// Read input from `stdin`, compile a contract, and write the output to `stdout`. - fn run() -> anyhow::Result<()> { + fn run(input_file: Option<&mut std::fs::File>) -> anyhow::Result<()> { let mut stdin = std::io::stdin(); let mut stdout = std::io::stdout(); let mut stderr = std::io::stderr(); - + let mut buffer = Vec::with_capacity(16384); - stdin.read_to_end(&mut buffer).expect("Stdin reading error"); - - let input: Input = revive_common::deserialize_from_slice(buffer.as_slice())?; - if input.enable_test_encoding { - todo!() + match input_file { + Some(ins) => { + if let Err(error) = ins.read_to_end(&mut buffer) { + anyhow::bail!("Failed to read recursive process input file: {:?}", error); + } + } + None => { + if let Err(error) = stdin.read_to_end(&mut buffer) { + anyhow::bail!( + "Failed to read recursive process input from stdin: {:?}", + error + ) + } + } } + + let input: Input = revive_common::deserialize_from_slice(buffer.as_slice())?; let result = input.contract.compile( input.project, input.optimizer_settings, - input.is_system_mode, input.include_metadata_hash, input.debug_config, ); - + match result { Ok(build) => { let output = Output::new(build); @@ -56,16 +66,16 @@ impl Process for NativeProcess { } } } - + /// Runs this process recursively to compile a single contract. fn call(input: Input) -> anyhow::Result { let input_json = serde_json::to_vec(&input).expect("Always valid"); - + let executable = match EXECUTABLE.get() { Some(executable) => executable.to_owned(), None => std::env::current_exe()?, }; - + let mut command = Command::new(executable.as_path()); command.stdin(std::process::Stdio::piped()); command.stdout(std::process::Stdio::piped()); @@ -74,15 +84,26 @@ impl Process for NativeProcess { let process = command.spawn().map_err(|error| { anyhow::anyhow!("{:?} subprocess spawning error: {:?}", executable, error) })?; - + + #[cfg(debug_assertions)] + if let Some(dbg_config) = &input.debug_config { + dbg_config + .dump_stage_output(&input.contract.path, Some("stage"), &input_json) + .map_err(|error| { + anyhow::anyhow!( + "{:?} failed to log the recursive process output: {:?}", + executable, + error, + ) + })?; + } + process .stdin .as_ref() .ok_or_else(|| anyhow::anyhow!("{:?} stdin getting error", executable))? .write_all(input_json.as_slice()) - .map_err(|error| { - anyhow::anyhow!("{:?} stdin writing error: {:?}", executable, error) - })?; + .map_err(|error| anyhow::anyhow!("{:?} stdin writing error: {:?}", executable, error))?; let output = process.wait_with_output().map_err(|error| { anyhow::anyhow!("{:?} subprocess output error: {:?}", executable, error) })?; @@ -92,9 +113,9 @@ impl Process for NativeProcess { String::from_utf8_lossy(output.stderr.as_slice()).to_string(), ); } - - let output: Output = revive_common::deserialize_from_slice(output.stdout.as_slice()) - .map_err(|error| { + + let output: Output = + revive_common::deserialize_from_slice(output.stdout.as_slice()).map_err(|error| { anyhow::anyhow!( "{:?} subprocess output parsing error: {}", executable, diff --git a/crates/solidity/src/resolc/arguments.rs b/crates/solidity/src/resolc/arguments.rs index e0d9847..bb877a9 100644 --- a/crates/solidity/src/resolc/arguments.rs +++ b/crates/solidity/src/resolc/arguments.rs @@ -4,21 +4,25 @@ use std::collections::BTreeSet; use std::path::Path; use std::path::PathBuf; +use clap::Parser; use path_slash::PathExt; -use structopt::StructOpt; /// Compiles the provided Solidity input files (or use the standard input if no files /// are given or "-" is specified as a file name). Outputs the components based on the /// chosen options, either to the standard output or to files within the designated /// output directory. /// Example: resolc ERC20.sol -O3 --bin --output-dir './build/' -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] #[structopt(name = "The PolkaVM Solidity compiler")] pub struct Arguments { /// Print the version and exit. #[structopt(long = "version")] pub version: bool, + /// Print the licence and exit. + #[structopt(long = "license")] + pub license: bool, + /// Specify the input paths and remappings. /// If an argument contains a '=', it is considered a remapping. /// Multiple Solidity files can be passed in the default Solidity mode. @@ -42,7 +46,7 @@ pub struct Arguments { pub allow_paths: Option, /// Create one file per component and contract/file at the specified directory, if given. - #[structopt(short = "o", long = "output-dir")] + #[structopt(short = 'o', long = "output-dir")] pub output_directory: Option, /// Overwrite existing files (used together with -o). @@ -51,7 +55,7 @@ pub struct Arguments { /// Set the optimization parameter -O[0 | 1 | 2 | 3 | s | z]. /// Use `3` for best performance and `z` for minimal size. - #[structopt(short = "O", long = "optimization")] + #[structopt(short = 'O', long = "optimization")] pub optimization: Option, /// Try to recompile with -Oz if the bytecode is too large. @@ -77,7 +81,7 @@ pub struct Arguments { /// Specify addresses of deployable libraries. Syntax: `=
[, or whitespace] ...`. /// Addresses are interpreted as hexadecimal strings prefixed with `0x`. - #[structopt(short = "l", long = "libraries")] + #[structopt(short = 'l', long = "libraries")] pub libraries: Vec, /// Output a single JSON document containing the specified information. @@ -153,6 +157,12 @@ pub struct Arguments { /// Only for usage from within the compiler. #[structopt(long = "recursive-process")] pub recursive_process: bool, + + /// Specify the input file to use instead of stdin when --recursive-process is given. + /// This is only intended for use when developing the compiler. + #[cfg(debug_assertions)] + #[structopt(long = "recursive-process-input")] + pub recursive_process_input: Option, } impl Default for Arguments { @@ -164,7 +174,7 @@ impl Default for Arguments { impl Arguments { /// A shortcut constructor. pub fn new() -> Self { - Self::from_args() + Self::parse() } /// Validates the arguments. diff --git a/crates/solidity/src/resolc/main.rs b/crates/solidity/src/resolc/main.rs index 05596c7..b6a0056 100644 --- a/crates/solidity/src/resolc/main.rs +++ b/crates/solidity/src/resolc/main.rs @@ -41,6 +41,14 @@ fn main_inner() -> anyhow::Result<()> { return Ok(()); } + if arguments.license { + let license_mit = include_str!("../../../../LICENSE-MIT"); + let license_apache = include_str!("../../../../LICENSE-APACHE"); + + println!("{}\n{}\n", license_mit, license_apache); + return Ok(()); + } + #[cfg(feature = "parallel")] rayon::ThreadPoolBuilder::new() .stack_size(RAYON_WORKER_STACK_SIZE) @@ -50,13 +58,25 @@ fn main_inner() -> anyhow::Result<()> { revive_llvm_context::initialize_target(revive_llvm_context::Target::PVM); // TODO: pass from CLI if arguments.recursive_process { + #[cfg(debug_assertions)] + if let Some(fname) = arguments.recursive_process_input { + let mut infile = std::fs::File::open(fname)?; + #[cfg(target_os = "emscripten")] + { + return revive_solidity::WorkerProcess::run(Some(&mut infile)); + } + #[cfg(not(target_os = "emscripten"))] + { + return revive_solidity::NativeProcess::run(Some(&mut infile)); + } + } #[cfg(target_os = "emscripten")] { - return revive_solidity::WorkerProcess::run(); + return revive_solidity::WorkerProcess::run(None); } #[cfg(not(target_os = "emscripten"))] { - return revive_solidity::NativeProcess::run(); + return revive_solidity::NativeProcess::run(None); } } diff --git a/crates/solidity/src/solc/compiler.rs b/crates/solidity/src/solc/compiler.rs index dbebc08..bb34391 100644 --- a/crates/solidity/src/solc/compiler.rs +++ b/crates/solidity/src/solc/compiler.rs @@ -22,7 +22,7 @@ use self::version::Version; const FIRST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 4, 12); /// The first version of `solc`, where Yul codegen is considered robust enough. -const FIRST_YUL_VERSION: semver::Version = semver::Version::new(0, 8, 0); +pub(crate) const FIRST_YUL_VERSION: semver::Version = semver::Version::new(0, 8, 0); /// The first version of `solc`, where `--via-ir` codegen mode is supported. const FIRST_VIA_IR_VERSION: semver::Version = semver::Version::new(0, 8, 13); diff --git a/crates/solidity/src/solc/mod.rs b/crates/solidity/src/solc/mod.rs deleted file mode 100644 index 8c0ec7a..0000000 --- a/crates/solidity/src/solc/mod.rs +++ /dev/null @@ -1,299 +0,0 @@ -//! The Solidity compiler. - -pub mod combined_json; -pub mod pipeline; -pub mod standard_json; -pub mod version; - -use std::io::Write; -use std::path::Path; -use std::path::PathBuf; - -use self::combined_json::CombinedJson; -use self::pipeline::Pipeline; -use self::standard_json::input::Input as StandardJsonInput; -use self::standard_json::output::Output as StandardJsonOutput; -use self::version::Version; - -/// The Solidity compiler. -pub struct Compiler { - /// The binary executable name. - pub executable: String, - /// The lazily-initialized compiler version. - pub version: Option, -} - -impl Compiler { - /// The default executable name. - pub const DEFAULT_EXECUTABLE_NAME: &'static str = "solc"; - - /// The first version of `solc` with the support of standard JSON interface. - pub const FIRST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 4, 12); - - /// The first version of `solc`, where Yul codegen is considered robust enough. - pub const FIRST_YUL_VERSION: semver::Version = semver::Version::new(0, 8, 0); - - /// The first version of `solc`, where `--via-ir` codegen mode is supported. - pub const FIRST_VIA_IR_VERSION: semver::Version = semver::Version::new(0, 8, 13); - - /// The last supported version of `solc`. - pub const LAST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 8, 28); - - /// A shortcut constructor. - /// Different tools may use different `executable` names. For example, the integration tester - /// uses `solc-` format. - pub fn new(executable: String) -> anyhow::Result { - if let Err(error) = which::which(executable.as_str()) { - anyhow::bail!( - "The `{executable}` executable not found in ${{PATH}}: {}", - error - ); - } - Ok(Self { - executable, - version: None, - }) - } - - /// Compiles the Solidity `--standard-json` input into Yul IR. - pub fn standard_json( - &mut self, - mut input: StandardJsonInput, - pipeline: Pipeline, - base_path: Option, - include_paths: Vec, - allow_paths: Option, - ) -> anyhow::Result { - let version = self.version()?; - - let mut command = std::process::Command::new(self.executable.as_str()); - command.stdin(std::process::Stdio::piped()); - command.stdout(std::process::Stdio::piped()); - command.arg("--standard-json"); - - if let Some(base_path) = base_path { - command.arg("--base-path"); - command.arg(base_path); - } - for include_path in include_paths.into_iter() { - command.arg("--include-path"); - command.arg(include_path); - } - if let Some(allow_paths) = allow_paths { - command.arg("--allow-paths"); - command.arg(allow_paths); - } - - input.normalize(&version.default); - - let suppressed_warnings = input.suppressed_warnings.take().unwrap_or_default(); - - let input_json = serde_json::to_vec(&input).expect("Always valid"); - - let process = command.spawn().map_err(|error| { - anyhow::anyhow!("{} subprocess spawning error: {:?}", self.executable, error) - })?; - process - .stdin - .as_ref() - .ok_or_else(|| anyhow::anyhow!("{} stdin getting error", self.executable))? - .write_all(input_json.as_slice()) - .map_err(|error| { - anyhow::anyhow!("{} stdin writing error: {:?}", self.executable, error) - })?; - - let output = process.wait_with_output().map_err(|error| { - anyhow::anyhow!("{} subprocess output error: {:?}", self.executable, error) - })?; - if !output.status.success() { - anyhow::bail!( - "{} error: {}", - self.executable, - String::from_utf8_lossy(output.stderr.as_slice()).to_string() - ); - } - - let mut output: StandardJsonOutput = - revive_common::deserialize_from_slice(output.stdout.as_slice()).map_err(|error| { - anyhow::anyhow!( - "{} subprocess output parsing error: {}\n{}", - self.executable, - error, - revive_common::deserialize_from_slice::( - output.stdout.as_slice() - ) - .map(|json| serde_json::to_string_pretty(&json).expect("Always valid")) - .unwrap_or_else( - |_| String::from_utf8_lossy(output.stdout.as_slice()).to_string() - ), - ) - })?; - output.preprocess_ast(&version, pipeline, suppressed_warnings.as_slice())?; - - Ok(output) - } - - /// The `solc --combined-json abi,hashes...` mirror. - pub fn combined_json( - &self, - paths: &[PathBuf], - combined_json_argument: &str, - ) -> anyhow::Result { - let mut command = std::process::Command::new(self.executable.as_str()); - command.args(paths); - - let mut combined_json_flags = Vec::new(); - let mut combined_json_fake_flag_pushed = false; - let mut filtered_flags = Vec::with_capacity(3); - for flag in combined_json_argument.split(',') { - match flag { - flag @ "asm" | flag @ "bin" | flag @ "bin-runtime" => filtered_flags.push(flag), - flag => combined_json_flags.push(flag), - } - } - if combined_json_flags.is_empty() { - combined_json_flags.push("ast"); - combined_json_fake_flag_pushed = true; - } - command.arg("--combined-json"); - command.arg(combined_json_flags.join(",")); - - let output = command.output().map_err(|error| { - anyhow::anyhow!("{} subprocess error: {:?}", self.executable, error) - })?; - if !output.status.success() { - println!("{}", String::from_utf8_lossy(output.stdout.as_slice())); - println!("{}", String::from_utf8_lossy(output.stderr.as_slice())); - anyhow::bail!( - "{} error: {}", - self.executable, - String::from_utf8_lossy(output.stdout.as_slice()).to_string() - ); - } - - let mut combined_json: CombinedJson = - revive_common::deserialize_from_slice(output.stdout.as_slice()).map_err(|error| { - anyhow::anyhow!( - "{} subprocess output parsing error: {}\n{}", - self.executable, - error, - revive_common::deserialize_from_slice::( - output.stdout.as_slice() - ) - .map(|json| serde_json::to_string_pretty(&json).expect("Always valid")) - .unwrap_or_else( - |_| String::from_utf8_lossy(output.stdout.as_slice()).to_string() - ), - ) - })?; - for filtered_flag in filtered_flags.into_iter() { - for (_path, contract) in combined_json.contracts.iter_mut() { - match filtered_flag { - "asm" => contract.asm = Some(serde_json::Value::Null), - "bin" => contract.bin = Some("".to_owned()), - "bin-runtime" => contract.bin_runtime = Some("".to_owned()), - _ => continue, - } - } - } - if combined_json_fake_flag_pushed { - combined_json.source_list = None; - combined_json.sources = None; - } - combined_json.remove_evm(); - - Ok(combined_json) - } - - /// The `solc` Yul validator. - pub fn validate_yul(&self, path: &Path) -> anyhow::Result<()> { - let mut command = std::process::Command::new(self.executable.as_str()); - command.arg("--strict-assembly"); - command.arg(path); - - let output = command.output().map_err(|error| { - anyhow::anyhow!("{} subprocess error: {:?}", self.executable, error) - })?; - if !output.status.success() { - anyhow::bail!( - "{} error: {}", - self.executable, - String::from_utf8_lossy(output.stderr.as_slice()).to_string() - ); - } - - Ok(()) - } - - /// The `solc --version` mini-parser. - pub fn version(&mut self) -> anyhow::Result { - if let Some(version) = self.version.as_ref() { - return Ok(version.to_owned()); - } - - let mut command = std::process::Command::new(self.executable.as_str()); - command.arg("--version"); - let output = command.output().map_err(|error| { - anyhow::anyhow!("{} subprocess error: {:?}", self.executable, error) - })?; - if !output.status.success() { - anyhow::bail!( - "{} error: {}", - self.executable, - String::from_utf8_lossy(output.stderr.as_slice()).to_string() - ); - } - - let stdout = String::from_utf8_lossy(output.stdout.as_slice()); - let long = stdout - .lines() - .nth(1) - .ok_or_else(|| { - anyhow::anyhow!("{} version parsing: not enough lines", self.executable) - })? - .split(' ') - .nth(1) - .ok_or_else(|| { - anyhow::anyhow!( - "{} version parsing: not enough words in the 2nd line", - self.executable - ) - })? - .to_owned(); - let default: semver::Version = long - .split('+') - .next() - .ok_or_else(|| { - anyhow::anyhow!("{} version parsing: metadata dropping", self.executable) - })? - .parse() - .map_err(|error| anyhow::anyhow!("{} version parsing: {}", self.executable, error))?; - - let l2_revision: Option = stdout - .lines() - .nth(2) - .and_then(|line| line.split(' ').nth(1)) - .and_then(|line| line.split('-').nth(1)) - .and_then(|version| version.parse().ok()); - - let version = Version::new(long, default, l2_revision); - if version.default < Self::FIRST_SUPPORTED_VERSION { - anyhow::bail!( - "`solc` versions <{} are not supported, found {}", - Self::FIRST_SUPPORTED_VERSION, - version.default - ); - } - if version.default > Self::LAST_SUPPORTED_VERSION { - anyhow::bail!( - "`solc` versions >{} are not supported, found {}", - Self::LAST_SUPPORTED_VERSION, - version.default - ); - } - - self.version = Some(version.clone()); - - Ok(version) - } -} diff --git a/crates/solidity/src/solc/pipeline.rs b/crates/solidity/src/solc/pipeline.rs index f74313b..94a10d5 100644 --- a/crates/solidity/src/solc/pipeline.rs +++ b/crates/solidity/src/solc/pipeline.rs @@ -2,8 +2,7 @@ use serde::{Deserialize, Serialize}; -use crate::solc::version::Version as SolcVersion; -use crate::solc::Compiler as SolcCompiler; +use crate::compiler::version::Version as SolcVersion; /// The Solidity compiler pipeline type. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -19,7 +18,7 @@ pub enum Pipeline { impl Pipeline { /// We always use EVMLA for Solidity <=0.7, or if the user does not want to compile via Yul. pub fn new(solc_version: &SolcVersion, force_evmla: bool) -> Self { - if solc_version.default < compiler::FIRST_YUL_VERSION || force_evmla { + if solc_version.default < crate::compiler::FIRST_YUL_VERSION || force_evmla { Self::EVMLA } else { Self::Yul diff --git a/crates/solidity/src/solc/solc.rs b/crates/solidity/src/solc/solc.rs index 1c46621..13562a0 100644 --- a/crates/solidity/src/solc/solc.rs +++ b/crates/solidity/src/solc/solc.rs @@ -42,8 +42,8 @@ impl SolcCompiler { } impl Compiler for SolcCompiler { - /// Compiles the Solidity `--standard-json` input into Yul IR. - fn standard_json( + /// Compiles the Solidity `--standard-json` input into Yul IR. + fn standard_json( &mut self, mut input: StandardJsonInput, pipeline: Pipeline, @@ -116,7 +116,6 @@ impl Compiler for SolcCompiler { ) })?; output.preprocess_ast(&version, pipeline, suppressed_warnings.as_slice())?; - output.remove_evm(); Ok(output) } diff --git a/crates/solidity/src/test_utils.rs b/crates/solidity/src/test_utils.rs index 1d5ef30..bfca442 100644 --- a/crates/solidity/src/test_utils.rs +++ b/crates/solidity/src/test_utils.rs @@ -1,8 +1,8 @@ //! Common utility used for in frontend and integration tests. use std::collections::BTreeMap; use std::collections::BTreeSet; +use std::collections::HashMap; use std::path::PathBuf; -use std::str::FromStr; use std::sync::Mutex; use once_cell::sync::Lazy; @@ -16,14 +16,7 @@ use crate::compiler::standard_json::output::contract::evm::bytecode::DeployedByt use crate::compiler::standard_json::output::Output as SolcStandardJsonOutput; use crate::compiler::Compiler; use crate::project::Project; -use crate::solc::pipeline::Pipeline as SolcPipeline; -use crate::solc::standard_json::input::settings::optimizer::Optimizer as SolcStandardJsonInputSettingsOptimizer; -use crate::solc::standard_json::input::settings::selection::Selection as SolcStandardJsonInputSettingsSelection; -use crate::solc::standard_json::input::Input as SolcStandardJsonInput; -use crate::solc::standard_json::output::contract::evm::bytecode::Bytecode; -use crate::solc::standard_json::output::contract::evm::bytecode::DeployedBytecode; -use crate::solc::standard_json::output::Output as SolcStandardJsonOutput; -use crate::solc::Compiler as SolcCompiler; +use crate::compiler::standard_json::output::contract::evm::bytecode::Bytecode; use crate::warning::Warning; static PVM_BLOB_CACHE: Lazy>>> = Lazy::new(Default::default); diff --git a/crates/stdlib/Cargo.toml b/crates/stdlib/Cargo.toml index 2bcab72..33055e6 100644 --- a/crates/stdlib/Cargo.toml +++ b/crates/stdlib/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "revive-stdlib" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +version.workspace = true +license.workspace = true +edition.workspace = true +repository.workspace = true +description = "revive compiler stdlib components" [dependencies] inkwell = { workspace = true, features = ["target-riscv", "no-libffi-linking", "llvm18-0"] }