mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-12 02:31:02 +00:00
Merge remote-tracking branch 'origin/main' into resolc.js
This commit is contained in:
@@ -5,9 +5,10 @@ pub mod contract;
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::compiler::combined_json::CombinedJson;
|
||||
use crate::compiler::standard_json::output::Output as StandardJsonOutput;
|
||||
use crate::compiler::version::Version as SolcVersion;
|
||||
use crate::solc::combined_json::CombinedJson;
|
||||
use crate::solc::standard_json::output::Output as StandardJsonOutput;
|
||||
use crate::solc::version::Version as SolcVersion;
|
||||
use crate::ResolcVersion;
|
||||
|
||||
use self::contract::Contract;
|
||||
|
||||
@@ -40,11 +41,7 @@ impl Build {
|
||||
}
|
||||
|
||||
/// Writes all contracts assembly and bytecode to the combined JSON.
|
||||
pub fn write_to_combined_json(
|
||||
self,
|
||||
combined_json: &mut CombinedJson,
|
||||
resolc_version: &semver::Version,
|
||||
) -> anyhow::Result<()> {
|
||||
pub fn write_to_combined_json(self, combined_json: &mut CombinedJson) -> anyhow::Result<()> {
|
||||
for (path, contract) in self.contracts.into_iter() {
|
||||
let combined_json_contract = combined_json
|
||||
.contracts
|
||||
@@ -61,7 +58,7 @@ impl Build {
|
||||
contract.write_to_combined_json(combined_json_contract)?;
|
||||
}
|
||||
|
||||
combined_json.zk_version = Some(resolc_version.to_string());
|
||||
combined_json.revive_version = Some(ResolcVersion::default().long);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -71,7 +68,6 @@ impl Build {
|
||||
mut self,
|
||||
standard_json: &mut StandardJsonOutput,
|
||||
solc_version: &SolcVersion,
|
||||
resolc_version: &semver::Version,
|
||||
) -> anyhow::Result<()> {
|
||||
let contracts = match standard_json.contracts.as_mut() {
|
||||
Some(contracts) => contracts,
|
||||
@@ -90,7 +86,7 @@ impl Build {
|
||||
|
||||
standard_json.version = Some(solc_version.default.to_string());
|
||||
standard_json.long_version = Some(solc_version.long.to_owned());
|
||||
standard_json.zk_version = Some(resolc_version.to_string());
|
||||
standard_json.revive_version = Some(ResolcVersion::default().long);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -199,6 +199,7 @@ where
|
||||
revive_llvm_context::PolkaVMDummyLLVMWritable::default(),
|
||||
)
|
||||
.declare(context)?;
|
||||
revive_llvm_context::PolkaVMImmutableDataLoadFunction.declare(context)?;
|
||||
|
||||
entry.into_llvm(context)?;
|
||||
|
||||
@@ -266,6 +267,7 @@ where
|
||||
revive_llvm_context::PolkaVMCodeType::Runtime,
|
||||
))
|
||||
.into_llvm(context)?;
|
||||
revive_llvm_context::PolkaVMImmutableDataLoadFunction.into_llvm(context)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ impl Element {
|
||||
fn pop_arguments_llvm<'ctx, D>(
|
||||
&mut self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
|
||||
) -> Vec<inkwell::values::BasicValueEnum<'ctx>>
|
||||
) -> anyhow::Result<Vec<inkwell::values::BasicValueEnum<'ctx>>>
|
||||
where
|
||||
D: revive_llvm_context::PolkaVMDependency + Clone,
|
||||
{
|
||||
@@ -57,15 +57,13 @@ impl Element {
|
||||
[self.stack.elements.len() + input_size - output_size - 1 - index]
|
||||
.to_llvm()
|
||||
.into_pointer_value();
|
||||
let value = context
|
||||
.build_load(
|
||||
revive_llvm_context::PolkaVMPointer::new_stack_field(context, pointer),
|
||||
format!("argument_{index}").as_str(),
|
||||
)
|
||||
.unwrap();
|
||||
let value = context.build_load(
|
||||
revive_llvm_context::PolkaVMPointer::new_stack_field(context, pointer),
|
||||
format!("argument_{index}").as_str(),
|
||||
)?;
|
||||
arguments.push(value);
|
||||
}
|
||||
arguments
|
||||
Ok(arguments)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,7 +424,7 @@ where
|
||||
InstructionName::JUMPDEST => Ok(None),
|
||||
|
||||
InstructionName::ADD => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_arithmetic::addition(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -435,7 +433,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::SUB => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_arithmetic::subtraction(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -444,7 +442,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::MUL => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_arithmetic::multiplication(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -453,7 +451,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::DIV => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_arithmetic::division(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -462,7 +460,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::MOD => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_arithmetic::remainder(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -471,7 +469,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::SDIV => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_arithmetic::division_signed(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -480,7 +478,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::SMOD => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_arithmetic::remainder_signed(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -490,7 +488,7 @@ where
|
||||
}
|
||||
|
||||
InstructionName::LT => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_comparison::compare(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -500,7 +498,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::GT => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_comparison::compare(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -510,7 +508,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::EQ => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_comparison::compare(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -520,7 +518,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::ISZERO => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_comparison::compare(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -530,7 +528,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::SLT => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_comparison::compare(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -540,7 +538,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::SGT => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_comparison::compare(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -551,7 +549,7 @@ where
|
||||
}
|
||||
|
||||
InstructionName::OR => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_bitwise::or(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -560,7 +558,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::XOR => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_bitwise::xor(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -569,7 +567,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::NOT => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_bitwise::xor(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -578,7 +576,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::AND => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_bitwise::and(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -587,7 +585,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::SHL => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_bitwise::shift_left(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -596,7 +594,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::SHR => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_bitwise::shift_right(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -605,7 +603,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::SAR => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_bitwise::shift_right_arithmetic(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -614,7 +612,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::BYTE => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_bitwise::byte(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -624,7 +622,7 @@ where
|
||||
}
|
||||
|
||||
InstructionName::ADDMOD => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_math::add_mod(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -634,7 +632,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::MULMOD => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_math::mul_mod(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -644,7 +642,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::EXP => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_math::exponent(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -653,7 +651,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::SIGNEXTEND => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_math::sign_extend(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -663,7 +661,7 @@ where
|
||||
}
|
||||
|
||||
InstructionName::SHA3 | InstructionName::KECCAK256 => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_crypto::sha3(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -673,7 +671,7 @@ where
|
||||
}
|
||||
|
||||
InstructionName::MLOAD => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_memory::load(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -681,7 +679,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::MSTORE => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_memory::store(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -690,7 +688,7 @@ where
|
||||
.map(|_| None)
|
||||
}
|
||||
InstructionName::MSTORE8 => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_memory::store_byte(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -699,7 +697,7 @@ where
|
||||
.map(|_| None)
|
||||
}
|
||||
InstructionName::MCOPY => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
let destination = revive_llvm_context::PolkaVMPointer::new_with_offset(
|
||||
context,
|
||||
revive_llvm_context::PolkaVMAddressSpace::Heap,
|
||||
@@ -725,7 +723,7 @@ where
|
||||
}
|
||||
|
||||
InstructionName::SLOAD => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_storage::load(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -733,7 +731,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::SSTORE => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_storage::store(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -742,7 +740,7 @@ where
|
||||
.map(|_| None)
|
||||
}
|
||||
InstructionName::TLOAD => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_storage::transient_load(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -750,7 +748,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::TSTORE => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_storage::transient_store(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -766,27 +764,28 @@ where
|
||||
|
||||
let offset = context
|
||||
.solidity_mut()
|
||||
.get_or_allocate_immutable(key.as_str());
|
||||
.get_or_allocate_immutable(key.as_str())
|
||||
/ revive_common::BYTE_LENGTH_WORD;
|
||||
|
||||
let index = context.word_const(offset as u64);
|
||||
let index = context.xlen_type().const_int(offset as u64, false);
|
||||
revive_llvm_context::polkavm_evm_immutable::load(context, index).map(Some)
|
||||
}
|
||||
InstructionName::ASSIGNIMMUTABLE => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
|
||||
let key = self
|
||||
.instruction
|
||||
.value
|
||||
.ok_or_else(|| anyhow::anyhow!("Instruction value missing"))?;
|
||||
|
||||
let offset = context.solidity_mut().allocate_immutable(key.as_str());
|
||||
let offset = context.solidity_mut().allocate_immutable(key.as_str())
|
||||
/ revive_common::BYTE_LENGTH_WORD;
|
||||
|
||||
let index = context.word_const(offset as u64);
|
||||
let index = context.xlen_type().const_int(offset as u64, false);
|
||||
let value = arguments.pop().expect("Always exists").into_int_value();
|
||||
revive_llvm_context::polkavm_evm_immutable::store(context, index, value)
|
||||
.map(|_| None)
|
||||
}
|
||||
|
||||
InstructionName::CALLDATALOAD => {
|
||||
match context
|
||||
.code_type()
|
||||
@@ -796,7 +795,7 @@ where
|
||||
Ok(Some(context.word_const(0).as_basic_value_enum()))
|
||||
}
|
||||
revive_llvm_context::PolkaVMCodeType::Runtime => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_calldata::load(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -819,7 +818,7 @@ where
|
||||
}
|
||||
}
|
||||
InstructionName::CALLDATACOPY => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
|
||||
match context
|
||||
.code_type()
|
||||
@@ -862,7 +861,7 @@ where
|
||||
}
|
||||
}
|
||||
InstructionName::CODECOPY => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
|
||||
let parent = context.module().get_name().to_str().expect("Always valid");
|
||||
let source = &self.stack_input.elements[1];
|
||||
@@ -917,7 +916,7 @@ where
|
||||
revive_llvm_context::polkavm_evm_return_data::size(context).map(Some)
|
||||
}
|
||||
InstructionName::RETURNDATACOPY => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_return_data::copy(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -927,7 +926,7 @@ where
|
||||
.map(|_| None)
|
||||
}
|
||||
InstructionName::EXTCODESIZE => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_ext_code::size(
|
||||
context,
|
||||
Some(arguments[0].into_int_value()),
|
||||
@@ -935,7 +934,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::EXTCODEHASH => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_ext_code::hash(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -944,7 +943,7 @@ where
|
||||
}
|
||||
|
||||
InstructionName::RETURN => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_return::r#return(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -953,7 +952,7 @@ where
|
||||
.map(|_| None)
|
||||
}
|
||||
InstructionName::REVERT => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_return::revert(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
@@ -969,7 +968,7 @@ where
|
||||
}
|
||||
|
||||
InstructionName::LOG0 => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_event::log(
|
||||
context,
|
||||
arguments.remove(0).into_int_value(),
|
||||
@@ -982,7 +981,7 @@ where
|
||||
.map(|_| None)
|
||||
}
|
||||
InstructionName::LOG1 => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_event::log(
|
||||
context,
|
||||
arguments.remove(0).into_int_value(),
|
||||
@@ -995,7 +994,7 @@ where
|
||||
.map(|_| None)
|
||||
}
|
||||
InstructionName::LOG2 => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_event::log(
|
||||
context,
|
||||
arguments.remove(0).into_int_value(),
|
||||
@@ -1008,7 +1007,7 @@ where
|
||||
.map(|_| None)
|
||||
}
|
||||
InstructionName::LOG3 => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_event::log(
|
||||
context,
|
||||
arguments.remove(0).into_int_value(),
|
||||
@@ -1021,7 +1020,7 @@ where
|
||||
.map(|_| None)
|
||||
}
|
||||
InstructionName::LOG4 => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
revive_llvm_context::polkavm_evm_event::log(
|
||||
context,
|
||||
arguments.remove(0).into_int_value(),
|
||||
@@ -1035,7 +1034,7 @@ where
|
||||
}
|
||||
|
||||
InstructionName::CALL => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
|
||||
let gas = arguments.remove(0).into_int_value();
|
||||
let address = arguments.remove(0).into_int_value();
|
||||
@@ -1060,7 +1059,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::STATICCALL => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
|
||||
let gas = arguments.remove(0).into_int_value();
|
||||
let address = arguments.remove(0).into_int_value();
|
||||
@@ -1084,7 +1083,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::DELEGATECALL => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
|
||||
let gas = arguments.remove(0).into_int_value();
|
||||
let address = arguments.remove(0).into_int_value();
|
||||
@@ -1108,7 +1107,7 @@ where
|
||||
}
|
||||
|
||||
InstructionName::CREATE | InstructionName::ZK_CREATE => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
|
||||
let value = arguments[0].into_int_value();
|
||||
let input_offset = arguments[1].into_int_value();
|
||||
@@ -1119,18 +1118,19 @@ where
|
||||
value,
|
||||
input_offset,
|
||||
input_length,
|
||||
None,
|
||||
)
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::CREATE2 | InstructionName::ZK_CREATE2 => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
|
||||
let value = arguments[0].into_int_value();
|
||||
let input_offset = arguments[1].into_int_value();
|
||||
let input_length = arguments[2].into_int_value();
|
||||
let salt = arguments[3].into_int_value();
|
||||
|
||||
revive_llvm_context::polkavm_evm_create::create2(
|
||||
revive_llvm_context::polkavm_evm_create::create(
|
||||
context,
|
||||
value,
|
||||
input_offset,
|
||||
@@ -1154,12 +1154,14 @@ where
|
||||
revive_llvm_context::polkavm_evm_ether_gas::gas(context).map(Some)
|
||||
}
|
||||
InstructionName::BALANCE => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
|
||||
let address = arguments[0].into_int_value();
|
||||
revive_llvm_context::polkavm_evm_ether_gas::balance(context, address).map(Some)
|
||||
}
|
||||
InstructionName::SELFBALANCE => todo!(),
|
||||
InstructionName::SELFBALANCE => {
|
||||
revive_llvm_context::polkavm_evm_ether_gas::self_balance(context).map(Some)
|
||||
}
|
||||
|
||||
InstructionName::GASLIMIT => {
|
||||
revive_llvm_context::polkavm_evm_contract_context::gas_limit(context).map(Some)
|
||||
@@ -1181,7 +1183,7 @@ where
|
||||
revive_llvm_context::polkavm_evm_contract_context::block_number(context).map(Some)
|
||||
}
|
||||
InstructionName::BLOCKHASH => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
let arguments = self.pop_arguments_llvm(context)?;
|
||||
let index = arguments[0].into_int_value();
|
||||
|
||||
revive_llvm_context::polkavm_evm_contract_context::block_hash(context, index)
|
||||
@@ -1204,7 +1206,7 @@ where
|
||||
anyhow::bail!("The `BLOBBASEFEE` instruction is not supported until zkVM v1.5.0");
|
||||
}
|
||||
InstructionName::MSIZE => {
|
||||
revive_llvm_context::polkavm_evm_contract_context::msize(context).map(Some)
|
||||
revive_llvm_context::polkavm_evm_memory::msize(context).map(Some)
|
||||
}
|
||||
|
||||
InstructionName::CALLCODE => {
|
||||
@@ -1219,7 +1221,7 @@ where
|
||||
anyhow::bail!("The `EXTCODECOPY` instruction is not supported");
|
||||
}
|
||||
InstructionName::SELFDESTRUCT => {
|
||||
let _arguments = self.pop_arguments_llvm(context);
|
||||
let _arguments = self.pop_arguments_llvm(context)?;
|
||||
anyhow::bail!("The `SELFDESTRUCT` instruction is not supported");
|
||||
}
|
||||
|
||||
@@ -1231,7 +1233,7 @@ where
|
||||
return_address,
|
||||
..
|
||||
} => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
arguments.pop();
|
||||
arguments.reverse();
|
||||
arguments.pop();
|
||||
@@ -1294,7 +1296,7 @@ where
|
||||
return Ok(());
|
||||
}
|
||||
InstructionName::RecursiveReturn { .. } => {
|
||||
let mut arguments = self.pop_arguments_llvm(context);
|
||||
let mut arguments = self.pop_arguments_llvm(context)?;
|
||||
arguments.reverse();
|
||||
arguments.pop();
|
||||
|
||||
|
||||
@@ -1139,7 +1139,6 @@ where
|
||||
.integer_type(revive_common::BIT_LENGTH_BOOLEAN)
|
||||
.as_basic_type_enum()],
|
||||
output_size,
|
||||
false,
|
||||
);
|
||||
(r#type, output_size)
|
||||
}
|
||||
@@ -1156,7 +1155,6 @@ where
|
||||
input_size
|
||||
],
|
||||
output_size,
|
||||
false,
|
||||
);
|
||||
(r#type, output_size)
|
||||
}
|
||||
|
||||
+32
-54
@@ -8,6 +8,8 @@ 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;
|
||||
|
||||
@@ -46,6 +48,25 @@ 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")]
|
||||
pub mod libsolc;
|
||||
@@ -61,7 +82,6 @@ pub fn yul<T: Compiler>(
|
||||
input_files: &[PathBuf],
|
||||
solc: &mut T,
|
||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
is_system_mode: bool,
|
||||
include_metadata_hash: bool,
|
||||
debug_config: Option<revive_llvm_context::DebugConfig>,
|
||||
) -> anyhow::Result<Build> {
|
||||
@@ -74,28 +94,17 @@ pub fn yul<T: Compiler>(
|
||||
),
|
||||
};
|
||||
|
||||
let solc_validator = if is_system_mode {
|
||||
None
|
||||
} else {
|
||||
if solc.version()?.default != compiler::LAST_SUPPORTED_VERSION {
|
||||
anyhow::bail!(
|
||||
if solc.version()?.default != SolcCompiler::LAST_SUPPORTED_VERSION {
|
||||
anyhow::bail!(
|
||||
"The Yul mode is only supported with the most recent version of the Solidity compiler: {}",
|
||||
compiler::LAST_SUPPORTED_VERSION,
|
||||
);
|
||||
}
|
||||
|
||||
Some(&*solc)
|
||||
};
|
||||
}
|
||||
|
||||
let solc_validator = Some(&*solc);
|
||||
let project = Project::try_from_yul_path(path, solc_validator)?;
|
||||
|
||||
let build = project.compile(
|
||||
optimizer_settings,
|
||||
is_system_mode,
|
||||
include_metadata_hash,
|
||||
false,
|
||||
debug_config,
|
||||
)?;
|
||||
let build = project.compile(optimizer_settings, include_metadata_hash, debug_config)?;
|
||||
|
||||
Ok(build)
|
||||
}
|
||||
@@ -104,7 +113,6 @@ pub fn yul<T: Compiler>(
|
||||
pub fn llvm_ir(
|
||||
input_files: &[PathBuf],
|
||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
is_system_mode: bool,
|
||||
include_metadata_hash: bool,
|
||||
debug_config: Option<revive_llvm_context::DebugConfig>,
|
||||
) -> anyhow::Result<Build> {
|
||||
@@ -119,13 +127,7 @@ pub fn llvm_ir(
|
||||
|
||||
let project = Project::try_from_llvm_ir_path(path)?;
|
||||
|
||||
let build = project.compile(
|
||||
optimizer_settings,
|
||||
is_system_mode,
|
||||
include_metadata_hash,
|
||||
false,
|
||||
debug_config,
|
||||
)?;
|
||||
let build = project.compile(optimizer_settings, include_metadata_hash, debug_config)?;
|
||||
|
||||
Ok(build)
|
||||
}
|
||||
@@ -140,7 +142,6 @@ pub fn standard_output<T: Compiler>(
|
||||
solc_optimizer_enabled: bool,
|
||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
force_evmla: bool,
|
||||
is_system_mode: bool,
|
||||
include_metadata_hash: bool,
|
||||
base_path: Option<String>,
|
||||
include_paths: Vec<String>,
|
||||
@@ -164,7 +165,6 @@ pub fn standard_output<T: Compiler>(
|
||||
None,
|
||||
&solc_version.default,
|
||||
optimizer_settings.is_fallback_to_size_enabled(),
|
||||
optimizer_settings.is_system_request_memoization_disabled(),
|
||||
),
|
||||
None,
|
||||
solc_pipeline == SolcPipeline::Yul,
|
||||
@@ -210,13 +210,7 @@ pub fn standard_output<T: Compiler>(
|
||||
debug_config.as_ref(),
|
||||
)?;
|
||||
|
||||
let build = project.compile(
|
||||
optimizer_settings,
|
||||
is_system_mode,
|
||||
include_metadata_hash,
|
||||
false,
|
||||
debug_config,
|
||||
)?;
|
||||
let build = project.compile(optimizer_settings, include_metadata_hash, debug_config)?;
|
||||
|
||||
Ok(build)
|
||||
}
|
||||
@@ -227,7 +221,6 @@ pub fn standard_json<T: Compiler>(
|
||||
solc: &mut T,
|
||||
detect_missing_libraries: bool,
|
||||
force_evmla: bool,
|
||||
is_system_mode: bool,
|
||||
base_path: Option<String>,
|
||||
include_paths: Vec<String>,
|
||||
allow_paths: Option<String>,
|
||||
@@ -235,7 +228,6 @@ pub fn standard_json<T: Compiler>(
|
||||
) -> anyhow::Result<()> {
|
||||
let solc_version = solc.version()?;
|
||||
let solc_pipeline = SolcPipeline::new(&solc_version, force_evmla);
|
||||
let resolc_version = semver::Version::parse(env!("CARGO_PKG_VERSION")).expect("Always valid");
|
||||
|
||||
let solc_input = SolcStandardJsonInput::try_from_stdin(solc_pipeline)?;
|
||||
let source_code_files = solc_input
|
||||
@@ -282,20 +274,10 @@ pub fn standard_json<T: Compiler>(
|
||||
|
||||
if detect_missing_libraries {
|
||||
let missing_libraries = project.get_missing_libraries();
|
||||
missing_libraries.write_to_standard_json(
|
||||
&mut solc_output,
|
||||
&solc_version,
|
||||
&resolc_version,
|
||||
)?;
|
||||
missing_libraries.write_to_standard_json(&mut solc_output, &solc_version)?;
|
||||
} else {
|
||||
let build = project.compile(
|
||||
optimizer_settings,
|
||||
is_system_mode,
|
||||
include_metadata_hash,
|
||||
false,
|
||||
debug_config,
|
||||
)?;
|
||||
build.write_to_standard_json(&mut solc_output, &solc_version, &resolc_version)?;
|
||||
let build = project.compile(optimizer_settings, include_metadata_hash, debug_config)?;
|
||||
build.write_to_standard_json(&mut solc_output, &solc_version)?;
|
||||
}
|
||||
serde_json::to_writer(std::io::stdout(), &solc_output)?;
|
||||
std::process::exit(0);
|
||||
@@ -312,7 +294,6 @@ pub fn combined_json<T: Compiler>(
|
||||
solc_optimizer_enabled: bool,
|
||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
force_evmla: bool,
|
||||
is_system_mode: bool,
|
||||
include_metadata_hash: bool,
|
||||
base_path: Option<String>,
|
||||
include_paths: Vec<String>,
|
||||
@@ -323,8 +304,6 @@ pub fn combined_json<T: Compiler>(
|
||||
output_directory: Option<PathBuf>,
|
||||
overwrite: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
let resolc_version = semver::Version::parse(env!("CARGO_PKG_VERSION")).expect("Always valid");
|
||||
|
||||
let build = standard_output(
|
||||
input_files,
|
||||
libraries,
|
||||
@@ -333,7 +312,6 @@ pub fn combined_json<T: Compiler>(
|
||||
solc_optimizer_enabled,
|
||||
optimizer_settings,
|
||||
force_evmla,
|
||||
is_system_mode,
|
||||
include_metadata_hash,
|
||||
base_path,
|
||||
include_paths,
|
||||
@@ -344,7 +322,7 @@ pub fn combined_json<T: Compiler>(
|
||||
)?;
|
||||
|
||||
let mut combined_json = solc.combined_json(input_files, format.as_str())?;
|
||||
build.write_to_combined_json(&mut combined_json, &resolc_version)?;
|
||||
build.write_to_combined_json(&mut combined_json)?;
|
||||
|
||||
match output_directory {
|
||||
Some(output_directory) => {
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::compiler::standard_json::output::Output as StandardJsonOutput;
|
||||
use crate::compiler::version::Version as SolcVersion;
|
||||
use crate::solc::standard_json::output::Output as StandardJsonOutput;
|
||||
use crate::solc::version::Version as SolcVersion;
|
||||
use crate::ResolcVersion;
|
||||
|
||||
/// The missing Solidity libraries.
|
||||
pub struct MissingLibraries {
|
||||
@@ -23,7 +24,6 @@ impl MissingLibraries {
|
||||
mut self,
|
||||
standard_json: &mut StandardJsonOutput,
|
||||
solc_version: &SolcVersion,
|
||||
resolc_version: &semver::Version,
|
||||
) -> anyhow::Result<()> {
|
||||
let contracts = match standard_json.contracts.as_mut() {
|
||||
Some(contracts) => contracts,
|
||||
@@ -43,7 +43,7 @@ impl MissingLibraries {
|
||||
|
||||
standard_json.version = Some(solc_version.default.to_string());
|
||||
standard_json.long_version = Some(solc_version.long.to_owned());
|
||||
standard_json.zk_version = Some(resolc_version.to_string());
|
||||
standard_json.revive_version = Some(ResolcVersion::default().long);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -14,12 +14,8 @@ pub struct Input {
|
||||
pub contract: Contract,
|
||||
/// The project representation.
|
||||
pub project: Project,
|
||||
/// The system mode flag.
|
||||
pub is_system_mode: bool,
|
||||
/// Whether to append the metadata hash.
|
||||
pub include_metadata_hash: bool,
|
||||
/// Enables the test bytecode encoding.
|
||||
pub enable_test_encoding: bool,
|
||||
/// The optimizer settings.
|
||||
pub optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
/// The debug output config.
|
||||
@@ -31,18 +27,14 @@ impl Input {
|
||||
pub fn new(
|
||||
contract: Contract,
|
||||
project: Project,
|
||||
is_system_mode: bool,
|
||||
include_metadata_hash: bool,
|
||||
enable_test_encoding: bool,
|
||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
debug_config: Option<revive_llvm_context::DebugConfig>,
|
||||
) -> Self {
|
||||
Self {
|
||||
contract,
|
||||
project,
|
||||
is_system_mode,
|
||||
include_metadata_hash,
|
||||
enable_test_encoding,
|
||||
optimizer_settings,
|
||||
debug_config,
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::ResolcVersion;
|
||||
|
||||
/// The Solidity contract metadata.
|
||||
/// Is used to append the metadata hash to the contract bytecode.
|
||||
#[derive(Debug, Serialize)]
|
||||
@@ -9,11 +11,11 @@ pub struct Metadata {
|
||||
/// The `solc` metadata.
|
||||
pub solc_metadata: serde_json::Value,
|
||||
/// The `solc` version.
|
||||
pub solc_version: semver::Version,
|
||||
/// The zkVM `solc` edition.
|
||||
pub solc_zkvm_edition: Option<semver::Version>,
|
||||
pub solc_version: String,
|
||||
/// The pallet revive edition.
|
||||
pub revive_pallet_version: Option<semver::Version>,
|
||||
/// The PolkaVM compiler version.
|
||||
pub zk_version: semver::Version,
|
||||
pub revive_version: String,
|
||||
/// The PolkaVM compiler optimizer settings.
|
||||
pub optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
}
|
||||
@@ -22,16 +24,15 @@ impl Metadata {
|
||||
/// A shortcut constructor.
|
||||
pub fn new(
|
||||
solc_metadata: serde_json::Value,
|
||||
solc_version: semver::Version,
|
||||
solc_zkvm_edition: Option<semver::Version>,
|
||||
zk_version: semver::Version,
|
||||
solc_version: String,
|
||||
revive_pallet_version: Option<semver::Version>,
|
||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
) -> Self {
|
||||
Self {
|
||||
solc_metadata,
|
||||
solc_version,
|
||||
solc_zkvm_edition,
|
||||
zk_version,
|
||||
revive_pallet_version,
|
||||
revive_version: ResolcVersion::default().long,
|
||||
optimizer_settings,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,6 @@ impl Contract {
|
||||
mut self,
|
||||
project: Project,
|
||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
is_system_mode: bool,
|
||||
include_metadata_hash: bool,
|
||||
debug_config: Option<revive_llvm_context::DebugConfig>,
|
||||
) -> anyhow::Result<ContractBuild> {
|
||||
@@ -90,9 +89,8 @@ impl Contract {
|
||||
|
||||
let metadata = Metadata::new(
|
||||
self.metadata_json.take(),
|
||||
version.default.clone(),
|
||||
version.long.clone(),
|
||||
version.l2_revision.clone(),
|
||||
semver::Version::parse(env!("CARGO_PKG_VERSION")).expect("Always valid"),
|
||||
optimizer.settings().to_owned(),
|
||||
);
|
||||
let metadata_json = serde_json::to_value(&metadata).expect("Always valid");
|
||||
@@ -127,8 +125,7 @@ impl Contract {
|
||||
context.set_solidity_data(revive_llvm_context::PolkaVMContextSolidityData::default());
|
||||
match self.ir {
|
||||
IR::Yul(_) => {
|
||||
let yul_data = revive_llvm_context::PolkaVMContextYulData::new(is_system_mode);
|
||||
context.set_yul_data(yul_data);
|
||||
context.set_yul_data(Default::default());
|
||||
}
|
||||
IR::EVMLA(_) => {
|
||||
let evmla_data = revive_llvm_context::PolkaVMContextEVMLAData::new(version.default);
|
||||
|
||||
@@ -64,9 +64,7 @@ impl Project {
|
||||
pub fn compile(
|
||||
self,
|
||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
is_system_mode: bool,
|
||||
include_metadata_hash: bool,
|
||||
bytecode_encoding_testing: bool,
|
||||
debug_config: Option<revive_llvm_context::DebugConfig>,
|
||||
) -> anyhow::Result<Build> {
|
||||
let project = self.clone();
|
||||
@@ -80,9 +78,7 @@ impl Project {
|
||||
let process_input = ProcessInput::new(
|
||||
contract,
|
||||
project.clone(),
|
||||
is_system_mode,
|
||||
include_metadata_hash,
|
||||
bytecode_encoding_testing,
|
||||
optimizer_settings.clone(),
|
||||
debug_config.clone(),
|
||||
);
|
||||
@@ -255,7 +251,6 @@ impl revive_llvm_context::PolkaVMDependency for Project {
|
||||
project: Self,
|
||||
identifier: &str,
|
||||
optimizer_settings: revive_llvm_context::OptimizerSettings,
|
||||
is_system_mode: bool,
|
||||
include_metadata_hash: bool,
|
||||
debug_config: Option<revive_llvm_context::DebugConfig>,
|
||||
) -> anyhow::Result<String> {
|
||||
@@ -275,7 +270,6 @@ impl revive_llvm_context::PolkaVMDependency for Project {
|
||||
.compile(
|
||||
project,
|
||||
optimizer_settings,
|
||||
is_system_mode,
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
)
|
||||
|
||||
@@ -58,10 +58,6 @@ pub struct Arguments {
|
||||
#[structopt(long = "fallback-Oz")]
|
||||
pub fallback_to_optimizing_for_size: bool,
|
||||
|
||||
/// Disable the system request memoization.
|
||||
#[structopt(long = "disable-system-request-memoization")]
|
||||
pub disable_system_request_memoization: bool,
|
||||
|
||||
/// Disable the `solc` optimizer.
|
||||
/// Use it if your project uses the `MSIZE` instruction, or in other cases.
|
||||
/// Beware that it will prevent libraries from being inlined.
|
||||
@@ -75,7 +71,7 @@ pub struct Arguments {
|
||||
pub solc: Option<String>,
|
||||
|
||||
/// The EVM target version to generate IR for.
|
||||
/// See https://github.com/xermicus/revive/blob/main/crates/common/src/evm_version.rs for reference.
|
||||
/// See https://github.com/paritytech/revive/blob/main/crates/common/src/evm_version.rs for reference.
|
||||
#[structopt(long = "evm-version")]
|
||||
pub evm_version: Option<String>,
|
||||
|
||||
@@ -119,13 +115,6 @@ pub struct Arguments {
|
||||
#[structopt(long = "force-evmla")]
|
||||
pub force_evmla: bool,
|
||||
|
||||
/// Enable system contract compilation mode.
|
||||
/// In this mode PolkaVM extensions are enabled. For example, calls to addresses `0xFFFF` and below
|
||||
/// are substituted by special PolkaVM instructions.
|
||||
/// In the Yul mode, the `verbatim_*` instruction family is available.
|
||||
#[structopt(long = "system-mode")]
|
||||
pub is_system_mode: bool,
|
||||
|
||||
/// Set metadata hash mode.
|
||||
/// The only supported value is `none` that disables appending the metadata hash.
|
||||
/// Is enabled by default.
|
||||
@@ -185,6 +174,20 @@ impl Arguments {
|
||||
anyhow::bail!("No other options are allowed while getting the compiler version.");
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
if self.recursive_process_input.is_some() && !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.is_none() && std::env::args().count() > 2)
|
||||
|| (self.recursive_process_input.is_some() && 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.");
|
||||
}
|
||||
@@ -243,12 +246,6 @@ impl Arguments {
|
||||
if self.solc.is_some() {
|
||||
anyhow::bail!("`solc` is not used in LLVM IR and PolkaVM assembly modes.");
|
||||
}
|
||||
|
||||
if self.is_system_mode {
|
||||
anyhow::bail!(
|
||||
"System contract mode is not supported in LLVM IR and PolkaVM assembly modes."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if self.combined_json.is_some() {
|
||||
@@ -295,11 +292,6 @@ impl Arguments {
|
||||
"Falling back to -Oz must specified in standard JSON input settings."
|
||||
);
|
||||
}
|
||||
if self.disable_system_request_memoization {
|
||||
anyhow::bail!(
|
||||
"Disabling the system request memoization must specified in standard JSON input settings."
|
||||
);
|
||||
}
|
||||
if self.metadata_hash.is_some() {
|
||||
anyhow::bail!("Metadata hash mode must specified in standard JSON input settings.");
|
||||
}
|
||||
|
||||
@@ -34,10 +34,9 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
|
||||
if arguments.version {
|
||||
println!(
|
||||
"{} v{} (LLVM build {:?})",
|
||||
"{} version {}",
|
||||
env!("CARGO_PKG_DESCRIPTION"),
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
inkwell::support::get_llvm_version()
|
||||
revive_solidity::ResolcVersion::default().long
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
@@ -106,9 +105,6 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
if arguments.fallback_to_optimizing_for_size {
|
||||
optimizer_settings.enable_fallback_to_size();
|
||||
}
|
||||
if arguments.disable_system_request_memoization {
|
||||
optimizer_settings.disable_system_request_memoization();
|
||||
}
|
||||
optimizer_settings.is_verify_each_enabled = arguments.llvm_verify_each;
|
||||
optimizer_settings.is_debug_logging_enabled = arguments.llvm_debug_logging;
|
||||
|
||||
@@ -126,7 +122,6 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
input_files.as_slice(),
|
||||
&mut solc,
|
||||
optimizer_settings,
|
||||
arguments.is_system_mode,
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
)
|
||||
@@ -134,7 +129,6 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
revive_solidity::llvm_ir(
|
||||
input_files.as_slice(),
|
||||
optimizer_settings,
|
||||
arguments.is_system_mode,
|
||||
include_metadata_hash,
|
||||
debug_config,
|
||||
)
|
||||
@@ -143,7 +137,6 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
&mut solc,
|
||||
arguments.detect_missing_libraries,
|
||||
arguments.force_evmla,
|
||||
arguments.is_system_mode,
|
||||
arguments.base_path,
|
||||
arguments.include_paths,
|
||||
arguments.allow_paths,
|
||||
@@ -160,7 +153,6 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
!arguments.disable_solc_optimizer,
|
||||
optimizer_settings,
|
||||
arguments.force_evmla,
|
||||
arguments.is_system_mode,
|
||||
include_metadata_hash,
|
||||
arguments.base_path,
|
||||
arguments.include_paths,
|
||||
@@ -181,7 +173,6 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
!arguments.disable_solc_optimizer,
|
||||
optimizer_settings,
|
||||
arguments.force_evmla,
|
||||
arguments.is_system_mode,
|
||||
include_metadata_hash,
|
||||
arguments.base_path,
|
||||
arguments.include_paths,
|
||||
|
||||
@@ -28,7 +28,7 @@ pub struct CombinedJson {
|
||||
pub version: String,
|
||||
/// The `resolc` compiler version.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub zk_version: Option<String>,
|
||||
pub revive_version: Option<String>,
|
||||
}
|
||||
|
||||
impl CombinedJson {
|
||||
|
||||
@@ -37,7 +37,7 @@ impl Compiler {
|
||||
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, 26);
|
||||
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
|
||||
@@ -129,7 +129,6 @@ impl Compiler {
|
||||
)
|
||||
})?;
|
||||
output.preprocess_ast(&version, pipeline, suppressed_warnings.as_slice())?;
|
||||
output.remove_evm();
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
//! The Solidity compiler pipeline type.
|
||||
|
||||
use crate::compiler;
|
||||
use crate::compiler::version::Version as SolcVersion;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::solc::version::Version as SolcVersion;
|
||||
use crate::solc::Compiler as SolcCompiler;
|
||||
|
||||
/// The Solidity compiler pipeline type.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub enum Pipeline {
|
||||
|
||||
@@ -22,9 +22,6 @@ pub struct Optimizer {
|
||||
/// Whether to try to recompile with -Oz if the bytecode is too large.
|
||||
#[serde(skip_serializing)]
|
||||
pub fallback_to_optimizing_for_size: Option<bool>,
|
||||
/// Whether to disable the system request memoization.
|
||||
#[serde(skip_serializing)]
|
||||
pub disable_system_request_memoization: Option<bool>,
|
||||
}
|
||||
|
||||
impl Optimizer {
|
||||
@@ -34,14 +31,12 @@ impl Optimizer {
|
||||
mode: Option<char>,
|
||||
version: &semver::Version,
|
||||
fallback_to_optimizing_for_size: bool,
|
||||
disable_system_request_memoization: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
enabled,
|
||||
mode,
|
||||
details: Some(Details::disabled(version)),
|
||||
fallback_to_optimizing_for_size: Some(fallback_to_optimizing_for_size),
|
||||
disable_system_request_memoization: Some(disable_system_request_memoization),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,9 +61,6 @@ impl TryFrom<&Optimizer> for revive_llvm_context::OptimizerSettings {
|
||||
if value.fallback_to_optimizing_for_size.unwrap_or_default() {
|
||||
result.enable_fallback_to_size();
|
||||
}
|
||||
if value.disable_system_request_memoization.unwrap_or_default() {
|
||||
result.disable_system_request_memoization();
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,8 +37,13 @@ pub enum Flag {
|
||||
/// The EVM legacy assembly JSON.
|
||||
#[serde(rename = "evm.legacyAssembly")]
|
||||
EVMLA,
|
||||
#[serde(rename = "evm.bytecode")]
|
||||
EVMBC,
|
||||
#[serde(rename = "evm.deployedBytecode")]
|
||||
EVMDBC,
|
||||
/// The assembly code
|
||||
#[serde(rename = "evm.assembly")]
|
||||
Assembly,
|
||||
}
|
||||
|
||||
impl From<SolcPipeline> for Flag {
|
||||
@@ -62,7 +67,9 @@ impl std::fmt::Display for Flag {
|
||||
Self::AST => write!(f, "ast"),
|
||||
Self::Yul => write!(f, "irOptimized"),
|
||||
Self::EVMLA => write!(f, "evm.legacyAssembly"),
|
||||
Self::EVMBC => write!(f, "evm.bytecode"),
|
||||
Self::EVMDBC => write!(f, "evm.deployedBytecode"),
|
||||
Self::Assembly => write!(f, "evm.assembly"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ impl File {
|
||||
Self {
|
||||
per_file: Some(HashSet::from_iter([SelectionFlag::AST])),
|
||||
per_contract: Some(HashSet::from_iter([
|
||||
SelectionFlag::EVMBC,
|
||||
SelectionFlag::EVMDBC,
|
||||
SelectionFlag::MethodIdentifiers,
|
||||
SelectionFlag::Metadata,
|
||||
|
||||
@@ -20,15 +20,19 @@ use self::extra_metadata::ExtraMetadata;
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EVM {
|
||||
/// The contract EVM legacy assembly code.
|
||||
#[serde(rename = "legacyAssembly")]
|
||||
#[serde(rename = "legacyAssembly", skip_serializing_if = "Option::is_none")]
|
||||
pub assembly: Option<Assembly>,
|
||||
/// The contract PolkaVM assembly code.
|
||||
#[serde(rename = "assembly")]
|
||||
#[serde(rename = "assembly", skip_serializing_if = "Option::is_none")]
|
||||
pub assembly_text: Option<String>,
|
||||
/// The contract bytecode.
|
||||
/// Is reset by that of PolkaVM before yielding the compiled project artifacts.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub bytecode: Option<Bytecode>,
|
||||
/// The contract deployed bytecode.
|
||||
/// The deployed bytecode of the contract.
|
||||
/// It is overwritten with the PolkaVM blob before yielding the compiled project artifacts.
|
||||
/// Hence it will be the same as the runtime code but we keep both for compatibility reasons.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub deployed_bytecode: Option<DeployedBytecode>,
|
||||
/// The contract function signatures.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
@@ -42,6 +46,7 @@ impl EVM {
|
||||
/// Sets the PolkaVM assembly and bytecode.
|
||||
pub fn modify(&mut self, assembly_text: String, bytecode: String) {
|
||||
self.assembly_text = Some(assembly_text);
|
||||
self.bytecode = Some(Bytecode::new(bytecode));
|
||||
self.bytecode = Some(Bytecode::new(bytecode.clone()));
|
||||
self.deployed_bytecode = Some(DeployedBytecode::new(bytecode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ pub struct Output {
|
||||
pub long_version: Option<String>,
|
||||
/// The `resolc` compiler version.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub zk_version: Option<String>,
|
||||
pub revive_version: Option<String>,
|
||||
}
|
||||
|
||||
impl Output {
|
||||
@@ -138,19 +138,6 @@ impl Output {
|
||||
))
|
||||
}
|
||||
|
||||
/// Removes EVM artifacts to prevent their accidental usage.
|
||||
pub fn remove_evm(&mut self) {
|
||||
if let Some(files) = self.contracts.as_mut() {
|
||||
for (_, file) in files.iter_mut() {
|
||||
for (_, contract) in file.iter_mut() {
|
||||
if let Some(evm) = contract.evm.as_mut() {
|
||||
evm.bytecode = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Traverses the AST and returns the list of additional errors and warnings.
|
||||
pub fn preprocess_ast(
|
||||
&mut self,
|
||||
|
||||
@@ -3,6 +3,9 @@ use std::collections::BTreeMap;
|
||||
use std::collections::BTreeSet;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::compiler::pipeline::Pipeline as SolcPipeline;
|
||||
use crate::compiler::solc::SolcCompiler;
|
||||
@@ -14,6 +17,27 @@ use crate::compiler::standard_json::output::Output as SolcStandardJsonOutput;
|
||||
use crate::compiler::Compiler;
|
||||
use crate::project::Project;
|
||||
use crate::warning::Warning;
|
||||
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::warning::Warning;
|
||||
|
||||
static PVM_BLOB_CACHE: Lazy<Mutex<HashMap<CachedBlob, Vec<u8>>>> = Lazy::new(Default::default);
|
||||
static EVM_BLOB_CACHE: Lazy<Mutex<HashMap<CachedBlob, Vec<u8>>>> = Lazy::new(Default::default);
|
||||
static EVM_RUNTIME_BLOB_CACHE: Lazy<Mutex<HashMap<CachedBlob, Vec<u8>>>> =
|
||||
Lazy::new(Default::default);
|
||||
|
||||
#[derive(Hash, PartialEq, Eq)]
|
||||
struct CachedBlob {
|
||||
contract_name: String,
|
||||
solc_optimizer_enabled: bool,
|
||||
pipeline: SolcPipeline,
|
||||
}
|
||||
|
||||
/// Checks if the required executables are present in `${PATH}`.
|
||||
fn check_dependencies() {
|
||||
@@ -80,7 +104,6 @@ pub fn build_solidity_with_options(
|
||||
None,
|
||||
&solc_version.default,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
None,
|
||||
pipeline == SolcPipeline::Yul,
|
||||
@@ -91,24 +114,20 @@ pub fn build_solidity_with_options(
|
||||
|
||||
let project = output.try_to_project(sources, libraries, pipeline, &solc_version, None)?;
|
||||
|
||||
let build: crate::Build = project.compile(optimizer_settings, false, false, false, None)?;
|
||||
build.write_to_standard_json(
|
||||
&mut output,
|
||||
&solc_version,
|
||||
&semver::Version::from_str(env!("CARGO_PKG_VERSION"))?,
|
||||
)?;
|
||||
let build: crate::Build = project.compile(optimizer_settings, false, None)?;
|
||||
build.write_to_standard_json(&mut output, &solc_version)?;
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
/// Build a Solidity contract and get the EVM bin-runtime.
|
||||
/// Build a Solidity contract and get the EVM code
|
||||
pub fn build_solidity_with_options_evm(
|
||||
sources: BTreeMap<String, String>,
|
||||
libraries: BTreeMap<String, BTreeMap<String, String>>,
|
||||
remappings: Option<BTreeSet<String>>,
|
||||
pipeline: SolcPipeline,
|
||||
solc_optimizer_enabled: bool,
|
||||
) -> anyhow::Result<BTreeMap<String, DeployedBytecode>> {
|
||||
) -> anyhow::Result<BTreeMap<String, (Bytecode, DeployedBytecode)>> {
|
||||
check_dependencies();
|
||||
|
||||
inkwell::support::enable_llvm_pretty_stack_trace();
|
||||
@@ -130,7 +149,6 @@ pub fn build_solidity_with_options_evm(
|
||||
None,
|
||||
&solc_version.default,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
None,
|
||||
pipeline == SolcPipeline::Yul,
|
||||
@@ -144,9 +162,12 @@ pub fn build_solidity_with_options_evm(
|
||||
for (_, file) in files.iter_mut() {
|
||||
for (name, contract) in file.iter_mut() {
|
||||
if let Some(evm) = contract.evm.as_mut() {
|
||||
if let Some(deployed_bytecode) = evm.deployed_bytecode.as_ref() {
|
||||
contracts.insert(name.clone(), deployed_bytecode.clone());
|
||||
}
|
||||
let (Some(bytecode), Some(deployed_bytecode)) =
|
||||
(evm.bytecode.as_ref(), evm.deployed_bytecode.as_ref())
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
contracts.insert(name.clone(), (bytecode.clone(), deployed_bytecode.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,13 +198,7 @@ pub fn build_solidity_and_detect_missing_libraries(
|
||||
libraries.clone(),
|
||||
None,
|
||||
SolcStandardJsonInputSettingsSelection::new_required(pipeline),
|
||||
SolcStandardJsonInputSettingsOptimizer::new(
|
||||
true,
|
||||
None,
|
||||
&solc_version.default,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
SolcStandardJsonInputSettingsOptimizer::new(true, None, &solc_version.default, false),
|
||||
None,
|
||||
pipeline == SolcPipeline::Yul,
|
||||
None,
|
||||
@@ -194,11 +209,7 @@ pub fn build_solidity_and_detect_missing_libraries(
|
||||
let project = output.try_to_project(sources, libraries, pipeline, &solc_version, None)?;
|
||||
|
||||
let missing_libraries = project.get_missing_libraries();
|
||||
missing_libraries.write_to_standard_json(
|
||||
&mut output,
|
||||
&solc.version()?,
|
||||
&semver::Version::from_str(env!("CARGO_PKG_VERSION"))?,
|
||||
)?;
|
||||
missing_libraries.write_to_standard_json(&mut output, &solc.version()?)?;
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
@@ -211,12 +222,9 @@ pub fn build_yul(source_code: &str) -> anyhow::Result<()> {
|
||||
revive_llvm_context::initialize_target(revive_llvm_context::Target::PVM);
|
||||
let optimizer_settings = revive_llvm_context::OptimizerSettings::none();
|
||||
|
||||
let project = Project::try_from_yul_string::<SolcCompiler>(
|
||||
PathBuf::from("test.yul").as_path(),
|
||||
source_code,
|
||||
None,
|
||||
)?;
|
||||
let _build = project.compile(optimizer_settings, false, false, false, None)?;
|
||||
let project =
|
||||
Project::try_from_yul_string::<SolcCompiler>(PathBuf::from("test.yul").as_path(), source_code, None)?;
|
||||
let _build = project.compile(optimizer_settings, false, None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -227,14 +235,14 @@ pub fn check_solidity_warning(
|
||||
warning_substring: &str,
|
||||
libraries: BTreeMap<String, BTreeMap<String, String>>,
|
||||
pipeline: SolcPipeline,
|
||||
skip_for_zkvm_edition: bool,
|
||||
skip_for_revive_edition: bool,
|
||||
suppressed_warnings: Option<Vec<Warning>>,
|
||||
) -> anyhow::Result<bool> {
|
||||
check_dependencies();
|
||||
|
||||
let mut solc = SolcCompiler::new(SolcCompiler::DEFAULT_EXECUTABLE_NAME.to_owned())?;
|
||||
let solc_version = solc.version()?;
|
||||
if skip_for_zkvm_edition && solc_version.l2_revision.is_some() {
|
||||
if skip_for_revive_edition && solc_version.l2_revision.is_some() {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
@@ -246,13 +254,7 @@ pub fn check_solidity_warning(
|
||||
libraries,
|
||||
None,
|
||||
SolcStandardJsonInputSettingsSelection::new_required(pipeline),
|
||||
SolcStandardJsonInputSettingsOptimizer::new(
|
||||
true,
|
||||
None,
|
||||
&solc_version.default,
|
||||
false,
|
||||
false,
|
||||
),
|
||||
SolcStandardJsonInputSettingsOptimizer::new(true, None, &solc_version.default, false),
|
||||
None,
|
||||
pipeline == SolcPipeline::Yul,
|
||||
suppressed_warnings,
|
||||
@@ -267,3 +269,117 @@ pub fn check_solidity_warning(
|
||||
|
||||
Ok(contains_warning)
|
||||
}
|
||||
|
||||
/// Compile the blob of `contract_name` found in given `source_code`.
|
||||
/// The `solc` optimizer will be enabled
|
||||
pub fn compile_blob(contract_name: &str, source_code: &str) -> Vec<u8> {
|
||||
compile_blob_with_options(contract_name, source_code, true, SolcPipeline::Yul)
|
||||
}
|
||||
|
||||
/// Compile the EVM bin-runtime of `contract_name` found in given `source_code`.
|
||||
/// The `solc` optimizer will be enabled
|
||||
pub fn compile_evm_bin_runtime(contract_name: &str, source_code: &str) -> Vec<u8> {
|
||||
compile_evm(contract_name, source_code, true, true)
|
||||
}
|
||||
|
||||
/// Compile the EVM bin of `contract_name` found in given `source_code`.
|
||||
/// The `solc` optimizer will be enabled
|
||||
pub fn compile_evm_deploy_code(
|
||||
contract_name: &str,
|
||||
source_code: &str,
|
||||
solc_optimizer_enabled: bool,
|
||||
) -> Vec<u8> {
|
||||
compile_evm(contract_name, source_code, solc_optimizer_enabled, false)
|
||||
}
|
||||
|
||||
fn compile_evm(
|
||||
contract_name: &str,
|
||||
source_code: &str,
|
||||
solc_optimizer_enabled: bool,
|
||||
runtime: bool,
|
||||
) -> Vec<u8> {
|
||||
let pipeline = SolcPipeline::Yul;
|
||||
let id = CachedBlob {
|
||||
contract_name: contract_name.to_owned(),
|
||||
pipeline,
|
||||
solc_optimizer_enabled,
|
||||
};
|
||||
|
||||
let cache = if runtime {
|
||||
&EVM_RUNTIME_BLOB_CACHE
|
||||
} else {
|
||||
&EVM_BLOB_CACHE
|
||||
};
|
||||
if let Some(blob) = cache.lock().unwrap().get(&id) {
|
||||
return blob.clone();
|
||||
}
|
||||
|
||||
let file_name = "contract.sol";
|
||||
let contracts = build_solidity_with_options_evm(
|
||||
[(file_name.into(), source_code.into())].into(),
|
||||
Default::default(),
|
||||
None,
|
||||
pipeline,
|
||||
solc_optimizer_enabled,
|
||||
)
|
||||
.expect("source should compile");
|
||||
let object = &contracts
|
||||
.get(contract_name)
|
||||
.unwrap_or_else(|| panic!("contract '{}' didn't produce bin-runtime", contract_name));
|
||||
let code = if runtime {
|
||||
object.1.object.as_str()
|
||||
} else {
|
||||
object.0.object.as_str()
|
||||
};
|
||||
let blob = hex::decode(code).expect("code shold be hex encoded");
|
||||
|
||||
cache.lock().unwrap().insert(id, blob.clone());
|
||||
|
||||
blob
|
||||
}
|
||||
|
||||
/// Compile the blob of `contract_name` found in given `source_code`.
|
||||
pub fn compile_blob_with_options(
|
||||
contract_name: &str,
|
||||
source_code: &str,
|
||||
solc_optimizer_enabled: bool,
|
||||
pipeline: SolcPipeline,
|
||||
) -> Vec<u8> {
|
||||
let id = CachedBlob {
|
||||
contract_name: contract_name.to_owned(),
|
||||
solc_optimizer_enabled,
|
||||
pipeline,
|
||||
};
|
||||
|
||||
if let Some(blob) = PVM_BLOB_CACHE.lock().unwrap().get(&id) {
|
||||
return blob.clone();
|
||||
}
|
||||
|
||||
let file_name = "contract.sol";
|
||||
let contracts = build_solidity_with_options(
|
||||
[(file_name.into(), source_code.into())].into(),
|
||||
Default::default(),
|
||||
None,
|
||||
pipeline,
|
||||
revive_llvm_context::OptimizerSettings::cycles(),
|
||||
solc_optimizer_enabled,
|
||||
)
|
||||
.expect("source should compile")
|
||||
.contracts
|
||||
.expect("source should contain at least one contract");
|
||||
|
||||
let bytecode = contracts[file_name][contract_name]
|
||||
.evm
|
||||
.as_ref()
|
||||
.expect("source should produce EVM output")
|
||||
.bytecode
|
||||
.as_ref()
|
||||
.expect("source should produce assembly text")
|
||||
.object
|
||||
.as_str();
|
||||
let blob = hex::decode(bytecode).expect("hex encoding should always be valid");
|
||||
|
||||
PVM_BLOB_CACHE.lock().unwrap().insert(id, blob.clone());
|
||||
|
||||
blob
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "1.0.0",
|
||||
"title": "resolc CLI Tests",
|
||||
"description": "Auto tests for verifying resolc CLI",
|
||||
"repository": "https://github.com/xermicus/revive",
|
||||
"repository": "https://github.com/paritytech/revive",
|
||||
"main": "index.js",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
//! The resolc compiler version.
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
/// The resolc compiler version.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Version {
|
||||
/// The long version string.
|
||||
pub long: String,
|
||||
/// The short `semver`.
|
||||
pub default: semver::Version,
|
||||
/// The LLVM version string.
|
||||
pub llvm: semver::Version,
|
||||
}
|
||||
|
||||
impl Default for Version {
|
||||
fn default() -> Self {
|
||||
let default = semver::Version::parse(env!("CARGO_PKG_VERSION")).expect("Always valid");
|
||||
let commit = env!("GIT_COMMIT_HASH");
|
||||
let (llvm_major, llvm_minor, llvm_patch) = inkwell::support::get_llvm_version();
|
||||
let llvm = semver::Version::new(llvm_major as u64, llvm_minor as u64, llvm_patch as u64);
|
||||
|
||||
Self {
|
||||
long: format!("{default}+commit.{commit}.llvm-{llvm}"),
|
||||
default,
|
||||
llvm,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,13 +125,6 @@ impl FunctionCall {
|
||||
let location = self.location;
|
||||
|
||||
match self.name {
|
||||
Name::UserDefined(name)
|
||||
if name.starts_with(
|
||||
revive_llvm_context::PolkaVMFunction::ZKSYNC_NEAR_CALL_ABI_PREFIX,
|
||||
) && context.is_system_mode() =>
|
||||
{
|
||||
unimplemented!();
|
||||
}
|
||||
Name::UserDefined(name) => {
|
||||
let mut values = Vec::with_capacity(self.arguments.len());
|
||||
for argument in self.arguments.into_iter().rev() {
|
||||
@@ -501,25 +494,30 @@ impl FunctionCall {
|
||||
)
|
||||
.map(|_| None)
|
||||
}
|
||||
Name::LoadImmutable => todo!(),
|
||||
Name::LoadImmutable => {
|
||||
let mut arguments = self.pop_arguments::<D, 1>(context)?;
|
||||
let key = arguments[0].original.take().ok_or_else(|| {
|
||||
anyhow::anyhow!("{} `load_immutable` literal is missing", location)
|
||||
})?;
|
||||
let offset = context
|
||||
.solidity_mut()
|
||||
.get_or_allocate_immutable(key.as_str())
|
||||
/ revive_common::BYTE_LENGTH_WORD;
|
||||
let index = context.xlen_type().const_int(offset as u64, false);
|
||||
revive_llvm_context::polkavm_evm_immutable::load(context, index).map(Some)
|
||||
}
|
||||
Name::SetImmutable => {
|
||||
let mut arguments = self.pop_arguments::<D, 3>(context)?;
|
||||
let key = arguments[1].original.take().ok_or_else(|| {
|
||||
anyhow::anyhow!("{} `load_immutable` literal is missing", location)
|
||||
})?;
|
||||
|
||||
if key.as_str() == "library_deploy_address" {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let offset = context.solidity_mut().allocate_immutable(key.as_str());
|
||||
|
||||
let index = context.word_const(offset as u64);
|
||||
let offset = context.solidity_mut().allocate_immutable(key.as_str())
|
||||
/ revive_common::BYTE_LENGTH_WORD;
|
||||
let index = context.xlen_type().const_int(offset as u64, false);
|
||||
let value = arguments[2].value.into_int_value();
|
||||
revive_llvm_context::polkavm_evm_immutable::store(context, index, value)
|
||||
.map(|_| None)
|
||||
}
|
||||
|
||||
Name::CallDataLoad => {
|
||||
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
|
||||
|
||||
@@ -831,6 +829,7 @@ impl FunctionCall {
|
||||
value,
|
||||
input_offset,
|
||||
input_length,
|
||||
None,
|
||||
)
|
||||
.map(Some)
|
||||
}
|
||||
@@ -842,7 +841,7 @@ impl FunctionCall {
|
||||
let input_length = arguments[2].into_int_value();
|
||||
let salt = arguments[3].into_int_value();
|
||||
|
||||
revive_llvm_context::polkavm_evm_create::create2(
|
||||
revive_llvm_context::polkavm_evm_create::create(
|
||||
context,
|
||||
value,
|
||||
input_offset,
|
||||
@@ -912,7 +911,9 @@ impl FunctionCall {
|
||||
let address = arguments[0].into_int_value();
|
||||
revive_llvm_context::polkavm_evm_ether_gas::balance(context, address).map(Some)
|
||||
}
|
||||
Name::SelfBalance => todo!(),
|
||||
Name::SelfBalance => {
|
||||
revive_llvm_context::polkavm_evm_ether_gas::self_balance(context).map(Some)
|
||||
}
|
||||
|
||||
Name::GasLimit => {
|
||||
revive_llvm_context::polkavm_evm_contract_context::gas_limit(context).map(Some)
|
||||
@@ -962,9 +963,7 @@ impl FunctionCall {
|
||||
location
|
||||
);
|
||||
}
|
||||
Name::MSize => {
|
||||
revive_llvm_context::polkavm_evm_contract_context::msize(context).map(Some)
|
||||
}
|
||||
Name::MSize => revive_llvm_context::polkavm_evm_memory::msize(context).map(Some),
|
||||
|
||||
Name::Verbatim {
|
||||
input_size,
|
||||
|
||||
@@ -92,37 +92,7 @@ impl FunctionDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
let (mut arguments, next) = Identifier::parse_typed_list(lexer, None)?;
|
||||
if identifier
|
||||
.inner
|
||||
.contains(revive_llvm_context::PolkaVMFunction::ZKSYNC_NEAR_CALL_ABI_PREFIX)
|
||||
{
|
||||
if arguments.is_empty() {
|
||||
return Err(ParserError::InvalidNumberOfArguments {
|
||||
location,
|
||||
identifier: identifier.inner,
|
||||
expected: 1,
|
||||
found: arguments.len(),
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
arguments.remove(0);
|
||||
}
|
||||
if identifier
|
||||
.inner
|
||||
.contains(revive_llvm_context::PolkaVMFunction::ZKSYNC_NEAR_CALL_ABI_EXCEPTION_HANDLER)
|
||||
&& !arguments.is_empty()
|
||||
{
|
||||
return Err(ParserError::InvalidNumberOfArguments {
|
||||
location,
|
||||
identifier: identifier.inner,
|
||||
expected: 0,
|
||||
found: arguments.len(),
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
let (arguments, next) = Identifier::parse_typed_list(lexer, None)?;
|
||||
match crate::yul::parser::take_or_next(next, lexer)? {
|
||||
Token {
|
||||
lexeme: Lexeme::Symbol(Symbol::ParenthesisRight),
|
||||
@@ -234,12 +204,7 @@ where
|
||||
})
|
||||
.collect();
|
||||
|
||||
let function_type = context.function_type(
|
||||
argument_types,
|
||||
self.result.len(),
|
||||
self.identifier
|
||||
.starts_with(revive_llvm_context::PolkaVMFunction::ZKSYNC_NEAR_CALL_ABI_PREFIX),
|
||||
);
|
||||
let function_type = context.function_type(argument_types, self.result.len());
|
||||
|
||||
let function = context.add_function(
|
||||
self.identifier.as_str(),
|
||||
@@ -310,23 +275,12 @@ where
|
||||
yul_type.into_llvm(context)
|
||||
})
|
||||
.collect();
|
||||
for (mut index, argument) in self.arguments.iter().enumerate() {
|
||||
for (index, argument) in self.arguments.iter().enumerate() {
|
||||
let pointer = context.build_alloca(argument_types[index], argument.inner.as_str());
|
||||
context
|
||||
.current_function()
|
||||
.borrow_mut()
|
||||
.insert_stack_pointer(argument.inner.clone(), pointer);
|
||||
if self
|
||||
.identifier
|
||||
.starts_with(revive_llvm_context::PolkaVMFunction::ZKSYNC_NEAR_CALL_ABI_PREFIX)
|
||||
&& matches!(
|
||||
context.current_function().borrow().r#return(),
|
||||
revive_llvm_context::PolkaVMFunctionReturn::Compound { .. }
|
||||
)
|
||||
&& context.is_system_mode()
|
||||
{
|
||||
index += 1;
|
||||
}
|
||||
context.build_store(
|
||||
pointer,
|
||||
context.current_function().borrow().get_nth_param(index),
|
||||
@@ -354,13 +308,6 @@ where
|
||||
let return_value = context.build_load(pointer, "return_value")?;
|
||||
context.build_return(Some(&return_value));
|
||||
}
|
||||
revive_llvm_context::PolkaVMFunctionReturn::Compound { pointer, .. }
|
||||
if context.current_function().borrow().name().starts_with(
|
||||
revive_llvm_context::PolkaVMFunction::ZKSYNC_NEAR_CALL_ABI_PREFIX,
|
||||
) =>
|
||||
{
|
||||
context.build_return(Some(&pointer.value));
|
||||
}
|
||||
revive_llvm_context::PolkaVMFunctionReturn::Compound { pointer, .. } => {
|
||||
let return_value = context.build_load(pointer, "return_value")?;
|
||||
context.build_return(Some(&return_value));
|
||||
@@ -524,80 +471,6 @@ object "Test" {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error_invalid_number_of_arguments_near_call_abi() {
|
||||
let input = r#"
|
||||
object "Test" {
|
||||
code {
|
||||
{
|
||||
return(0, 0)
|
||||
}
|
||||
}
|
||||
object "Test_deployed" {
|
||||
code {
|
||||
{
|
||||
return(0, 0)
|
||||
}
|
||||
|
||||
function ZKSYNC_NEAR_CALL_test() -> result {
|
||||
result := 42
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
let mut lexer = Lexer::new(input.to_owned());
|
||||
let result = Object::parse(&mut lexer, None);
|
||||
assert_eq!(
|
||||
result,
|
||||
Err(Error::InvalidNumberOfArguments {
|
||||
location: Location::new(14, 22),
|
||||
identifier: "ZKSYNC_NEAR_CALL_test".to_owned(),
|
||||
expected: 1,
|
||||
found: 0,
|
||||
}
|
||||
.into())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error_invalid_number_of_arguments_near_call_abi_catch() {
|
||||
let input = r#"
|
||||
object "Test" {
|
||||
code {
|
||||
{
|
||||
return(0, 0)
|
||||
}
|
||||
}
|
||||
object "Test_deployed" {
|
||||
code {
|
||||
{
|
||||
return(0, 0)
|
||||
}
|
||||
|
||||
function ZKSYNC_CATCH_NEAR_CALL(length) {
|
||||
revert(0, length)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
let mut lexer = Lexer::new(input.to_owned());
|
||||
let result = Object::parse(&mut lexer, None);
|
||||
assert_eq!(
|
||||
result,
|
||||
Err(Error::InvalidNumberOfArguments {
|
||||
location: Location::new(14, 22),
|
||||
identifier: "ZKSYNC_CATCH_NEAR_CALL".to_owned(),
|
||||
expected: 0,
|
||||
found: 1,
|
||||
}
|
||||
.into())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error_reserved_identifier() {
|
||||
let input = r#"
|
||||
|
||||
@@ -183,6 +183,7 @@ where
|
||||
&mut self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
revive_llvm_context::PolkaVMImmutableDataLoadFunction.declare(context)?;
|
||||
let mut entry = revive_llvm_context::PolkaVMEntryFunction::default();
|
||||
entry.declare(context)?;
|
||||
|
||||
@@ -199,6 +200,7 @@ where
|
||||
revive_llvm_context::PolkaVMFunctionDeployCode,
|
||||
revive_llvm_context::PolkaVMFunctionRuntimeCode,
|
||||
revive_llvm_context::PolkaVMFunctionEntry,
|
||||
revive_llvm_context::PolkaVMFunctionImmutableDataLoad,
|
||||
]
|
||||
.into_iter()
|
||||
{
|
||||
@@ -216,6 +218,7 @@ where
|
||||
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
if self.identifier.ends_with("_deployed") {
|
||||
revive_llvm_context::PolkaVMImmutableDataLoadFunction.into_llvm(context)?;
|
||||
revive_llvm_context::PolkaVMRuntimeCodeFunction::new(self.code).into_llvm(context)?;
|
||||
} else {
|
||||
revive_llvm_context::PolkaVMDeployCodeFunction::new(self.code).into_llvm(context)?;
|
||||
|
||||
Reference in New Issue
Block a user