mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-05-08 04:18:02 +00:00
configurable stack and heap memory size (#288)
- Allow configuration of the maximum heap and stack size via CLI flags and JSON input settings. - Increase the default value for the stack size to 32kb. --------- Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
@@ -55,6 +55,7 @@ pub fn yul<T: Compiler>(
|
||||
include_metadata_hash: bool,
|
||||
debug_config: revive_llvm_context::DebugConfig,
|
||||
llvm_arguments: &[String],
|
||||
memory_config: revive_llvm_context::MemoryConfig,
|
||||
) -> anyhow::Result<Build> {
|
||||
let path = match input_files.len() {
|
||||
1 => input_files.first().expect("Always exists"),
|
||||
@@ -80,6 +81,7 @@ pub fn yul<T: Compiler>(
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
llvm_arguments,
|
||||
memory_config,
|
||||
)?;
|
||||
|
||||
Ok(build)
|
||||
@@ -92,6 +94,7 @@ pub fn llvm_ir(
|
||||
include_metadata_hash: bool,
|
||||
debug_config: revive_llvm_context::DebugConfig,
|
||||
llvm_arguments: &[String],
|
||||
memory_config: revive_llvm_context::MemoryConfig,
|
||||
) -> anyhow::Result<Build> {
|
||||
let path = match input_files.len() {
|
||||
1 => input_files.first().expect("Always exists"),
|
||||
@@ -109,6 +112,7 @@ pub fn llvm_ir(
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
llvm_arguments,
|
||||
memory_config,
|
||||
)?;
|
||||
|
||||
Ok(build)
|
||||
@@ -131,6 +135,7 @@ pub fn standard_output<T: Compiler>(
|
||||
suppressed_warnings: Option<Vec<ResolcWarning>>,
|
||||
debug_config: revive_llvm_context::DebugConfig,
|
||||
llvm_arguments: &[String],
|
||||
memory_config: revive_llvm_context::MemoryConfig,
|
||||
) -> anyhow::Result<Build> {
|
||||
let solc_version = solc.version()?;
|
||||
|
||||
@@ -189,12 +194,14 @@ pub fn standard_output<T: Compiler>(
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
llvm_arguments,
|
||||
memory_config,
|
||||
)?;
|
||||
|
||||
Ok(build)
|
||||
}
|
||||
|
||||
/// Runs the standard JSON mode.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn standard_json<T: Compiler>(
|
||||
solc: &mut T,
|
||||
detect_missing_libraries: bool,
|
||||
@@ -203,6 +210,7 @@ pub fn standard_json<T: Compiler>(
|
||||
allow_paths: Option<String>,
|
||||
debug_config: revive_llvm_context::DebugConfig,
|
||||
llvm_arguments: &[String],
|
||||
memory_config: revive_llvm_context::MemoryConfig,
|
||||
) -> anyhow::Result<()> {
|
||||
let solc_version = solc.version()?;
|
||||
|
||||
@@ -250,6 +258,7 @@ pub fn standard_json<T: Compiler>(
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
llvm_arguments,
|
||||
memory_config,
|
||||
)?;
|
||||
build.write_to_standard_json(&mut solc_output, &solc_version)?;
|
||||
}
|
||||
@@ -277,6 +286,7 @@ pub fn combined_json<T: Compiler>(
|
||||
output_directory: Option<PathBuf>,
|
||||
overwrite: bool,
|
||||
llvm_arguments: &[String],
|
||||
memory_config: revive_llvm_context::MemoryConfig,
|
||||
) -> anyhow::Result<()> {
|
||||
let build = standard_output(
|
||||
input_files,
|
||||
@@ -293,6 +303,7 @@ pub fn combined_json<T: Compiler>(
|
||||
suppressed_warnings,
|
||||
debug_config,
|
||||
llvm_arguments,
|
||||
memory_config,
|
||||
)?;
|
||||
|
||||
let mut combined_json = solc.combined_json(input_files, format.as_str())?;
|
||||
|
||||
@@ -22,6 +22,8 @@ pub struct Input {
|
||||
pub debug_config: revive_llvm_context::DebugConfig,
|
||||
/// The extra LLVM arguments give used for manual control.
|
||||
pub llvm_arguments: Vec<String>,
|
||||
/// The PVM memory configuration.
|
||||
pub memory_config: revive_llvm_context::MemoryConfig,
|
||||
}
|
||||
|
||||
impl Input {
|
||||
@@ -33,6 +35,7 @@ impl Input {
|
||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
debug_config: revive_llvm_context::DebugConfig,
|
||||
llvm_arguments: Vec<String>,
|
||||
memory_config: revive_llvm_context::MemoryConfig,
|
||||
) -> Self {
|
||||
Self {
|
||||
contract,
|
||||
@@ -41,6 +44,7 @@ impl Input {
|
||||
optimizer_settings,
|
||||
debug_config,
|
||||
llvm_arguments,
|
||||
memory_config,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ pub trait Process {
|
||||
input.include_metadata_hash,
|
||||
input.debug_config,
|
||||
&input.llvm_arguments,
|
||||
input.memory_config,
|
||||
);
|
||||
|
||||
match result {
|
||||
|
||||
@@ -78,6 +78,7 @@ impl Contract {
|
||||
include_metadata_hash: bool,
|
||||
debug_config: revive_llvm_context::DebugConfig,
|
||||
llvm_arguments: &[String],
|
||||
memory_config: revive_llvm_context::MemoryConfig,
|
||||
) -> anyhow::Result<ContractBuild> {
|
||||
let llvm = inkwell::context::Context::create();
|
||||
let optimizer = revive_llvm_context::Optimizer::new(optimizer_settings);
|
||||
@@ -123,6 +124,7 @@ impl Contract {
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
llvm_arguments,
|
||||
memory_config,
|
||||
);
|
||||
context.set_solidity_data(revive_llvm_context::PolkaVMContextSolidityData::default());
|
||||
match self.ir {
|
||||
|
||||
@@ -67,6 +67,7 @@ impl Project {
|
||||
include_metadata_hash: bool,
|
||||
debug_config: revive_llvm_context::DebugConfig,
|
||||
llvm_arguments: &[String],
|
||||
memory_config: revive_llvm_context::MemoryConfig,
|
||||
) -> anyhow::Result<Build> {
|
||||
let project = self.clone();
|
||||
#[cfg(feature = "parallel")]
|
||||
@@ -83,6 +84,7 @@ impl Project {
|
||||
optimizer_settings.clone(),
|
||||
debug_config.clone(),
|
||||
llvm_arguments.to_vec(),
|
||||
memory_config,
|
||||
);
|
||||
let process_output = {
|
||||
#[cfg(target_os = "emscripten")]
|
||||
@@ -319,6 +321,7 @@ impl revive_llvm_context::PolkaVMDependency for Project {
|
||||
include_metadata_hash: bool,
|
||||
debug_config: revive_llvm_context::DebugConfig,
|
||||
llvm_arguments: &[String],
|
||||
memory_config: revive_llvm_context::MemoryConfig,
|
||||
) -> anyhow::Result<String> {
|
||||
let contract_path = project.resolve_path(identifier)?;
|
||||
let contract = project
|
||||
@@ -339,6 +342,7 @@ impl revive_llvm_context::PolkaVMDependency for Project {
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
llvm_arguments,
|
||||
memory_config,
|
||||
)
|
||||
.map_err(|error| {
|
||||
anyhow::anyhow!(
|
||||
|
||||
@@ -170,6 +170,38 @@ pub struct Arguments {
|
||||
/// These are passed to LLVM as the command line to allow manual control.
|
||||
#[arg(long = "llvm-arg")]
|
||||
pub llvm_arguments: Vec<String>,
|
||||
|
||||
/// The emulated EVM linear heap memory static buffer size in bytes.
|
||||
///
|
||||
/// Unlike the EVM, due to the lack of dynamic memory metering, PVM contracts emulate
|
||||
/// the EVM heap memory with a static buffer. Consequentially, instead of infinite
|
||||
/// memory with exponentially growing gas costs, PVM contracts have a finite amount
|
||||
/// of memory with constant gas costs available.
|
||||
///
|
||||
/// If the contract uses more heap memory than configured, it will compile fine but
|
||||
/// eventually revert execution at runtime!
|
||||
///
|
||||
/// You are incentiviced to keep this value as small as possible:
|
||||
/// 1.Increasing the heap size will increase startup costs.
|
||||
/// 2.The heap size contributes to the total memory size a contract can use,
|
||||
/// which includes the contracts code size
|
||||
#[arg(long = "heap-size", default_value = "65536")]
|
||||
pub heap_size: u32,
|
||||
|
||||
/// The contracts total stack size in bytes.
|
||||
///
|
||||
/// PVM is a register machine with a traditional stack memory space for local
|
||||
/// variables. This controls the total amount of stack space the contract can use.
|
||||
///
|
||||
/// If the contract uses more stack memory than configured, it will compile fine but
|
||||
/// eventually revert execution at runtime!
|
||||
///
|
||||
/// You are incentiviced to keep this value as small as possible:
|
||||
/// 1.Increasing the heap size will increase startup costs.
|
||||
/// 2.The stack size contributes to the total memory size a contract can use,
|
||||
/// which includes the contracts code size
|
||||
#[arg(long = "stack-size", default_value = "32768")]
|
||||
pub stack_size: u32,
|
||||
}
|
||||
|
||||
impl Arguments {
|
||||
|
||||
@@ -148,6 +148,11 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
None => true,
|
||||
};
|
||||
|
||||
let memory_config = revive_llvm_context::MemoryConfig {
|
||||
heap_size: arguments.heap_size,
|
||||
stack_size: arguments.stack_size,
|
||||
};
|
||||
|
||||
let build = if arguments.yul {
|
||||
revive_solidity::yul(
|
||||
input_files.as_slice(),
|
||||
@@ -156,6 +161,7 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
&arguments.llvm_arguments,
|
||||
memory_config,
|
||||
)
|
||||
} else if arguments.llvm_ir {
|
||||
revive_solidity::llvm_ir(
|
||||
@@ -164,6 +170,7 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
&arguments.llvm_arguments,
|
||||
memory_config,
|
||||
)
|
||||
} else if arguments.standard_json {
|
||||
revive_solidity::standard_json(
|
||||
@@ -174,6 +181,7 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
arguments.allow_paths,
|
||||
debug_config,
|
||||
&arguments.llvm_arguments,
|
||||
memory_config,
|
||||
)?;
|
||||
return Ok(());
|
||||
} else if let Some(format) = arguments.combined_json {
|
||||
@@ -195,6 +203,7 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
arguments.output_directory,
|
||||
arguments.overwrite,
|
||||
&arguments.llvm_arguments,
|
||||
memory_config,
|
||||
)?;
|
||||
return Ok(());
|
||||
} else {
|
||||
@@ -213,6 +222,7 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
suppressed_warnings,
|
||||
debug_config,
|
||||
&arguments.llvm_arguments,
|
||||
memory_config,
|
||||
)
|
||||
}?;
|
||||
|
||||
|
||||
@@ -115,8 +115,13 @@ pub fn build_solidity_with_options(
|
||||
&debug_config,
|
||||
)?;
|
||||
|
||||
let build: crate::Build =
|
||||
project.compile(optimizer_settings, false, debug_config, Default::default())?;
|
||||
let build: crate::Build = project.compile(
|
||||
optimizer_settings,
|
||||
false,
|
||||
debug_config,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
)?;
|
||||
build.write_to_standard_json(&mut output, &solc_version)?;
|
||||
|
||||
Ok(output)
|
||||
@@ -243,7 +248,13 @@ pub fn build_yul(source_code: &str) -> anyhow::Result<()> {
|
||||
source_code,
|
||||
None,
|
||||
)?;
|
||||
let _build = project.compile(optimizer_settings, false, DEBUG_CONFIG, Default::default())?;
|
||||
let _build = project.compile(
|
||||
optimizer_settings,
|
||||
false,
|
||||
DEBUG_CONFIG,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user