Initial wasm support

This commit is contained in:
Sebastian Miasojed
2024-08-29 17:28:31 +02:00
parent 41c8d4e955
commit 5ac67bdc0d
69 changed files with 2277 additions and 8937 deletions
+6 -30
View File
@@ -4,25 +4,21 @@ 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, Parser)]
#[derive(Debug, StructOpt)]
#[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.
@@ -46,7 +42,7 @@ pub struct Arguments {
pub allow_paths: Option<String>,
/// 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<PathBuf>,
/// Overwrite existing files (used together with -o).
@@ -55,7 +51,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<char>,
/// Try to recompile with -Oz if the bytecode is too large.
@@ -85,7 +81,7 @@ pub struct Arguments {
/// Specify addresses of deployable libraries. Syntax: `<libraryName>=<address> [, or whitespace] ...`.
/// Addresses are interpreted as hexadecimal strings prefixed with `0x`.
#[structopt(short = 'l', long = "libraries")]
#[structopt(short = "l", long = "libraries")]
pub libraries: Vec<String>,
/// Output a single JSON document containing the specified information.
@@ -168,12 +164,6 @@ 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<String>,
}
impl Default for Arguments {
@@ -185,7 +175,7 @@ impl Default for Arguments {
impl Arguments {
/// A shortcut constructor.
pub fn new() -> Self {
Self::parse()
Self::from_args()
}
/// Validates the arguments.
@@ -195,20 +185,6 @@ impl Arguments {
anyhow::bail!("No other options are allowed while getting the compiler version.");
}
#[cfg(debug_assertions)]
if self.recursive_process_input != None && !self.recursive_process {
anyhow::bail!("--process-input can be only used when --recursive-process is given");
}
#[cfg(debug_assertions)]
if self.recursive_process
&& ((self.recursive_process_input == None && std::env::args().count() > 2)
|| (self.recursive_process_input != None && std::env::args().count() > 4))
{
anyhow::bail!("No other options are allowed in recursive mode.");
}
#[cfg(not(debug_assertions))]
if self.recursive_process && std::env::args().count() > 2 {
anyhow::bail!("No other options are allowed in recursive mode.");
}
+24 -19
View File
@@ -4,8 +4,11 @@ pub mod arguments;
use std::str::FromStr;
use revive_solidity::Process;
use self::arguments::Arguments;
#[cfg(feature = "parallel")]
/// The rayon worker stack size.
const RAYON_WORKER_STACK_SIZE: usize = 16 * 1024 * 1024;
@@ -39,14 +42,7 @@ 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)
.build_global()
@@ -55,13 +51,14 @@ 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)?;
return revive_solidity::run_process(Some(&mut infile));
#[cfg(target_os = "emscripten")]
{
return revive_solidity::WorkerProcess::run();
}
#[cfg(not(target_os = "emscripten"))]
{
return revive_solidity::NativeProcess::run();
}
return revive_solidity::run_process(None);
}
let debug_config = match arguments.debug_output_directory {
@@ -83,11 +80,19 @@ fn main_inner() -> anyhow::Result<()> {
None => None,
};
let mut solc = revive_solidity::SolcCompiler::new(
arguments
.solc
.unwrap_or_else(|| revive_solidity::SolcCompiler::DEFAULT_EXECUTABLE_NAME.to_owned()),
)?;
let mut solc = {
#[cfg(target_os = "emscripten")]
{
revive_solidity::SoljsonCompiler { version: None }
}
#[cfg(not(target_os = "emscripten"))]
{
revive_solidity::SolcCompiler::new(arguments.solc.unwrap_or_else(|| {
revive_solidity::SolcCompiler::DEFAULT_EXECUTABLE_NAME.to_owned()
}))?
}
};
let evm_version = match arguments.evm_version {
Some(evm_version) => Some(revive_common::EVMVersion::try_from(evm_version.as_str())?),