Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions solx-core/src/project/contract/ir/mlir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
pub struct MLIR {
/// LLVM dialect text of this code segment.
pub source: String,
/// Bare object names of contracts this segment references via cross-
/// contract ops (`sol.new` and friends). Populated during Slang→MLIR
/// emission and used by the assembler to pull in dependency bytecodes.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub dependencies: Vec<String>,
/// Runtime code object that is only set in deploy code.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub runtime_code: Option<Box<Self>>,
Expand Down
19 changes: 8 additions & 11 deletions solx-core/src/project/contract/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,17 +529,14 @@ impl Contract {
solx_utils::CodeSegment::Deploy => bare_name.to_owned(),
solx_utils::CodeSegment::Runtime => runtime_identifier.clone(),
};
let dependencies = match code_segment {
solx_utils::CodeSegment::Deploy => {
let mut dependencies =
solx_codegen_evm::Dependencies::new(code_identifier.as_str());
dependencies.push(runtime_identifier, true);
dependencies
}
solx_utils::CodeSegment::Runtime => {
solx_codegen_evm::Dependencies::new(code_identifier.as_str())
}
};
let mut dependencies =
solx_codegen_evm::Dependencies::new(code_identifier.as_str());
if matches!(code_segment, solx_utils::CodeSegment::Deploy) {
dependencies.push(runtime_identifier, true);
}
for cross_contract in mlir.dependencies.iter() {
dependencies.push(cross_contract.clone(), false);
}

let melior_context = solx_mlir::Context::create_mlir_context();
let raw_llvm =
Expand Down
2 changes: 2 additions & 0 deletions solx-core/src/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,12 @@ impl Project {
let result = contract.mlir.as_ref().map(|output| {
let runtime_code = ContractMLIR {
source: output.runtime_source.clone(),
dependencies: output.dependencies.clone(),
runtime_code: None,
};
let deploy_code = ContractMLIR {
source: output.deploy_source.clone(),
dependencies: output.dependencies.clone(),
runtime_code: Some(Box::new(runtime_code)),
};
Ok::<_, anyhow::Error>(Some(ContractIR::from(deploy_code)))
Expand Down
18 changes: 18 additions & 0 deletions solx-mlir/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod builder;
pub mod environment;
pub mod function;

use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::Once;

Expand Down Expand Up @@ -48,6 +49,11 @@ pub struct Context<'context> {
/// The MLIR type of the contract currently being emitted, used to type
/// `this` expressions. Frontends set this before emitting function bodies.
pub current_contract_type: Option<Type<'context>>,
/// Cross-contract references collected during emission, in encounter
/// order. Populated by [`Self::add_dependency`] from emitters that
/// reach into other contracts (e.g. `sol.new`), drained into the
/// returned [`crate::output::MlirOutput`] by [`Self::finalize_module`].
dependencies: RefCell<Vec<String>>,
}

impl<'context> Context<'context> {
Expand Down Expand Up @@ -159,6 +165,17 @@ impl<'context> Context<'context> {
function_signatures: HashMap::new(),
builder: Builder::new(context),
current_contract_type: None,
dependencies: RefCell::new(Vec::new()),
}
}

/// Records a cross-contract reference (e.g. the object name passed to
/// `sol.new`). Duplicates are ignored. The accumulated list is drained
/// into [`crate::output::MlirOutput::dependencies`] at finalize time.
pub fn add_dependency(&self, name: String) {
let mut dependencies = self.dependencies.borrow_mut();
if !dependencies.iter().any(|existing| existing == &name) {
dependencies.push(name);
}
}

Expand Down Expand Up @@ -316,6 +333,7 @@ impl<'context> Context<'context> {
sol_source,
deploy_source: deploy_llvm,
runtime_source: runtime_llvm,
dependencies: self.dependencies.into_inner(),
})
}

Expand Down
8 changes: 8 additions & 0 deletions solx-mlir/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@ pub struct MlirOutput {
/// LLVM dialect text of the runtime module.
#[serde(default, skip_serializing_if = "String::is_empty")]
pub runtime_source: String,
/// Cross-contract references collected during Slang→MLIR emission.
///
/// Each entry is the bare object name (e.g. `"B"`) of a contract this
/// module references via `sol.new` or other cross-contract ops. The
/// linker resolves these to the dependency's deploy bytecode when
/// assembling.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub dependencies: Vec<String>,
}
Loading