Skip to content

Commit c3041ce

Browse files
authored
feat: syncs EVM functionality with solx (#305)
1 parent 0150aef commit c3041ce

15 files changed

Lines changed: 182 additions & 152 deletions

File tree

Cargo.lock

Lines changed: 19 additions & 38 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ authors = [
1313
]
1414
license = "MIT OR Apache-2.0"
1515
edition = "2021"
16-
version = "1.5.13"
16+
version = "1.5.14"

era-compiler-solidity/src/build_evm/contract/mod.rs

Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
55
pub mod object;
66

7-
use std::collections::BTreeSet;
87
use std::io::Write;
98
use std::path::Path;
109
use std::path::PathBuf;
@@ -26,10 +25,6 @@ pub struct Contract {
2625
pub metadata_hash: Option<era_compiler_common::Hash>,
2726
/// The metadata JSON.
2827
pub metadata_json: serde_json::Value,
29-
/// The unlinked missing libraries.
30-
pub missing_libraries: BTreeSet<String>,
31-
/// The binary object format.
32-
pub object_format: era_compiler_common::ObjectFormat,
3328
}
3429

3530
impl Contract {
@@ -42,17 +37,13 @@ impl Contract {
4237
runtime_object: Object,
4338
metadata_hash: Option<era_compiler_common::Hash>,
4439
metadata_json: serde_json::Value,
45-
missing_libraries: BTreeSet<String>,
46-
object_format: era_compiler_common::ObjectFormat,
4740
) -> Self {
4841
Self {
4942
name,
5043
deploy_object,
5144
runtime_object,
5245
metadata_hash,
5346
metadata_json,
54-
missing_libraries,
55-
object_format,
5647
}
5748
}
5849

@@ -63,13 +54,9 @@ impl Contract {
6354
self,
6455
path: String,
6556
output_metadata: bool,
66-
output_assembly: bool,
6757
output_binary: bool,
6858
) -> anyhow::Result<()> {
6959
writeln!(std::io::stdout(), "\n======= {path} =======")?;
70-
if output_assembly {
71-
writeln!(std::io::stdout(), "Assembly:\nComing soon")?;
72-
}
7360
if output_metadata {
7461
writeln!(std::io::stdout(), "Metadata:\n{}", self.metadata_json)?;
7562
}
@@ -92,7 +79,6 @@ impl Contract {
9279
self,
9380
output_path: &Path,
9481
output_metadata: bool,
95-
output_assembly: bool,
9682
output_binary: bool,
9783
overwrite: bool,
9884
) -> anyhow::Result<()> {
@@ -129,25 +115,6 @@ impl Contract {
129115
}
130116
}
131117

132-
if output_assembly {
133-
let output_name = format!(
134-
"{}.{}",
135-
self.name.name.as_deref().unwrap_or(file_name),
136-
"asm"
137-
);
138-
let mut output_path = output_path.clone();
139-
output_path.push(output_name.as_str());
140-
141-
if output_path.exists() && !overwrite {
142-
anyhow::bail!(
143-
"Refusing to overwrite an existing file {output_path:?} (use --overwrite to force)."
144-
);
145-
} else {
146-
std::fs::write(output_path.as_path(), "Coming soon".as_bytes())
147-
.map_err(|error| anyhow::anyhow!("File {output_path:?} writing: {error}"))?;
148-
}
149-
}
150-
151118
if output_binary {
152119
let output_name = format!(
153120
"{}.{}",
@@ -186,8 +153,11 @@ impl Contract {
186153
.modify_evm(hex::encode(self.deploy_object.bytecode));
187154
standard_json_contract
188155
.missing_libraries
189-
.extend(self.missing_libraries);
190-
standard_json_contract.object_format = Some(self.object_format);
156+
.extend(self.deploy_object.unlinked_libraries);
157+
standard_json_contract
158+
.missing_libraries
159+
.extend(self.runtime_object.unlinked_libraries);
160+
standard_json_contract.object_format = Some(self.deploy_object.format);
191161

192162
Ok(())
193163
}
@@ -208,8 +178,11 @@ impl Contract {
208178

209179
combined_json_contract
210180
.missing_libraries
211-
.extend(self.missing_libraries);
212-
combined_json_contract.object_format = Some(self.object_format);
181+
.extend(self.deploy_object.unlinked_libraries);
182+
combined_json_contract
183+
.missing_libraries
184+
.extend(self.runtime_object.unlinked_libraries);
185+
combined_json_contract.object_format = Some(self.deploy_object.format);
213186

214187
Ok(())
215188
}

era-compiler-solidity/src/build_evm/contract/object.rs

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
//! Bytecode object.
33
//!
44
5+
use std::collections::BTreeMap;
6+
use std::collections::BTreeSet;
7+
58
///
69
/// Bytecode object.
710
///
@@ -21,11 +24,13 @@ pub struct Object {
2124
pub code_segment: era_compiler_common::CodeSegment,
2225
/// Dependencies.
2326
pub dependencies: era_yul::Dependencies,
27+
/// The unlinked unlinked libraries.
28+
pub unlinked_libraries: BTreeSet<String>,
2429
/// Whether the object is already assembled.
2530
pub is_assembled: bool,
26-
/// The binary object format.
27-
pub object_format: era_compiler_common::ObjectFormat,
28-
/// Warnings produced during compilation.
31+
/// Binary object format.
32+
pub format: era_compiler_common::ObjectFormat,
33+
/// Compilation warnings.
2934
pub warnings: Vec<era_compiler_llvm_context::EVMWarning>,
3035
}
3136

@@ -40,6 +45,8 @@ impl Object {
4045
codegen: Option<era_solc::StandardJsonInputCodegen>,
4146
code_segment: era_compiler_common::CodeSegment,
4247
dependencies: era_yul::Dependencies,
48+
unlinked_libraries: BTreeSet<String>,
49+
format: era_compiler_common::ObjectFormat,
4350
warnings: Vec<era_compiler_llvm_context::EVMWarning>,
4451
) -> Self {
4552
Self {
@@ -49,33 +56,63 @@ impl Object {
4956
codegen,
5057
code_segment,
5158
dependencies,
59+
unlinked_libraries,
5260
is_assembled: false,
53-
object_format: era_compiler_common::ObjectFormat::ELF,
61+
format,
5462
warnings,
5563
}
5664
}
5765

5866
///
59-
/// Whether the object requires assebmling with its dependencies.
67+
/// Links the object with its linker symbols.
6068
///
61-
pub fn requires_assembling(&self) -> bool {
62-
!self.is_assembled && !self.dependencies.inner.is_empty()
69+
pub fn link(
70+
&mut self,
71+
linker_symbols: &BTreeMap<String, [u8; era_compiler_common::BYTE_LENGTH_ETH_ADDRESS]>,
72+
) -> anyhow::Result<()> {
73+
let memory_buffer = inkwell::memory_buffer::MemoryBuffer::create_from_memory_range(
74+
self.bytecode.as_slice(),
75+
self.identifier.as_str(),
76+
false,
77+
);
78+
79+
let (linked_object, object_format) =
80+
era_compiler_llvm_context::evm_link(memory_buffer, linker_symbols)?;
81+
self.format = object_format;
82+
83+
self.bytecode = linked_object.as_slice().to_owned();
84+
// if let era_compiler_common::CodeSegment::Deploy = self.code_segment {
85+
// let metadata = match contract.metadata_hash {
86+
// Some(era_compiler_common::Hash::IPFS(ref hash)) => {
87+
// let cbor = era_compiler_common::CBOR::new(
88+
// Some((
89+
// era_compiler_common::EVMMetadataHashType::IPFS,
90+
// hash.as_bytes(),
91+
// )),
92+
// crate::r#const::SOLC_PRODUCTION_NAME.to_owned(),
93+
// cbor_data.clone(),
94+
// );
95+
// cbor.to_vec()
96+
// }
97+
// Some(era_compiler_common::Hash::Keccak256(ref hash)) => hash.to_vec(),
98+
// None => {
99+
// let cbor = era_compiler_common::CBOR::<'_, String>::new(
100+
// None,
101+
// crate::r#const::SOLC_PRODUCTION_NAME.to_owned(),
102+
// cbor_data.clone(),
103+
// );
104+
// cbor.to_vec()
105+
// }
106+
// };
107+
// self.bytecode.extend(metadata);
108+
// }
109+
Ok(())
63110
}
64111

65112
///
66-
/// Checks whether the object name matches a dot-separated dependency name.
67-
///
68-
/// This function is only useful for Yul codegen where object names like `A_25.A_25_deployed` are found.
69-
/// For EVM assembly codegen, it performs a simple comparison.
113+
/// Whether the object requires assebmling with its dependencies.
70114
///
71-
pub fn matches_dependency(&self, dependency: &str) -> bool {
72-
let dependency = match self.codegen {
73-
Some(era_solc::StandardJsonInputCodegen::EVMLA) | None => dependency,
74-
Some(era_solc::StandardJsonInputCodegen::Yul) => {
75-
dependency.split('.').last().expect("Always exists")
76-
}
77-
};
78-
79-
self.identifier.as_str() == dependency
115+
pub fn requires_assembling(&self) -> bool {
116+
!self.is_assembled && !self.dependencies.inner.is_empty()
80117
}
81118
}

0 commit comments

Comments
 (0)