Separate compilation and linker phases (#376)

Separate between compilation and linker phases to allow deploy time
linking and back-porting era compiler changes to fix #91. Unlinked
contract binaries (caused by missing libraries or missing factory
dependencies in turn) are emitted as raw ELF object.

Few drive by fixes:
- #98
- A compiler panic on missing libraries definitions.
- Fixes some incosistent type forwarding in JSON output (empty string
vs. null object).
- Remove the unused fallback for size optimization setting.
- Remove the broken `--lvm-ir`  mode.
- CI workflow fixes.

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
Signed-off-by: xermicus <bigcyrill@hotmail.com>
Signed-off-by: xermicus <cyrill@parity.io>
This commit is contained in:
xermicus
2025-09-27 20:52:22 +02:00
committed by GitHub
parent 13faedf08a
commit 94ec34c4d5
169 changed files with 6288 additions and 5206 deletions
@@ -1,13 +1,13 @@
//! The expression statement.
pub mod function_call;
pub mod literal;
use std::collections::HashSet;
use std::collections::BTreeSet;
use serde::Deserialize;
use serde::Serialize;
use revive_llvm_context::PolkaVMArgument;
use revive_llvm_context::PolkaVMContext;
use crate::error::Error;
use crate::lexer::token::lexeme::symbol::Symbol;
use crate::lexer::token::lexeme::Lexeme;
@@ -22,6 +22,9 @@ use crate::visitor::AstVisitor;
use self::function_call::FunctionCall;
use self::literal::Literal;
pub mod function_call;
pub mod literal;
/// The Yul expression statement.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub enum Expression {
@@ -82,11 +85,11 @@ impl Expression {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
match self {
Self::FunctionCall(inner) => inner.get_missing_libraries(),
Self::Identifier(_) => HashSet::new(),
Self::Literal(_) => HashSet::new(),
Self::Identifier(_) => BTreeSet::new(),
Self::Literal(_) => BTreeSet::new(),
}
}
@@ -100,13 +103,10 @@ impl Expression {
}
/// Converts the expression into an LLVM value.
pub fn into_llvm<'ctx, D>(
pub fn into_llvm<'ctx>(
self,
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<Option<revive_llvm_context::PolkaVMArgument<'ctx>>>
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
context: &mut PolkaVMContext<'ctx>,
) -> anyhow::Result<Option<PolkaVMArgument<'ctx>>> {
match self {
Self::Literal(literal) => literal
.clone()
@@ -133,16 +133,14 @@ impl Expression {
let constant = context.current_function().borrow().yul().get_constant(&id);
let argument = revive_llvm_context::PolkaVMArgument::pointer(pointer, id);
let argument = PolkaVMArgument::pointer(pointer, id);
Ok(Some(match constant {
Some(constant) => argument.with_constant(constant),
_ => argument,
}))
}
Self::FunctionCall(call) => Ok(call
.into_llvm(context)?
.map(revive_llvm_context::PolkaVMArgument::value)),
Self::FunctionCall(call) => Ok(call.into_llvm(context)?.map(PolkaVMArgument::value)),
}
}
}