mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-04-22 07:57:57 +00:00
feat: use PolkaVM disassembler (#6)
Integrate the PolkaVM disassembler to fix `--asm` output Co-authored-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
Generated
+116
-5
@@ -91,12 +91,55 @@ version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.82"
|
||||
@@ -406,6 +449,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -414,8 +458,22 @@ version = "4.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -424,6 +482,12 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.1.0"
|
||||
@@ -863,6 +927,12 @@ version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
@@ -899,6 +969,15 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iced-x86"
|
||||
version = "1.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c447cff8c7f384a7d4f741cfcff32f75f3ad02b406432e8d6c878d56b1edf6b"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "impl-codec"
|
||||
version = "0.6.0"
|
||||
@@ -982,6 +1061,12 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
@@ -1325,7 +1410,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "polkavm"
|
||||
version = "0.10.0"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=e2801d9#e2801d9f34211fb5e16aee36a81700ad450c50e5"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=266658b#266658b328975ec07ec389f8d966a894f37a8916"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
@@ -1337,7 +1422,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "polkavm-assembler"
|
||||
version = "0.10.0"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=e2801d9#e2801d9f34211fb5e16aee36a81700ad450c50e5"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=266658b#266658b328975ec07ec389f8d966a894f37a8916"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
@@ -1345,15 +1430,27 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "polkavm-common"
|
||||
version = "0.10.0"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=e2801d9#e2801d9f34211fb5e16aee36a81700ad450c50e5"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=266658b#266658b328975ec07ec389f8d966a894f37a8916"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polkavm-disassembler"
|
||||
version = "0.10.0"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=266658b#266658b328975ec07ec389f8d966a894f37a8916"
|
||||
dependencies = [
|
||||
"clap 4.5.4",
|
||||
"iced-x86",
|
||||
"polkavm",
|
||||
"polkavm-common",
|
||||
"polkavm-linker",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polkavm-linker"
|
||||
version = "0.10.0"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=e2801d9#e2801d9f34211fb5e16aee36a81700ad450c50e5"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=266658b#266658b328975ec07ec389f8d966a894f37a8916"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
"hashbrown 0.14.5",
|
||||
@@ -1367,7 +1464,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "polkavm-linux-raw"
|
||||
version = "0.10.0"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=e2801d9#e2801d9f34211fb5e16aee36a81700ad450c50e5"
|
||||
source = "git+https://github.com/koute/polkavm.git?rev=266658b#266658b328975ec07ec389f8d966a894f37a8916"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
@@ -1707,6 +1804,8 @@ dependencies = [
|
||||
"num",
|
||||
"once_cell",
|
||||
"path-slash",
|
||||
"polkavm-common",
|
||||
"polkavm-disassembler",
|
||||
"rand",
|
||||
"rayon",
|
||||
"regex",
|
||||
@@ -2060,6 +2159,12 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.26"
|
||||
@@ -2266,6 +2371,12 @@ version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
|
||||
+4
-3
@@ -27,9 +27,10 @@ path-slash = "0.2"
|
||||
rayon = "1.8"
|
||||
structopt = { version = "0.3", default-features = false }
|
||||
rand = "0.8"
|
||||
polkavm-common = { git = "https://github.com/koute/polkavm.git", rev = "e2801d9" }
|
||||
polkavm-linker = { git = "https://github.com/koute/polkavm.git", rev = "e2801d9" }
|
||||
polkavm = { git = "https://github.com/koute/polkavm.git", rev = "e2801d9" }
|
||||
polkavm-common = { git = "https://github.com/koute/polkavm.git", rev = "266658b" }
|
||||
polkavm-linker = { git = "https://github.com/koute/polkavm.git", rev = "266658b" }
|
||||
polkavm-disassembler = { git = "https://github.com/koute/polkavm.git", rev = "266658b" }
|
||||
polkavm = { git = "https://github.com/koute/polkavm.git", rev = "266658b" }
|
||||
alloy-primitives = "0.6"
|
||||
alloy-sol-types = "0.6"
|
||||
env_logger = { version = "0.10.0", default-features = false }
|
||||
|
||||
@@ -72,7 +72,7 @@ where
|
||||
group
|
||||
.sample_size(10)
|
||||
.measurement_time(Duration::from_secs(60));
|
||||
return group;
|
||||
group
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "bench-extensive"))]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"Fibonacci": 5971,
|
||||
"Computation": 7380,
|
||||
"ERC20": 51241,
|
||||
"Baseline": 3912,
|
||||
"ERC20": 53186,
|
||||
"Flipper": 4354,
|
||||
"Computation": 7380
|
||||
"Fibonacci": 5971,
|
||||
"Flipper": 4354
|
||||
}
|
||||
@@ -36,6 +36,8 @@ num = { workspace = true }
|
||||
sha3 = { workspace = true }
|
||||
md5 = { workspace = true }
|
||||
inkwell = { workspace = true }
|
||||
polkavm-disassembler = { workspace = true }
|
||||
polkavm-common = { workspace = true }
|
||||
|
||||
revive-common = { path = "../common" }
|
||||
revive-llvm-context = { path = "../llvm-context" }
|
||||
|
||||
@@ -8,6 +8,9 @@ use std::path::Path;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
use polkavm_common::program::ProgramBlob;
|
||||
use polkavm_disassembler::{Disassembler, DisassemblyFormat};
|
||||
|
||||
use crate::solc::combined_json::contract::Contract as CombinedJsonContract;
|
||||
use crate::solc::standard_json::output::contract::Contract as StandardJsonOutputContract;
|
||||
|
||||
@@ -53,9 +56,14 @@ impl Contract {
|
||||
overwrite: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
let file_name = Self::short_path(self.path.as_str());
|
||||
let bytescode = self.build.bytecode;
|
||||
|
||||
if output_assembly {
|
||||
let file_name = format!("{}.{}", file_name, revive_common::EXTENSION_POLKAVM_ASSEMBLY);
|
||||
let file_name = format!(
|
||||
"{}.{}",
|
||||
file_name,
|
||||
revive_common::EXTENSION_POLKAVM_ASSEMBLY
|
||||
);
|
||||
let mut file_path = path.to_owned();
|
||||
file_path.push(file_name);
|
||||
|
||||
@@ -64,11 +72,39 @@ impl Contract {
|
||||
"Refusing to overwrite an existing file {file_path:?} (use --overwrite to force)."
|
||||
);
|
||||
} else {
|
||||
let program_blob = ProgramBlob::parse(bytescode.as_slice()).map_err(|error| {
|
||||
anyhow::anyhow!(format!("Failed to parse program blob: {}", error))
|
||||
})?;
|
||||
|
||||
let mut disassembler = Disassembler::new(&program_blob, DisassemblyFormat::Guest)
|
||||
.map_err(|error| {
|
||||
anyhow::anyhow!(format!(
|
||||
"Failed to create disassembler for contract '{:?}'\n\nDue to:\n{}",
|
||||
&file_path, error
|
||||
))
|
||||
})?;
|
||||
|
||||
let mut disassembled_code = Vec::new();
|
||||
disassembler
|
||||
.disassemble_into(&mut disassembled_code)
|
||||
.map_err(|error| {
|
||||
anyhow::anyhow!(format!(
|
||||
"Failed to disassemble contract '{:?}'\n\nDue to:\n{}\n\nGas details:{:?}\n",
|
||||
&file_path, error, disassembler.display_gas()
|
||||
))
|
||||
})?;
|
||||
|
||||
let assembly_text = String::from_utf8(disassembled_code)
|
||||
.map_err(|error| anyhow::anyhow!(format!(
|
||||
"Failed to convert disassembled code to string for contract '{:?}'\n\nDue to:\n{}",
|
||||
&file_path, error
|
||||
)))?;
|
||||
|
||||
File::create(&file_path)
|
||||
.map_err(|error| {
|
||||
anyhow::anyhow!("File {:?} creating error: {}", file_path, error)
|
||||
})?
|
||||
.write_all(self.build.assembly_text.as_bytes())
|
||||
.write_all(assembly_text.as_bytes())
|
||||
.map_err(|error| {
|
||||
anyhow::anyhow!("File {:?} writing error: {}", file_path, error)
|
||||
})?;
|
||||
@@ -89,7 +125,7 @@ impl Contract {
|
||||
.map_err(|error| {
|
||||
anyhow::anyhow!("File {:?} creating error: {}", file_path, error)
|
||||
})?
|
||||
.write_all(self.build.bytecode.as_slice())
|
||||
.write_all(bytescode.as_slice())
|
||||
.map_err(|error| {
|
||||
anyhow::anyhow!("File {:?} writing error: {}", file_path, error)
|
||||
})?;
|
||||
|
||||
@@ -23,10 +23,7 @@ impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for EntryLink
|
||||
where
|
||||
D: revive_llvm_context::PolkaVMDependency + Clone,
|
||||
{
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
let target = context
|
||||
.get_function(EtherealIR::DEFAULT_ENTRY_FUNCTION_NAME)
|
||||
.expect("Always exists")
|
||||
|
||||
@@ -1168,8 +1168,7 @@ where
|
||||
.map(Some)
|
||||
}
|
||||
InstructionName::NUMBER => {
|
||||
revive_llvm_context::polkavm_evm_contract_context::block_number(context)
|
||||
.map(Some)
|
||||
revive_llvm_context::polkavm_evm_contract_context::block_number(context).map(Some)
|
||||
}
|
||||
InstructionName::BLOCKHASH => {
|
||||
let arguments = self.pop_arguments_llvm(context);
|
||||
@@ -1244,9 +1243,7 @@ where
|
||||
.to_llvm()
|
||||
.into_pointer_value();
|
||||
context.build_store(
|
||||
revive_llvm_context::PolkaVMPointer::new_stack_field(
|
||||
context, pointer,
|
||||
),
|
||||
revive_llvm_context::PolkaVMPointer::new_stack_field(context, pointer),
|
||||
value,
|
||||
)?;
|
||||
}
|
||||
@@ -1297,9 +1294,7 @@ where
|
||||
assert_eq!(arguments.len(), 1);
|
||||
context.build_store(pointer, arguments.remove(0))?;
|
||||
}
|
||||
revive_llvm_context::PolkaVMFunctionReturn::Compound {
|
||||
pointer, ..
|
||||
} => {
|
||||
revive_llvm_context::PolkaVMFunctionReturn::Compound { pointer, .. } => {
|
||||
for (index, argument) in arguments.into_iter().enumerate() {
|
||||
let element_pointer = context.build_gep(
|
||||
pointer,
|
||||
|
||||
@@ -117,10 +117,7 @@ impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for Block
|
||||
where
|
||||
D: revive_llvm_context::PolkaVMDependency + Clone,
|
||||
{
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
context.set_code_type(self.key.code_type);
|
||||
|
||||
for element in self.elements.into_iter() {
|
||||
|
||||
@@ -252,12 +252,10 @@ impl Function {
|
||||
destination.to_owned() - num::BigUint::from(1u64 << 32),
|
||||
)
|
||||
}
|
||||
Element::Tag(destination) => {
|
||||
revive_llvm_context::PolkaVMFunctionBlockKey::new(
|
||||
code_type,
|
||||
destination.to_owned(),
|
||||
)
|
||||
}
|
||||
Element::Tag(destination) => revive_llvm_context::PolkaVMFunctionBlockKey::new(
|
||||
code_type,
|
||||
destination.to_owned(),
|
||||
),
|
||||
Element::ReturnAddress(output_size) => {
|
||||
block_element.instruction =
|
||||
Instruction::recursive_return(1 + output_size, instruction);
|
||||
@@ -316,12 +314,10 @@ impl Function {
|
||||
destination.to_owned() - num::BigUint::from(1u64 << 32),
|
||||
)
|
||||
}
|
||||
Element::Tag(destination) => {
|
||||
revive_llvm_context::PolkaVMFunctionBlockKey::new(
|
||||
code_type,
|
||||
destination.to_owned(),
|
||||
)
|
||||
}
|
||||
Element::Tag(destination) => revive_llvm_context::PolkaVMFunctionBlockKey::new(
|
||||
code_type,
|
||||
destination.to_owned(),
|
||||
),
|
||||
element => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"The {} instruction expected a tag or return address, found {}",
|
||||
@@ -346,8 +342,7 @@ impl Function {
|
||||
..
|
||||
} => {
|
||||
let tag: num::BigUint = tag.parse().expect("Always valid");
|
||||
let block_key =
|
||||
revive_llvm_context::PolkaVMFunctionBlockKey::new(code_type, tag);
|
||||
let block_key = revive_llvm_context::PolkaVMFunctionBlockKey::new(code_type, tag);
|
||||
|
||||
queue_element.predecessor = Some((queue_element.block_key.clone(), instance));
|
||||
queue_element.block_key = block_key.clone();
|
||||
@@ -1014,21 +1009,16 @@ impl Function {
|
||||
block_stack: &mut Stack,
|
||||
block_element: &mut BlockElement,
|
||||
version: &semver::Version,
|
||||
) -> anyhow::Result<(
|
||||
revive_llvm_context::PolkaVMFunctionBlockKey,
|
||||
Vec<Element>,
|
||||
)> {
|
||||
) -> anyhow::Result<(revive_llvm_context::PolkaVMFunctionBlockKey, Vec<Element>)> {
|
||||
let return_address_offset = block_stack.elements.len() - 2 - recursive_function.input_size;
|
||||
let input_arguments_offset = return_address_offset + 1;
|
||||
let callee_tag_offset = input_arguments_offset + recursive_function.input_size;
|
||||
|
||||
let return_address = match block_stack.elements[return_address_offset] {
|
||||
Element::Tag(ref return_address) => {
|
||||
revive_llvm_context::PolkaVMFunctionBlockKey::new(
|
||||
block_key.code_type,
|
||||
return_address.to_owned(),
|
||||
)
|
||||
}
|
||||
Element::Tag(ref return_address) => revive_llvm_context::PolkaVMFunctionBlockKey::new(
|
||||
block_key.code_type,
|
||||
return_address.to_owned(),
|
||||
),
|
||||
ref element => anyhow::bail!("Expected the function return address, found {}", element),
|
||||
};
|
||||
let mut stack = Stack::with_capacity(1 + recursive_function.input_size);
|
||||
@@ -1177,17 +1167,16 @@ where
|
||||
output_size,
|
||||
Some(inkwell::module::Linkage::Private),
|
||||
)?;
|
||||
function.borrow_mut().set_evmla_data(
|
||||
revive_llvm_context::PolkaVMFunctionEVMLAData::new(self.stack_size),
|
||||
);
|
||||
function
|
||||
.borrow_mut()
|
||||
.set_evmla_data(revive_llvm_context::PolkaVMFunctionEVMLAData::new(
|
||||
self.stack_size,
|
||||
));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
context.set_current_function(self.name.as_str())?;
|
||||
|
||||
for (key, blocks) in self.blocks.iter() {
|
||||
|
||||
@@ -81,10 +81,7 @@ impl EtherealIR {
|
||||
&instructions[offset..],
|
||||
)?;
|
||||
blocks.insert(
|
||||
revive_llvm_context::PolkaVMFunctionBlockKey::new(
|
||||
code_type,
|
||||
block.key.tag.clone(),
|
||||
),
|
||||
revive_llvm_context::PolkaVMFunctionBlockKey::new(code_type, block.key.tag.clone()),
|
||||
block,
|
||||
);
|
||||
offset += size;
|
||||
@@ -111,10 +108,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
context.evmla_mut().stack = vec![];
|
||||
|
||||
self.entry_function.into_llvm(context)?;
|
||||
|
||||
@@ -41,10 +41,7 @@ where
|
||||
self.assembly.declare(context)
|
||||
}
|
||||
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
self.assembly.into_llvm(context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,10 +83,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
match self {
|
||||
Self::Yul(inner) => inner.into_llvm(context),
|
||||
Self::EVMLA(inner) => inner.into_llvm(context),
|
||||
|
||||
@@ -42,10 +42,7 @@ where
|
||||
self.object.declare(context)
|
||||
}
|
||||
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
self.object.into_llvm(context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,8 +148,7 @@ impl Contract {
|
||||
context.set_yul_data(yul_data);
|
||||
}
|
||||
IR::EVMLA(_) => {
|
||||
let evmla_data =
|
||||
revive_llvm_context::PolkaVMContextEVMLAData::new(version.default);
|
||||
let evmla_data = revive_llvm_context::PolkaVMContextEVMLAData::new(version.default);
|
||||
context.set_evmla_data(evmla_data);
|
||||
}
|
||||
IR::LLVMIR(_) => {}
|
||||
@@ -201,10 +200,7 @@ where
|
||||
self.ir.declare(context)
|
||||
}
|
||||
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
self.ir.into_llvm(context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,19 +14,23 @@ describe("Run with --asm by default", () => {
|
||||
});
|
||||
|
||||
it("--asm output is presented", () => {
|
||||
expect(result.output).toMatch(/(__entry:)/i);
|
||||
const expectedPatterns = [/(deploy)/i, /(call)/i, /(seal_return)/i];
|
||||
|
||||
for (const pattern of expectedPatterns) {
|
||||
expect(result.output).toMatch(pattern);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it("solc exit code == zksolc exit code", () => {
|
||||
const command = `solc ${paths.pathToBasicSolContract} --asm`;
|
||||
const solcResult = executeCommand(command);
|
||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||
const command = `solc ${paths.pathToBasicSolContract} --asm`;
|
||||
const solcResult = executeCommand(command);
|
||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||
});
|
||||
|
||||
it("run invalid: zksolc --asm", () => {
|
||||
expect(resultInvalid.output).toMatch(/(No input sources specified|Compilation aborted)/i);
|
||||
});
|
||||
|
||||
it("Invalid command exit code = 1", () => {
|
||||
expect(resultInvalid.exitCode).toBe(1);
|
||||
});
|
||||
@@ -36,4 +40,4 @@ describe("Run with --asm by default", () => {
|
||||
const solcResult = executeCommand(command);
|
||||
expect(solcResult.exitCode).toBe(resultInvalid.exitCode);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -3,6 +3,5 @@
|
||||
"target": "ES6",
|
||||
"module": "CommonJS",
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,10 +132,7 @@ impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for Block
|
||||
where
|
||||
D: revive_llvm_context::PolkaVMDependency + Clone,
|
||||
{
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
let current_function = context.current_function().borrow().name().to_owned();
|
||||
let current_block = context.basic_block();
|
||||
|
||||
|
||||
@@ -59,10 +59,7 @@ impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for Code
|
||||
where
|
||||
D: revive_llvm_context::PolkaVMDependency + Clone,
|
||||
{
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
self.block.into_llvm(context)?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -911,9 +911,7 @@ impl FunctionCall {
|
||||
Ok(Some(context.integer_const(256, 0).as_basic_value_enum()))
|
||||
}
|
||||
|
||||
Name::CallValue => {
|
||||
revive_llvm_context::polkavm_evm_ether_gas::value(context).map(Some)
|
||||
}
|
||||
Name::CallValue => revive_llvm_context::polkavm_evm_ether_gas::value(context).map(Some),
|
||||
Name::Gas => revive_llvm_context::polkavm_evm_ether_gas::gas(context).map(Some),
|
||||
Name::Balance => {
|
||||
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
|
||||
@@ -940,8 +938,7 @@ impl FunctionCall {
|
||||
.map(Some)
|
||||
}
|
||||
Name::Number => {
|
||||
revive_llvm_context::polkavm_evm_contract_context::block_number(context)
|
||||
.map(Some)
|
||||
revive_llvm_context::polkavm_evm_contract_context::block_number(context).map(Some)
|
||||
}
|
||||
Name::BlockHash => {
|
||||
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
|
||||
|
||||
@@ -137,9 +137,7 @@ impl Expression {
|
||||
|
||||
match constant {
|
||||
Some(constant) => Ok(Some(
|
||||
revive_llvm_context::PolkaVMArgument::new_with_constant(
|
||||
value, constant,
|
||||
),
|
||||
revive_llvm_context::PolkaVMArgument::new_with_constant(value, constant),
|
||||
)),
|
||||
None => Ok(Some(value.into())),
|
||||
}
|
||||
|
||||
@@ -64,10 +64,7 @@ impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for ForLoop
|
||||
where
|
||||
D: revive_llvm_context::PolkaVMDependency + Clone,
|
||||
{
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
self.initializer.into_llvm(context)?;
|
||||
|
||||
let condition_block = context.append_basic_block("for_condition");
|
||||
|
||||
@@ -109,9 +109,10 @@ impl FunctionDefinition {
|
||||
|
||||
arguments.remove(0);
|
||||
}
|
||||
if identifier.inner.contains(
|
||||
revive_llvm_context::PolkaVMFunction::ZKSYNC_NEAR_CALL_ABI_EXCEPTION_HANDLER,
|
||||
) && !arguments.is_empty()
|
||||
if identifier
|
||||
.inner
|
||||
.contains(revive_llvm_context::PolkaVMFunction::ZKSYNC_NEAR_CALL_ABI_EXCEPTION_HANDLER)
|
||||
&& !arguments.is_empty()
|
||||
{
|
||||
return Err(ParserError::InvalidNumberOfArguments {
|
||||
location,
|
||||
|
||||
@@ -52,10 +52,7 @@ impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for IfConditional
|
||||
where
|
||||
D: revive_llvm_context::PolkaVMDependency + Clone,
|
||||
{
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
let condition = self
|
||||
.condition
|
||||
.into_llvm(context)?
|
||||
|
||||
@@ -219,16 +219,11 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
if self.identifier.ends_with("_deployed") {
|
||||
revive_llvm_context::PolkaVMRuntimeCodeFunction::new(self.code)
|
||||
.into_llvm(context)?;
|
||||
revive_llvm_context::PolkaVMRuntimeCodeFunction::new(self.code).into_llvm(context)?;
|
||||
} else {
|
||||
revive_llvm_context::PolkaVMDeployCodeFunction::new(self.code)
|
||||
.into_llvm(context)?;
|
||||
revive_llvm_context::PolkaVMDeployCodeFunction::new(self.code).into_llvm(context)?;
|
||||
}
|
||||
|
||||
match self.inner_object {
|
||||
|
||||
@@ -122,10 +122,7 @@ impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for Switch
|
||||
where
|
||||
D: revive_llvm_context::PolkaVMDependency + Clone,
|
||||
{
|
||||
fn into_llvm(
|
||||
self,
|
||||
context: &mut revive_llvm_context::PolkaVMContext<D>,
|
||||
) -> anyhow::Result<()> {
|
||||
fn into_llvm(self, context: &mut revive_llvm_context::PolkaVMContext<D>) -> anyhow::Result<()> {
|
||||
let scrutinee = self.expression.into_llvm(context)?;
|
||||
|
||||
if self.cases.is_empty() {
|
||||
|
||||
@@ -212,7 +212,9 @@ impl Arguments {
|
||||
|
||||
if self.yul || self.llvm_ir || self.zkasm {
|
||||
if self.base_path.is_some() {
|
||||
anyhow::bail!("`base-path` is not used in Yul, LLVM IR and PolkaVM assembly modes.");
|
||||
anyhow::bail!(
|
||||
"`base-path` is not used in Yul, LLVM IR and PolkaVM assembly modes."
|
||||
);
|
||||
}
|
||||
if !self.include_paths.is_empty() {
|
||||
anyhow::bail!(
|
||||
|
||||
@@ -6,6 +6,9 @@ use std::str::FromStr;
|
||||
|
||||
use self::arguments::Arguments;
|
||||
|
||||
use polkavm_common::program::ProgramBlob;
|
||||
use polkavm_disassembler::{Disassembler, DisassemblyFormat};
|
||||
|
||||
/// The rayon worker stack size.
|
||||
const RAYON_WORKER_STACK_SIZE: usize = 16 * 1024 * 1024;
|
||||
|
||||
@@ -190,18 +193,41 @@ fn main_inner() -> anyhow::Result<()> {
|
||||
);
|
||||
} else if arguments.output_assembly || arguments.output_binary {
|
||||
for (path, contract) in build.contracts.into_iter() {
|
||||
let bytescode = contract.build.bytecode;
|
||||
|
||||
if arguments.output_assembly {
|
||||
println!(
|
||||
"Contract `{}` assembly:\n\n{}",
|
||||
path, contract.build.assembly_text
|
||||
);
|
||||
let program_blob = ProgramBlob::parse(bytescode.as_slice()).map_err(|error| {
|
||||
anyhow::anyhow!(format!("Failed to parse program blob: {}", error))
|
||||
})?;
|
||||
|
||||
let mut disassembler = Disassembler::new(&program_blob, DisassemblyFormat::Guest)
|
||||
.map_err(|error| {
|
||||
anyhow::anyhow!(format!(
|
||||
"Failed to create disassembler for contract '{}'\n\nDue to:\n{}",
|
||||
path, error
|
||||
))
|
||||
})?;
|
||||
|
||||
let mut disassembled_code = Vec::new();
|
||||
disassembler
|
||||
.disassemble_into(&mut disassembled_code)
|
||||
.map_err(|error| {
|
||||
anyhow::anyhow!(format!(
|
||||
"Failed to disassemble contract '{}'\n\nDue to:\n{}\n\nGas details:{:?}\n",
|
||||
path, error, disassembler.display_gas()
|
||||
))
|
||||
})?;
|
||||
|
||||
let assembly_text = String::from_utf8(disassembled_code)
|
||||
.map_err(|error| anyhow::anyhow!(format!(
|
||||
"Failed to convert disassembled code to string for contract '{}'\n\nDue to:\n{}",
|
||||
path, error
|
||||
)))?;
|
||||
|
||||
println!("Contract `{}` assembly:\n\n{}", path, assembly_text);
|
||||
}
|
||||
if arguments.output_binary {
|
||||
println!(
|
||||
"Contract `{}` bytecode: 0x{}",
|
||||
path,
|
||||
hex::encode(contract.build.bytecode)
|
||||
);
|
||||
println!("Contract `{}` bytecode: 0x{}", path, hex::encode(bytescode));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user