mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-13 01:41:00 +00:00
Suport passing arbitrary llvm arguments (#271)
- Support for passing LLVM command line options via the prcoess input or providing one or more `--llvm-arg='..'` resolc CLI flag. This allows more fine-grained control over the LLVM backend configuration. - Make LLVM initialization idempotent. --------- Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
@@ -10,6 +10,7 @@ Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
|
|||||||
- Support for solc v0.8.29
|
- Support for solc v0.8.29
|
||||||
- Decouples the solc JSON-input-output type definitions from the Solidity fronted and expose them via a dedicated crate.
|
- Decouples the solc JSON-input-output type definitions from the Solidity fronted and expose them via a dedicated crate.
|
||||||
- `--supported-solc-versions` for `resolc` binary to return a `semver` range of supported `solc` versions.
|
- `--supported-solc-versions` for `resolc` binary to return a `semver` range of supported `solc` versions.
|
||||||
|
- Support for passing LLVM command line options via the prcoess input or providing one or more `--llvm-arg='..'` resolc CLI flag. This allows more fine-grained control over the LLVM backend configuration.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Runner `resolc` using webkit is no longer supported.
|
- Runner `resolc` using webkit is no longer supported.
|
||||||
|
|||||||
Generated
+1
@@ -8368,6 +8368,7 @@ dependencies = [
|
|||||||
"hex",
|
"hex",
|
||||||
"inkwell",
|
"inkwell",
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
|
"libc",
|
||||||
"num",
|
"num",
|
||||||
"polkavm-common 0.21.0",
|
"polkavm-common 0.21.0",
|
||||||
"polkavm-disassembler",
|
"polkavm-disassembler",
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ num = { workspace = true }
|
|||||||
hex = { workspace = true }
|
hex = { workspace = true }
|
||||||
sha3 = { workspace = true }
|
sha3 = { workspace = true }
|
||||||
inkwell = { workspace = true }
|
inkwell = { workspace = true }
|
||||||
|
libc = { workspace = true }
|
||||||
polkavm-disassembler = { workspace = true }
|
polkavm-disassembler = { workspace = true }
|
||||||
polkavm-common = { workspace = true }
|
polkavm-common = { workspace = true }
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
//! The LLVM context library.
|
//! The LLVM context library.
|
||||||
|
|
||||||
pub(crate) mod debug_config;
|
use std::ffi::CString;
|
||||||
pub(crate) mod optimizer;
|
use std::sync::OnceLock;
|
||||||
pub(crate) mod polkavm;
|
|
||||||
pub(crate) mod target_machine;
|
|
||||||
|
|
||||||
pub use self::debug_config::ir_type::IRType as DebugConfigIR;
|
pub use self::debug_config::ir_type::IRType as DebugConfigIR;
|
||||||
pub use self::debug_config::DebugConfig;
|
pub use self::debug_config::DebugConfig;
|
||||||
@@ -74,9 +72,41 @@ pub use self::polkavm::WriteLLVM as PolkaVMWriteLLVM;
|
|||||||
pub use self::target_machine::target::Target;
|
pub use self::target_machine::target::Target;
|
||||||
pub use self::target_machine::TargetMachine;
|
pub use self::target_machine::TargetMachine;
|
||||||
|
|
||||||
/// Initializes the target machine.
|
pub(crate) mod debug_config;
|
||||||
pub fn initialize_target(target: Target) {
|
pub(crate) mod optimizer;
|
||||||
|
pub(crate) mod polkavm;
|
||||||
|
pub(crate) mod target_machine;
|
||||||
|
|
||||||
|
static DID_INITIALIZE: OnceLock<()> = OnceLock::new();
|
||||||
|
|
||||||
|
/// Initializes the LLVM compiler backend.
|
||||||
|
///
|
||||||
|
/// This is a no-op if called subsequentially.
|
||||||
|
///
|
||||||
|
/// `llvm_arguments` are passed as-is to the LLVM CL options parser.
|
||||||
|
pub fn initialize_llvm(target: Target, name: &str, llvm_arguments: &[String]) {
|
||||||
|
let Ok(_) = DID_INITIALIZE.set(()) else {
|
||||||
|
return; // Tests don't go through a recursive process
|
||||||
|
};
|
||||||
|
|
||||||
|
let argv = [name.to_string()]
|
||||||
|
.iter()
|
||||||
|
.chain(llvm_arguments)
|
||||||
|
.map(|arg| CString::new(arg.as_bytes()).unwrap())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let argv: Vec<*const libc::c_char> = argv.iter().map(|arg| arg.as_ptr()).collect();
|
||||||
|
let overview = CString::new("").unwrap();
|
||||||
|
unsafe {
|
||||||
|
inkwell::llvm_sys::support::LLVMParseCommandLineOptions(
|
||||||
|
argv.len() as i32,
|
||||||
|
argv.as_ptr(),
|
||||||
|
overview.as_ptr(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inkwell::support::enable_llvm_pretty_stack_trace();
|
||||||
|
|
||||||
match target {
|
match target {
|
||||||
Target::PVM => self::polkavm::initialize_target(),
|
Target::PVM => inkwell::targets::Target::initialize_riscv(&Default::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ where
|
|||||||
current_function: Option<Rc<RefCell<Function<'ctx>>>>,
|
current_function: Option<Rc<RefCell<Function<'ctx>>>>,
|
||||||
/// The loop context stack.
|
/// The loop context stack.
|
||||||
loop_stack: Vec<Loop<'ctx>>,
|
loop_stack: Vec<Loop<'ctx>>,
|
||||||
|
/// The extra LLVM arguments that were used during target initialization.
|
||||||
|
llvm_arguments: &'ctx [String],
|
||||||
|
|
||||||
/// The project dependency manager. It can be any entity implementing the trait.
|
/// The project dependency manager. It can be any entity implementing the trait.
|
||||||
/// The manager is used to get information about contracts and their dependencies during
|
/// The manager is used to get information about contracts and their dependencies during
|
||||||
@@ -223,6 +225,7 @@ where
|
|||||||
dependency_manager: Option<D>,
|
dependency_manager: Option<D>,
|
||||||
include_metadata_hash: bool,
|
include_metadata_hash: bool,
|
||||||
debug_config: DebugConfig,
|
debug_config: DebugConfig,
|
||||||
|
llvm_arguments: &'ctx [String],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::set_data_layout(llvm, &module);
|
Self::set_data_layout(llvm, &module);
|
||||||
Self::link_stdlib_module(llvm, &module);
|
Self::link_stdlib_module(llvm, &module);
|
||||||
@@ -250,6 +253,7 @@ where
|
|||||||
functions: HashMap::with_capacity(Self::FUNCTIONS_HASHMAP_INITIAL_CAPACITY),
|
functions: HashMap::with_capacity(Self::FUNCTIONS_HASHMAP_INITIAL_CAPACITY),
|
||||||
current_function: None,
|
current_function: None,
|
||||||
loop_stack: Vec::with_capacity(Self::LOOP_STACK_INITIAL_CAPACITY),
|
loop_stack: Vec::with_capacity(Self::LOOP_STACK_INITIAL_CAPACITY),
|
||||||
|
llvm_arguments,
|
||||||
|
|
||||||
dependency_manager,
|
dependency_manager,
|
||||||
include_metadata_hash,
|
include_metadata_hash,
|
||||||
@@ -639,6 +643,7 @@ where
|
|||||||
self.optimizer.settings().to_owned(),
|
self.optimizer.settings().to_owned(),
|
||||||
self.include_metadata_hash,
|
self.include_metadata_hash,
|
||||||
self.debug_config.clone(),
|
self.debug_config.clone(),
|
||||||
|
self.llvm_arguments,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,20 @@ pub fn create_context(
|
|||||||
llvm: &inkwell::context::Context,
|
llvm: &inkwell::context::Context,
|
||||||
optimizer_settings: OptimizerSettings,
|
optimizer_settings: OptimizerSettings,
|
||||||
) -> Context<DummyDependency> {
|
) -> Context<DummyDependency> {
|
||||||
crate::polkavm::initialize_target();
|
crate::initialize_llvm(crate::Target::PVM, "resolc", Default::default());
|
||||||
|
|
||||||
let module = llvm.create_module("test");
|
let module = llvm.create_module("test");
|
||||||
let optimizer = Optimizer::new(optimizer_settings);
|
let optimizer = Optimizer::new(optimizer_settings);
|
||||||
|
|
||||||
Context::<DummyDependency>::new(llvm, module, optimizer, None, true, Default::default())
|
Context::<DummyDependency>::new(
|
||||||
|
llvm,
|
||||||
|
module,
|
||||||
|
optimizer,
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -17,11 +17,6 @@ use sha3::Digest;
|
|||||||
use self::context::build::Build;
|
use self::context::build::Build;
|
||||||
use self::context::Context;
|
use self::context::Context;
|
||||||
|
|
||||||
/// Initializes the PolkaVM target machine.
|
|
||||||
pub fn initialize_target() {
|
|
||||||
inkwell::targets::Target::initialize_riscv(&Default::default());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds PolkaVM assembly text.
|
/// Builds PolkaVM assembly text.
|
||||||
pub fn build_assembly_text(
|
pub fn build_assembly_text(
|
||||||
contract_path: &str,
|
contract_path: &str,
|
||||||
@@ -94,6 +89,7 @@ pub trait Dependency {
|
|||||||
optimizer_settings: OptimizerSettings,
|
optimizer_settings: OptimizerSettings,
|
||||||
include_metadata_hash: bool,
|
include_metadata_hash: bool,
|
||||||
debug_config: DebugConfig,
|
debug_config: DebugConfig,
|
||||||
|
llvm_arguments: &[String],
|
||||||
) -> anyhow::Result<String>;
|
) -> anyhow::Result<String>;
|
||||||
|
|
||||||
/// Resolves a full contract path.
|
/// Resolves a full contract path.
|
||||||
@@ -114,6 +110,7 @@ impl Dependency for DummyDependency {
|
|||||||
_optimizer_settings: OptimizerSettings,
|
_optimizer_settings: OptimizerSettings,
|
||||||
_include_metadata_hash: bool,
|
_include_metadata_hash: bool,
|
||||||
_debug_config: DebugConfig,
|
_debug_config: DebugConfig,
|
||||||
|
_llvm_arguments: &[String],
|
||||||
) -> anyhow::Result<String> {
|
) -> anyhow::Result<String> {
|
||||||
Ok(String::new())
|
Ok(String::new())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ pub fn yul<T: Compiler>(
|
|||||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||||
include_metadata_hash: bool,
|
include_metadata_hash: bool,
|
||||||
debug_config: revive_llvm_context::DebugConfig,
|
debug_config: revive_llvm_context::DebugConfig,
|
||||||
|
llvm_arguments: &[String],
|
||||||
) -> anyhow::Result<Build> {
|
) -> anyhow::Result<Build> {
|
||||||
let path = match input_files.len() {
|
let path = match input_files.len() {
|
||||||
1 => input_files.first().expect("Always exists"),
|
1 => input_files.first().expect("Always exists"),
|
||||||
@@ -74,7 +75,12 @@ pub fn yul<T: Compiler>(
|
|||||||
let solc_validator = Some(&*solc);
|
let solc_validator = Some(&*solc);
|
||||||
let project = Project::try_from_yul_path(path, solc_validator)?;
|
let project = Project::try_from_yul_path(path, solc_validator)?;
|
||||||
|
|
||||||
let build = project.compile(optimizer_settings, include_metadata_hash, debug_config)?;
|
let build = project.compile(
|
||||||
|
optimizer_settings,
|
||||||
|
include_metadata_hash,
|
||||||
|
debug_config,
|
||||||
|
llvm_arguments,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(build)
|
Ok(build)
|
||||||
}
|
}
|
||||||
@@ -85,6 +91,7 @@ pub fn llvm_ir(
|
|||||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||||
include_metadata_hash: bool,
|
include_metadata_hash: bool,
|
||||||
debug_config: revive_llvm_context::DebugConfig,
|
debug_config: revive_llvm_context::DebugConfig,
|
||||||
|
llvm_arguments: &[String],
|
||||||
) -> anyhow::Result<Build> {
|
) -> anyhow::Result<Build> {
|
||||||
let path = match input_files.len() {
|
let path = match input_files.len() {
|
||||||
1 => input_files.first().expect("Always exists"),
|
1 => input_files.first().expect("Always exists"),
|
||||||
@@ -97,7 +104,12 @@ pub fn llvm_ir(
|
|||||||
|
|
||||||
let project = Project::try_from_llvm_ir_path(path)?;
|
let project = Project::try_from_llvm_ir_path(path)?;
|
||||||
|
|
||||||
let build = project.compile(optimizer_settings, include_metadata_hash, debug_config)?;
|
let build = project.compile(
|
||||||
|
optimizer_settings,
|
||||||
|
include_metadata_hash,
|
||||||
|
debug_config,
|
||||||
|
llvm_arguments,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(build)
|
Ok(build)
|
||||||
}
|
}
|
||||||
@@ -118,6 +130,7 @@ pub fn standard_output<T: Compiler>(
|
|||||||
remappings: Option<BTreeSet<String>>,
|
remappings: Option<BTreeSet<String>>,
|
||||||
suppressed_warnings: Option<Vec<ResolcWarning>>,
|
suppressed_warnings: Option<Vec<ResolcWarning>>,
|
||||||
debug_config: revive_llvm_context::DebugConfig,
|
debug_config: revive_llvm_context::DebugConfig,
|
||||||
|
llvm_arguments: &[String],
|
||||||
) -> anyhow::Result<Build> {
|
) -> anyhow::Result<Build> {
|
||||||
let solc_version = solc.version()?;
|
let solc_version = solc.version()?;
|
||||||
|
|
||||||
@@ -171,7 +184,12 @@ pub fn standard_output<T: Compiler>(
|
|||||||
&debug_config,
|
&debug_config,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let build = project.compile(optimizer_settings, include_metadata_hash, debug_config)?;
|
let build = project.compile(
|
||||||
|
optimizer_settings,
|
||||||
|
include_metadata_hash,
|
||||||
|
debug_config,
|
||||||
|
llvm_arguments,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(build)
|
Ok(build)
|
||||||
}
|
}
|
||||||
@@ -184,6 +202,7 @@ pub fn standard_json<T: Compiler>(
|
|||||||
include_paths: Vec<String>,
|
include_paths: Vec<String>,
|
||||||
allow_paths: Option<String>,
|
allow_paths: Option<String>,
|
||||||
debug_config: revive_llvm_context::DebugConfig,
|
debug_config: revive_llvm_context::DebugConfig,
|
||||||
|
llvm_arguments: &[String],
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let solc_version = solc.version()?;
|
let solc_version = solc.version()?;
|
||||||
|
|
||||||
@@ -226,7 +245,12 @@ pub fn standard_json<T: Compiler>(
|
|||||||
let missing_libraries = project.get_missing_libraries();
|
let missing_libraries = project.get_missing_libraries();
|
||||||
missing_libraries.write_to_standard_json(&mut solc_output, &solc_version)?;
|
missing_libraries.write_to_standard_json(&mut solc_output, &solc_version)?;
|
||||||
} else {
|
} else {
|
||||||
let build = project.compile(optimizer_settings, include_metadata_hash, debug_config)?;
|
let build = project.compile(
|
||||||
|
optimizer_settings,
|
||||||
|
include_metadata_hash,
|
||||||
|
debug_config,
|
||||||
|
llvm_arguments,
|
||||||
|
)?;
|
||||||
build.write_to_standard_json(&mut solc_output, &solc_version)?;
|
build.write_to_standard_json(&mut solc_output, &solc_version)?;
|
||||||
}
|
}
|
||||||
serde_json::to_writer(std::io::stdout(), &solc_output)?;
|
serde_json::to_writer(std::io::stdout(), &solc_output)?;
|
||||||
@@ -252,6 +276,7 @@ pub fn combined_json<T: Compiler>(
|
|||||||
debug_config: revive_llvm_context::DebugConfig,
|
debug_config: revive_llvm_context::DebugConfig,
|
||||||
output_directory: Option<PathBuf>,
|
output_directory: Option<PathBuf>,
|
||||||
overwrite: bool,
|
overwrite: bool,
|
||||||
|
llvm_arguments: &[String],
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let build = standard_output(
|
let build = standard_output(
|
||||||
input_files,
|
input_files,
|
||||||
@@ -267,6 +292,7 @@ pub fn combined_json<T: Compiler>(
|
|||||||
remappings,
|
remappings,
|
||||||
suppressed_warnings,
|
suppressed_warnings,
|
||||||
debug_config,
|
debug_config,
|
||||||
|
llvm_arguments,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut combined_json = solc.combined_json(input_files, format.as_str())?;
|
let mut combined_json = solc.combined_json(input_files, format.as_str())?;
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ pub struct Input {
|
|||||||
pub optimizer_settings: revive_llvm_context::OptimizerSettings,
|
pub optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||||
/// The debug output config.
|
/// The debug output config.
|
||||||
pub debug_config: revive_llvm_context::DebugConfig,
|
pub debug_config: revive_llvm_context::DebugConfig,
|
||||||
|
/// The extra LLVM arguments give used for manual control.
|
||||||
|
pub llvm_arguments: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input {
|
impl Input {
|
||||||
@@ -30,6 +32,7 @@ impl Input {
|
|||||||
include_metadata_hash: bool,
|
include_metadata_hash: bool,
|
||||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||||
debug_config: revive_llvm_context::DebugConfig,
|
debug_config: revive_llvm_context::DebugConfig,
|
||||||
|
llvm_arguments: Vec<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
contract,
|
contract,
|
||||||
@@ -37,6 +40,7 @@ impl Input {
|
|||||||
include_metadata_hash,
|
include_metadata_hash,
|
||||||
optimizer_settings,
|
optimizer_settings,
|
||||||
debug_config,
|
debug_config,
|
||||||
|
llvm_arguments,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,11 +37,19 @@ pub trait Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let input: Input = revive_common::deserialize_from_slice(buffer.as_slice())?;
|
let input: Input = revive_common::deserialize_from_slice(buffer.as_slice())?;
|
||||||
|
|
||||||
|
revive_llvm_context::initialize_llvm(
|
||||||
|
revive_llvm_context::Target::PVM,
|
||||||
|
crate::DEFAULT_EXECUTABLE_NAME,
|
||||||
|
&input.llvm_arguments,
|
||||||
|
);
|
||||||
|
|
||||||
let result = input.contract.compile(
|
let result = input.contract.compile(
|
||||||
input.project,
|
input.project,
|
||||||
input.optimizer_settings,
|
input.optimizer_settings,
|
||||||
input.include_metadata_hash,
|
input.include_metadata_hash,
|
||||||
input.debug_config,
|
input.debug_config,
|
||||||
|
&input.llvm_arguments,
|
||||||
);
|
);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ pub struct Metadata {
|
|||||||
pub revive_version: String,
|
pub revive_version: String,
|
||||||
/// The PolkaVM compiler optimizer settings.
|
/// The PolkaVM compiler optimizer settings.
|
||||||
pub optimizer_settings: revive_llvm_context::OptimizerSettings,
|
pub optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||||
|
/// The extra LLVM arguments give used for manual control.
|
||||||
|
pub llvm_arguments: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Metadata {
|
impl Metadata {
|
||||||
@@ -27,6 +29,7 @@ impl Metadata {
|
|||||||
solc_version: String,
|
solc_version: String,
|
||||||
revive_pallet_version: Option<semver::Version>,
|
revive_pallet_version: Option<semver::Version>,
|
||||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||||
|
llvm_arguments: Vec<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
solc_metadata,
|
solc_metadata,
|
||||||
@@ -34,6 +37,7 @@ impl Metadata {
|
|||||||
revive_pallet_version,
|
revive_pallet_version,
|
||||||
revive_version: ResolcVersion::default().long,
|
revive_version: ResolcVersion::default().long,
|
||||||
optimizer_settings,
|
optimizer_settings,
|
||||||
|
llvm_arguments,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ impl Contract {
|
|||||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||||
include_metadata_hash: bool,
|
include_metadata_hash: bool,
|
||||||
debug_config: revive_llvm_context::DebugConfig,
|
debug_config: revive_llvm_context::DebugConfig,
|
||||||
|
llvm_arguments: &[String],
|
||||||
) -> anyhow::Result<ContractBuild> {
|
) -> anyhow::Result<ContractBuild> {
|
||||||
let llvm = inkwell::context::Context::create();
|
let llvm = inkwell::context::Context::create();
|
||||||
let optimizer = revive_llvm_context::Optimizer::new(optimizer_settings);
|
let optimizer = revive_llvm_context::Optimizer::new(optimizer_settings);
|
||||||
@@ -89,6 +90,7 @@ impl Contract {
|
|||||||
version.long.clone(),
|
version.long.clone(),
|
||||||
version.l2_revision.clone(),
|
version.l2_revision.clone(),
|
||||||
optimizer.settings().to_owned(),
|
optimizer.settings().to_owned(),
|
||||||
|
llvm_arguments.to_vec(),
|
||||||
);
|
);
|
||||||
let metadata_json = serde_json::to_value(&metadata).expect("Always valid");
|
let metadata_json = serde_json::to_value(&metadata).expect("Always valid");
|
||||||
let metadata_hash: Option<[u8; revive_common::BYTE_LENGTH_WORD]> = if include_metadata_hash
|
let metadata_hash: Option<[u8; revive_common::BYTE_LENGTH_WORD]> = if include_metadata_hash
|
||||||
@@ -120,6 +122,7 @@ impl Contract {
|
|||||||
Some(project),
|
Some(project),
|
||||||
include_metadata_hash,
|
include_metadata_hash,
|
||||||
debug_config,
|
debug_config,
|
||||||
|
llvm_arguments,
|
||||||
);
|
);
|
||||||
context.set_solidity_data(revive_llvm_context::PolkaVMContextSolidityData::default());
|
context.set_solidity_data(revive_llvm_context::PolkaVMContextSolidityData::default());
|
||||||
match self.ir {
|
match self.ir {
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ impl Project {
|
|||||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||||
include_metadata_hash: bool,
|
include_metadata_hash: bool,
|
||||||
debug_config: revive_llvm_context::DebugConfig,
|
debug_config: revive_llvm_context::DebugConfig,
|
||||||
|
llvm_arguments: &[String],
|
||||||
) -> anyhow::Result<Build> {
|
) -> anyhow::Result<Build> {
|
||||||
let project = self.clone();
|
let project = self.clone();
|
||||||
#[cfg(feature = "parallel")]
|
#[cfg(feature = "parallel")]
|
||||||
@@ -81,6 +82,7 @@ impl Project {
|
|||||||
include_metadata_hash,
|
include_metadata_hash,
|
||||||
optimizer_settings.clone(),
|
optimizer_settings.clone(),
|
||||||
debug_config.clone(),
|
debug_config.clone(),
|
||||||
|
llvm_arguments.to_vec(),
|
||||||
);
|
);
|
||||||
let process_output = {
|
let process_output = {
|
||||||
#[cfg(target_os = "emscripten")]
|
#[cfg(target_os = "emscripten")]
|
||||||
@@ -316,6 +318,7 @@ impl revive_llvm_context::PolkaVMDependency for Project {
|
|||||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||||
include_metadata_hash: bool,
|
include_metadata_hash: bool,
|
||||||
debug_config: revive_llvm_context::DebugConfig,
|
debug_config: revive_llvm_context::DebugConfig,
|
||||||
|
llvm_arguments: &[String],
|
||||||
) -> anyhow::Result<String> {
|
) -> anyhow::Result<String> {
|
||||||
let contract_path = project.resolve_path(identifier)?;
|
let contract_path = project.resolve_path(identifier)?;
|
||||||
let contract = project
|
let contract = project
|
||||||
@@ -335,6 +338,7 @@ impl revive_llvm_context::PolkaVMDependency for Project {
|
|||||||
optimizer_settings,
|
optimizer_settings,
|
||||||
include_metadata_hash,
|
include_metadata_hash,
|
||||||
debug_config,
|
debug_config,
|
||||||
|
llvm_arguments,
|
||||||
)
|
)
|
||||||
.map_err(|error| {
|
.map_err(|error| {
|
||||||
anyhow::anyhow!(
|
anyhow::anyhow!(
|
||||||
|
|||||||
@@ -166,6 +166,10 @@ pub struct Arguments {
|
|||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
#[arg(long = "recursive-process-input")]
|
#[arg(long = "recursive-process-input")]
|
||||||
pub recursive_process_input: Option<String>,
|
pub recursive_process_input: Option<String>,
|
||||||
|
|
||||||
|
#[arg(long = "llvm-arg")]
|
||||||
|
/// These are passed to LLVM as the command line to allow manual control.
|
||||||
|
pub llvm_arguments: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Arguments {
|
impl Arguments {
|
||||||
|
|||||||
@@ -64,8 +64,6 @@ fn main_inner() -> anyhow::Result<()> {
|
|||||||
.stack_size(RAYON_WORKER_STACK_SIZE)
|
.stack_size(RAYON_WORKER_STACK_SIZE)
|
||||||
.build_global()
|
.build_global()
|
||||||
.expect("Thread pool configuration failure");
|
.expect("Thread pool configuration failure");
|
||||||
inkwell::support::enable_llvm_pretty_stack_trace();
|
|
||||||
revive_llvm_context::initialize_target(revive_llvm_context::Target::PVM); // TODO: pass from CLI
|
|
||||||
|
|
||||||
if arguments.recursive_process {
|
if arguments.recursive_process {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -157,6 +155,7 @@ fn main_inner() -> anyhow::Result<()> {
|
|||||||
optimizer_settings,
|
optimizer_settings,
|
||||||
include_metadata_hash,
|
include_metadata_hash,
|
||||||
debug_config,
|
debug_config,
|
||||||
|
&arguments.llvm_arguments,
|
||||||
)
|
)
|
||||||
} else if arguments.llvm_ir {
|
} else if arguments.llvm_ir {
|
||||||
revive_solidity::llvm_ir(
|
revive_solidity::llvm_ir(
|
||||||
@@ -164,6 +163,7 @@ fn main_inner() -> anyhow::Result<()> {
|
|||||||
optimizer_settings,
|
optimizer_settings,
|
||||||
include_metadata_hash,
|
include_metadata_hash,
|
||||||
debug_config,
|
debug_config,
|
||||||
|
&arguments.llvm_arguments,
|
||||||
)
|
)
|
||||||
} else if arguments.standard_json {
|
} else if arguments.standard_json {
|
||||||
revive_solidity::standard_json(
|
revive_solidity::standard_json(
|
||||||
@@ -173,6 +173,7 @@ fn main_inner() -> anyhow::Result<()> {
|
|||||||
arguments.include_paths,
|
arguments.include_paths,
|
||||||
arguments.allow_paths,
|
arguments.allow_paths,
|
||||||
debug_config,
|
debug_config,
|
||||||
|
&arguments.llvm_arguments,
|
||||||
)?;
|
)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if let Some(format) = arguments.combined_json {
|
} else if let Some(format) = arguments.combined_json {
|
||||||
@@ -193,6 +194,7 @@ fn main_inner() -> anyhow::Result<()> {
|
|||||||
debug_config,
|
debug_config,
|
||||||
arguments.output_directory,
|
arguments.output_directory,
|
||||||
arguments.overwrite,
|
arguments.overwrite,
|
||||||
|
&arguments.llvm_arguments,
|
||||||
)?;
|
)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
@@ -210,6 +212,7 @@ fn main_inner() -> anyhow::Result<()> {
|
|||||||
remappings,
|
remappings,
|
||||||
suppressed_warnings,
|
suppressed_warnings,
|
||||||
debug_config,
|
debug_config,
|
||||||
|
&arguments.llvm_arguments,
|
||||||
)
|
)
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,11 @@ pub fn build_solidity_with_options(
|
|||||||
check_dependencies();
|
check_dependencies();
|
||||||
|
|
||||||
inkwell::support::enable_llvm_pretty_stack_trace();
|
inkwell::support::enable_llvm_pretty_stack_trace();
|
||||||
revive_llvm_context::initialize_target(revive_llvm_context::Target::PVM);
|
revive_llvm_context::initialize_llvm(
|
||||||
|
revive_llvm_context::Target::PVM,
|
||||||
|
crate::DEFAULT_EXECUTABLE_NAME,
|
||||||
|
&[],
|
||||||
|
);
|
||||||
let _ = crate::process::native_process::EXECUTABLE
|
let _ = crate::process::native_process::EXECUTABLE
|
||||||
.set(PathBuf::from(crate::r#const::DEFAULT_EXECUTABLE_NAME));
|
.set(PathBuf::from(crate::r#const::DEFAULT_EXECUTABLE_NAME));
|
||||||
|
|
||||||
@@ -106,7 +110,8 @@ pub fn build_solidity_with_options(
|
|||||||
&DEBUG_CONFIG,
|
&DEBUG_CONFIG,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let build: crate::Build = project.compile(optimizer_settings, false, DEBUG_CONFIG)?;
|
let build: crate::Build =
|
||||||
|
project.compile(optimizer_settings, false, DEBUG_CONFIG, Default::default())?;
|
||||||
build.write_to_standard_json(&mut output, &solc_version)?;
|
build.write_to_standard_json(&mut output, &solc_version)?;
|
||||||
|
|
||||||
Ok(output)
|
Ok(output)
|
||||||
@@ -122,7 +127,11 @@ pub fn build_solidity_with_options_evm(
|
|||||||
check_dependencies();
|
check_dependencies();
|
||||||
|
|
||||||
inkwell::support::enable_llvm_pretty_stack_trace();
|
inkwell::support::enable_llvm_pretty_stack_trace();
|
||||||
revive_llvm_context::initialize_target(revive_llvm_context::Target::PVM);
|
revive_llvm_context::initialize_llvm(
|
||||||
|
revive_llvm_context::Target::PVM,
|
||||||
|
crate::DEFAULT_EXECUTABLE_NAME,
|
||||||
|
&[],
|
||||||
|
);
|
||||||
let _ = crate::process::native_process::EXECUTABLE
|
let _ = crate::process::native_process::EXECUTABLE
|
||||||
.set(PathBuf::from(crate::r#const::DEFAULT_EXECUTABLE_NAME));
|
.set(PathBuf::from(crate::r#const::DEFAULT_EXECUTABLE_NAME));
|
||||||
|
|
||||||
@@ -174,7 +183,11 @@ pub fn build_solidity_and_detect_missing_libraries(
|
|||||||
check_dependencies();
|
check_dependencies();
|
||||||
|
|
||||||
inkwell::support::enable_llvm_pretty_stack_trace();
|
inkwell::support::enable_llvm_pretty_stack_trace();
|
||||||
revive_llvm_context::initialize_target(revive_llvm_context::Target::PVM);
|
revive_llvm_context::initialize_llvm(
|
||||||
|
revive_llvm_context::Target::PVM,
|
||||||
|
crate::DEFAULT_EXECUTABLE_NAME,
|
||||||
|
&[],
|
||||||
|
);
|
||||||
let _ = crate::process::native_process::EXECUTABLE
|
let _ = crate::process::native_process::EXECUTABLE
|
||||||
.set(PathBuf::from(crate::r#const::DEFAULT_EXECUTABLE_NAME));
|
.set(PathBuf::from(crate::r#const::DEFAULT_EXECUTABLE_NAME));
|
||||||
|
|
||||||
@@ -213,7 +226,11 @@ pub fn build_yul(source_code: &str) -> anyhow::Result<()> {
|
|||||||
check_dependencies();
|
check_dependencies();
|
||||||
|
|
||||||
inkwell::support::enable_llvm_pretty_stack_trace();
|
inkwell::support::enable_llvm_pretty_stack_trace();
|
||||||
revive_llvm_context::initialize_target(revive_llvm_context::Target::PVM);
|
revive_llvm_context::initialize_llvm(
|
||||||
|
revive_llvm_context::Target::PVM,
|
||||||
|
crate::DEFAULT_EXECUTABLE_NAME,
|
||||||
|
&[],
|
||||||
|
);
|
||||||
let optimizer_settings = revive_llvm_context::OptimizerSettings::none();
|
let optimizer_settings = revive_llvm_context::OptimizerSettings::none();
|
||||||
|
|
||||||
let project = Project::try_from_yul_string::<SolcCompiler>(
|
let project = Project::try_from_yul_string::<SolcCompiler>(
|
||||||
@@ -221,7 +238,7 @@ pub fn build_yul(source_code: &str) -> anyhow::Result<()> {
|
|||||||
source_code,
|
source_code,
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
let _build = project.compile(optimizer_settings, false, DEBUG_CONFIG)?;
|
let _build = project.compile(optimizer_settings, false, DEBUG_CONFIG, Default::default())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user