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
+9 -11
View File
@@ -1,11 +1,15 @@
//! The assignment expression statement.
use std::collections::HashSet;
use std::collections::BTreeSet;
use inkwell::types::BasicType;
use serde::Deserialize;
use serde::Serialize;
use revive_common::BIT_LENGTH_X32;
use revive_llvm_context::PolkaVMContext;
use revive_llvm_context::PolkaVMWriteLLVM;
use crate::error::Error;
use crate::lexer::token::lexeme::symbol::Symbol;
use crate::lexer::token::lexeme::Lexeme;
@@ -108,19 +112,13 @@ impl Assignment {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
self.initializer.get_missing_libraries()
}
}
impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for Assignment
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
fn into_llvm(
mut self,
context: &mut revive_llvm_context::PolkaVMContext<D>,
) -> anyhow::Result<()> {
impl PolkaVMWriteLLVM for Assignment {
fn into_llvm(mut self, context: &mut PolkaVMContext) -> anyhow::Result<()> {
context.set_debug_location(self.location.line, self.location.column, None)?;
let value = match self.initializer.into_llvm(context)? {
@@ -158,7 +156,7 @@ where
&[
context.word_const(0),
context
.integer_type(revive_common::BIT_LENGTH_X32)
.integer_type(BIT_LENGTH_X32)
.const_int(index as u64, false),
],
context.word_type().as_basic_type_enum(),
+8 -9
View File
@@ -1,11 +1,13 @@
//! The source code block.
use std::collections::HashSet;
use std::collections::BTreeSet;
use inkwell::debug_info::AsDIScope;
use serde::Deserialize;
use serde::Serialize;
use inkwell::debug_info::AsDIScope;
use revive_llvm_context::PolkaVMContext;
use revive_llvm_context::PolkaVMWriteLLVM;
use crate::error::Error;
use crate::lexer::token::lexeme::symbol::Symbol;
@@ -123,8 +125,8 @@ impl Block {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
let mut libraries = HashSet::new();
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
let mut libraries = BTreeSet::new();
for statement in self.statements.iter() {
libraries.extend(statement.get_missing_libraries());
}
@@ -132,11 +134,8 @@ impl Block {
}
}
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<()> {
impl PolkaVMWriteLLVM for Block {
fn into_llvm(self, context: &mut PolkaVMContext) -> anyhow::Result<()> {
let current_function = context.current_function().borrow().name().to_owned();
let current_block = context.basic_block();
+7 -7
View File
@@ -1,10 +1,13 @@
//! The YUL code.
use std::collections::HashSet;
use std::collections::BTreeSet;
use serde::Deserialize;
use serde::Serialize;
use revive_llvm_context::PolkaVMContext;
use revive_llvm_context::PolkaVMWriteLLVM;
use crate::error::Error;
use crate::lexer::token::lexeme::keyword::Keyword;
use crate::lexer::token::lexeme::Lexeme;
@@ -52,16 +55,13 @@ impl Code {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
self.block.get_missing_libraries()
}
}
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<()> {
impl PolkaVMWriteLLVM for Code {
fn into_llvm(self, context: &mut PolkaVMContext) -> anyhow::Result<()> {
self.block.into_llvm(context)?;
Ok(())
@@ -3,7 +3,7 @@
pub mod name;
pub mod verbatim;
use std::collections::HashSet;
use std::collections::BTreeSet;
use inkwell::values::BasicValue;
use serde::Deserialize;
@@ -95,8 +95,8 @@ impl FunctionCall {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
let mut libraries = HashSet::new();
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
let mut libraries = BTreeSet::new();
if let Name::LinkerSymbol = self.name {
let _argument = self.arguments.first().expect("Always exists");
@@ -117,13 +117,10 @@ impl FunctionCall {
}
/// Converts the function call into an LLVM value.
pub fn into_llvm<'ctx, D>(
pub fn into_llvm<'ctx>(
mut self,
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<Option<inkwell::values::BasicValueEnum<'ctx>>>
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
context: &mut revive_llvm_context::PolkaVMContext<'ctx>,
) -> anyhow::Result<Option<inkwell::values::BasicValueEnum<'ctx>>> {
let location = self.location;
context.set_debug_location(location.line, location.column, None)?;
@@ -164,7 +161,7 @@ impl FunctionCall {
}
Name::Add => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_arithmetic::addition(
context,
arguments[0].into_int_value(),
@@ -173,7 +170,7 @@ impl FunctionCall {
.map(Some)
}
Name::Sub => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_arithmetic::subtraction(
context,
arguments[0].into_int_value(),
@@ -182,7 +179,7 @@ impl FunctionCall {
.map(Some)
}
Name::Mul => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_arithmetic::multiplication(
context,
arguments[0].into_int_value(),
@@ -191,7 +188,7 @@ impl FunctionCall {
.map(Some)
}
Name::Div => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_arithmetic::division(
context,
arguments[0].into_int_value(),
@@ -200,7 +197,7 @@ impl FunctionCall {
.map(Some)
}
Name::Mod => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_arithmetic::remainder(
context,
arguments[0].into_int_value(),
@@ -209,7 +206,7 @@ impl FunctionCall {
.map(Some)
}
Name::Sdiv => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_arithmetic::division_signed(
context,
arguments[0].into_int_value(),
@@ -218,7 +215,7 @@ impl FunctionCall {
.map(Some)
}
Name::Smod => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_arithmetic::remainder_signed(
context,
arguments[0].into_int_value(),
@@ -228,7 +225,7 @@ impl FunctionCall {
}
Name::Lt => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_comparison::compare(
context,
arguments[0].into_int_value(),
@@ -238,7 +235,7 @@ impl FunctionCall {
.map(Some)
}
Name::Gt => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_comparison::compare(
context,
arguments[0].into_int_value(),
@@ -248,7 +245,7 @@ impl FunctionCall {
.map(Some)
}
Name::Eq => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_comparison::compare(
context,
arguments[0].into_int_value(),
@@ -258,7 +255,7 @@ impl FunctionCall {
.map(Some)
}
Name::IsZero => {
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let arguments = self.pop_arguments_llvm::<1>(context)?;
revive_llvm_context::polkavm_evm_comparison::compare(
context,
arguments[0].into_int_value(),
@@ -268,7 +265,7 @@ impl FunctionCall {
.map(Some)
}
Name::Slt => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_comparison::compare(
context,
arguments[0].into_int_value(),
@@ -278,7 +275,7 @@ impl FunctionCall {
.map(Some)
}
Name::Sgt => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_comparison::compare(
context,
arguments[0].into_int_value(),
@@ -289,7 +286,7 @@ impl FunctionCall {
}
Name::Or => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_bitwise::or(
context,
arguments[0].into_int_value(),
@@ -298,7 +295,7 @@ impl FunctionCall {
.map(Some)
}
Name::Xor => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_bitwise::xor(
context,
arguments[0].into_int_value(),
@@ -307,7 +304,7 @@ impl FunctionCall {
.map(Some)
}
Name::Not => {
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let arguments = self.pop_arguments_llvm::<1>(context)?;
revive_llvm_context::polkavm_evm_bitwise::xor(
context,
arguments[0].into_int_value(),
@@ -316,7 +313,7 @@ impl FunctionCall {
.map(Some)
}
Name::And => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_bitwise::and(
context,
arguments[0].into_int_value(),
@@ -325,7 +322,7 @@ impl FunctionCall {
.map(Some)
}
Name::Shl => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_bitwise::shift_left(
context,
arguments[0].into_int_value(),
@@ -334,7 +331,7 @@ impl FunctionCall {
.map(Some)
}
Name::Shr => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_bitwise::shift_right(
context,
arguments[0].into_int_value(),
@@ -343,7 +340,7 @@ impl FunctionCall {
.map(Some)
}
Name::Sar => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_bitwise::shift_right_arithmetic(
context,
arguments[0].into_int_value(),
@@ -352,7 +349,7 @@ impl FunctionCall {
.map(Some)
}
Name::Byte => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_bitwise::byte(
context,
arguments[0].into_int_value(),
@@ -361,12 +358,12 @@ impl FunctionCall {
.map(Some)
}
Name::Pop => {
let _arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let _arguments = self.pop_arguments_llvm::<1>(context)?;
Ok(None)
}
Name::AddMod => {
let arguments = self.pop_arguments_llvm::<D, 3>(context)?;
let arguments = self.pop_arguments_llvm::<3>(context)?;
revive_llvm_context::polkavm_evm_math::add_mod(
context,
arguments[0].into_int_value(),
@@ -376,7 +373,7 @@ impl FunctionCall {
.map(Some)
}
Name::MulMod => {
let arguments = self.pop_arguments_llvm::<D, 3>(context)?;
let arguments = self.pop_arguments_llvm::<3>(context)?;
revive_llvm_context::polkavm_evm_math::mul_mod(
context,
arguments[0].into_int_value(),
@@ -386,7 +383,7 @@ impl FunctionCall {
.map(Some)
}
Name::Exp => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_math::exponent(
context,
arguments[0].into_int_value(),
@@ -395,7 +392,7 @@ impl FunctionCall {
.map(Some)
}
Name::SignExtend => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_math::sign_extend(
context,
arguments[0].into_int_value(),
@@ -405,7 +402,7 @@ impl FunctionCall {
}
Name::Keccak256 => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_crypto::sha3(
context,
arguments[0].into_int_value(),
@@ -415,7 +412,7 @@ impl FunctionCall {
}
Name::MLoad => {
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let arguments = self.pop_arguments_llvm::<1>(context)?;
revive_llvm_context::polkavm_evm_memory::load(
context,
arguments[0].into_int_value(),
@@ -423,7 +420,7 @@ impl FunctionCall {
.map(Some)
}
Name::MStore => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_memory::store(
context,
arguments[0].into_int_value(),
@@ -432,7 +429,7 @@ impl FunctionCall {
.map(|_| None)
}
Name::MStore8 => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_memory::store_byte(
context,
arguments[0].into_int_value(),
@@ -441,7 +438,7 @@ impl FunctionCall {
.map(|_| None)
}
Name::MCopy => {
let arguments = self.pop_arguments_llvm::<D, 3>(context)?;
let arguments = self.pop_arguments_llvm::<3>(context)?;
let destination = revive_llvm_context::PolkaVMPointer::new_with_offset(
context,
revive_llvm_context::PolkaVMAddressSpace::Heap,
@@ -467,11 +464,11 @@ impl FunctionCall {
}
Name::SLoad => {
let arguments = self.pop_arguments::<D, 1>(context)?;
let arguments = self.pop_arguments::<1>(context)?;
revive_llvm_context::polkavm_evm_storage::load(context, &arguments[0]).map(Some)
}
Name::SStore => {
let arguments = self.pop_arguments::<D, 2>(context)?;
let arguments = self.pop_arguments::<2>(context)?;
revive_llvm_context::polkavm_evm_storage::store(
context,
&arguments[0],
@@ -480,12 +477,12 @@ impl FunctionCall {
.map(|_| None)
}
Name::TLoad => {
let arguments = self.pop_arguments::<D, 1>(context)?;
let arguments = self.pop_arguments::<1>(context)?;
revive_llvm_context::polkavm_evm_storage::transient_load(context, &arguments[0])
.map(Some)
}
Name::TStore => {
let arguments = self.pop_arguments::<D, 2>(context)?;
let arguments = self.pop_arguments::<2>(context)?;
revive_llvm_context::polkavm_evm_storage::transient_store(
context,
&arguments[0],
@@ -494,7 +491,7 @@ impl FunctionCall {
.map(|_| None)
}
Name::LoadImmutable => {
let mut arguments = self.pop_arguments::<D, 1>(context)?;
let mut arguments = self.pop_arguments::<1>(context)?;
let key = arguments[0].original.take().ok_or_else(|| {
anyhow::anyhow!("{} `load_immutable` literal is missing", location)
})?;
@@ -506,7 +503,7 @@ impl FunctionCall {
revive_llvm_context::polkavm_evm_immutable::load(context, index).map(Some)
}
Name::SetImmutable => {
let mut arguments = self.pop_arguments::<D, 3>(context)?;
let mut arguments = self.pop_arguments::<3>(context)?;
let key = arguments[1].original.take().ok_or_else(|| {
anyhow::anyhow!("{} `load_immutable` literal is missing", location)
})?;
@@ -518,7 +515,7 @@ impl FunctionCall {
.map(|_| None)
}
Name::CallDataLoad => {
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let arguments = self.pop_arguments_llvm::<1>(context)?;
match context
.code_type()
@@ -550,7 +547,7 @@ impl FunctionCall {
}
}
Name::CallDataCopy => {
let arguments = self.pop_arguments_llvm::<D, 3>(context)?;
let arguments = self.pop_arguments_llvm::<3>(context)?;
match context
.code_type()
@@ -603,7 +600,7 @@ impl FunctionCall {
);
}
let arguments = self.pop_arguments_llvm::<D, 3>(context)?;
let arguments = self.pop_arguments_llvm::<3>(context)?;
revive_llvm_context::polkavm_evm_calldata::copy(
context,
arguments[0].into_int_value(),
@@ -616,7 +613,7 @@ impl FunctionCall {
revive_llvm_context::polkavm_evm_return_data::size(context).map(Some)
}
Name::ReturnDataCopy => {
let arguments = self.pop_arguments_llvm::<D, 3>(context)?;
let arguments = self.pop_arguments_llvm::<3>(context)?;
revive_llvm_context::polkavm_evm_return_data::copy(
context,
arguments[0].into_int_value(),
@@ -626,7 +623,7 @@ impl FunctionCall {
.map(|_| None)
}
Name::ExtCodeSize => {
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let arguments = self.pop_arguments_llvm::<1>(context)?;
revive_llvm_context::polkavm_evm_ext_code::size(
context,
Some(arguments[0].into_int_value()),
@@ -634,7 +631,7 @@ impl FunctionCall {
.map(Some)
}
Name::ExtCodeHash => {
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let arguments = self.pop_arguments_llvm::<1>(context)?;
revive_llvm_context::polkavm_evm_ext_code::hash(
context,
arguments[0].into_int_value(),
@@ -643,7 +640,7 @@ impl FunctionCall {
}
Name::Return => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_return::r#return(
context,
arguments[0].into_int_value(),
@@ -652,7 +649,7 @@ impl FunctionCall {
.map(|_| None)
}
Name::Revert => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_return::revert(
context,
arguments[0].into_int_value(),
@@ -666,7 +663,7 @@ impl FunctionCall {
}
Name::Log0 => {
let arguments = self.pop_arguments_llvm::<D, 2>(context)?;
let arguments = self.pop_arguments_llvm::<2>(context)?;
revive_llvm_context::polkavm_evm_event::log(
context,
arguments[0].into_int_value(),
@@ -676,7 +673,7 @@ impl FunctionCall {
.map(|_| None)
}
Name::Log1 => {
let arguments = self.pop_arguments_llvm::<D, 3>(context)?;
let arguments = self.pop_arguments_llvm::<3>(context)?;
revive_llvm_context::polkavm_evm_event::log(
context,
arguments[0].into_int_value(),
@@ -686,7 +683,7 @@ impl FunctionCall {
.map(|_| None)
}
Name::Log2 => {
let arguments = self.pop_arguments_llvm::<D, 4>(context)?;
let arguments = self.pop_arguments_llvm::<4>(context)?;
revive_llvm_context::polkavm_evm_event::log(
context,
arguments[0].into_int_value(),
@@ -696,7 +693,7 @@ impl FunctionCall {
.map(|_| None)
}
Name::Log3 => {
let arguments = self.pop_arguments_llvm::<D, 5>(context)?;
let arguments = self.pop_arguments_llvm::<5>(context)?;
revive_llvm_context::polkavm_evm_event::log(
context,
arguments[0].into_int_value(),
@@ -706,7 +703,7 @@ impl FunctionCall {
.map(|_| None)
}
Name::Log4 => {
let arguments = self.pop_arguments_llvm::<D, 6>(context)?;
let arguments = self.pop_arguments_llvm::<6>(context)?;
revive_llvm_context::polkavm_evm_event::log(
context,
arguments[0].into_int_value(),
@@ -717,7 +714,7 @@ impl FunctionCall {
}
Name::Call => {
let arguments = self.pop_arguments::<D, 7>(context)?;
let arguments = self.pop_arguments::<7>(context)?;
let gas = arguments[0].access(context)?.into_int_value();
let address = arguments[1].access(context)?.into_int_value();
@@ -747,7 +744,7 @@ impl FunctionCall {
.map(Some)
}
Name::StaticCall => {
let arguments = self.pop_arguments::<D, 6>(context)?;
let arguments = self.pop_arguments::<6>(context)?;
let gas = arguments[0].access(context)?.into_int_value();
let address = arguments[1].access(context)?.into_int_value();
@@ -776,7 +773,7 @@ impl FunctionCall {
.map(Some)
}
Name::DelegateCall => {
let arguments = self.pop_arguments::<D, 6>(context)?;
let arguments = self.pop_arguments::<6>(context)?;
let gas = arguments[0].access(context)?.into_int_value();
let address = arguments[1].access(context)?.into_int_value();
@@ -804,7 +801,7 @@ impl FunctionCall {
}
Name::Create => {
let arguments = self.pop_arguments_llvm::<D, 3>(context)?;
let arguments = self.pop_arguments_llvm::<3>(context)?;
let value = arguments[0].into_int_value();
let input_offset = arguments[1].into_int_value();
@@ -820,7 +817,7 @@ impl FunctionCall {
.map(Some)
}
Name::Create2 => {
let arguments = self.pop_arguments_llvm::<D, 4>(context)?;
let arguments = self.pop_arguments_llvm::<4>(context)?;
let value = arguments[0].into_int_value();
let input_offset = arguments[1].into_int_value();
@@ -837,7 +834,7 @@ impl FunctionCall {
.map(Some)
}
Name::DataOffset => {
let mut arguments = self.pop_arguments::<D, 1>(context)?;
let mut arguments = self.pop_arguments::<1>(context)?;
let identifier = arguments[0].original.take().ok_or_else(|| {
anyhow::anyhow!("{} `dataoffset` object identifier is missing", location)
@@ -848,7 +845,7 @@ impl FunctionCall {
.map(Some)
}
Name::DataSize => {
let mut arguments = self.pop_arguments::<D, 1>(context)?;
let mut arguments = self.pop_arguments::<1>(context)?;
let identifier = arguments[0].original.take().ok_or_else(|| {
anyhow::anyhow!("{} `dataoffset` object identifier is missing", location)
@@ -859,7 +856,7 @@ impl FunctionCall {
.map(Some)
}
Name::DataCopy => {
let arguments = self.pop_arguments_llvm::<D, 3>(context)?;
let arguments = self.pop_arguments_llvm::<3>(context)?;
revive_llvm_context::polkavm_evm_memory::store(
context,
arguments[0].into_int_value(),
@@ -869,19 +866,14 @@ impl FunctionCall {
}
Name::LinkerSymbol => {
let mut arguments = self.pop_arguments::<D, 1>(context)?;
let mut arguments = self.pop_arguments::<1>(context)?;
let path = arguments[0].original.take().ok_or_else(|| {
anyhow::anyhow!("{} Linker symbol literal is missing", location)
})?;
Ok(Some(
context
.resolve_library(path.as_str())?
.as_basic_value_enum(),
))
revive_llvm_context::polkavm_evm_call::linker_symbol(context, &path).map(Some)
}
Name::MemoryGuard => {
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let arguments = self.pop_arguments_llvm::<1>(context)?;
Ok(Some(arguments[0]))
}
@@ -894,7 +886,7 @@ impl FunctionCall {
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)?;
let arguments = self.pop_arguments_llvm::<1>(context)?;
let address = arguments[0].into_int_value();
revive_llvm_context::polkavm_evm_ether_gas::balance(context, address).map(Some)
@@ -923,14 +915,14 @@ impl FunctionCall {
revive_llvm_context::polkavm_evm_contract_context::block_number(context).map(Some)
}
Name::BlockHash => {
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let arguments = self.pop_arguments_llvm::<1>(context)?;
let index = arguments[0].into_int_value();
revive_llvm_context::polkavm_evm_contract_context::block_hash(context, index)
.map(Some)
}
Name::BlobHash => {
let _arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let _arguments = self.pop_arguments_llvm::<1>(context)?;
anyhow::bail!(
"{} The `BLOBHASH` instruction is not supported in revive",
location
@@ -959,19 +951,19 @@ impl FunctionCall {
} => verbatim::verbatim(context, &mut self, input_size, output_size),
Name::CallCode => {
let _arguments = self.pop_arguments_llvm::<D, 7>(context)?;
let _arguments = self.pop_arguments_llvm::<7>(context)?;
anyhow::bail!("{} The `CALLCODE` instruction is not supported", location)
}
Name::Pc => anyhow::bail!("{} The `PC` instruction is not supported", location),
Name::ExtCodeCopy => {
let _arguments = self.pop_arguments_llvm::<D, 4>(context)?;
let _arguments = self.pop_arguments_llvm::<4>(context)?;
anyhow::bail!(
"{} The `EXTCODECOPY` instruction is not supported",
location
)
}
Name::SelfDestruct => {
let _arguments = self.pop_arguments_llvm::<D, 1>(context)?;
let _arguments = self.pop_arguments_llvm::<1>(context)?;
anyhow::bail!(
"{} The `SELFDESTRUCT` instruction is not supported",
location
@@ -981,13 +973,10 @@ impl FunctionCall {
}
/// Pops the specified number of arguments, converted into their LLVM values.
fn pop_arguments_llvm<'ctx, D, const N: usize>(
fn pop_arguments_llvm<'ctx, const N: usize>(
&mut self,
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<[inkwell::values::BasicValueEnum<'ctx>; N]>
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
context: &mut revive_llvm_context::PolkaVMContext<'ctx>,
) -> anyhow::Result<[inkwell::values::BasicValueEnum<'ctx>; N]> {
let mut arguments = Vec::with_capacity(N);
for expression in self.arguments.drain(0..N).rev() {
arguments.push(
@@ -1005,13 +994,10 @@ impl FunctionCall {
}
/// Pops the specified number of arguments.
fn pop_arguments<'ctx, D, const N: usize>(
fn pop_arguments<'ctx, const N: usize>(
&mut self,
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<[revive_llvm_context::PolkaVMArgument<'ctx>; N]>
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
context: &mut revive_llvm_context::PolkaVMContext<'ctx>,
) -> anyhow::Result<[revive_llvm_context::PolkaVMArgument<'ctx>; N]> {
let mut arguments = Vec::with_capacity(N);
for expression in self.arguments.drain(0..N).rev() {
arguments.push(expression.into_llvm(context)?.expect("Always exists"));
@@ -1,17 +1,16 @@
//! Translates the verbatim simulations.
use revive_llvm_context::PolkaVMContext;
use crate::parser::statement::expression::function_call::FunctionCall;
/// Translates the verbatim simulations.
pub fn verbatim<'ctx, D>(
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
pub fn verbatim<'ctx>(
context: &mut PolkaVMContext<'ctx>,
call: &mut FunctionCall,
_input_size: usize,
output_size: usize,
) -> anyhow::Result<Option<inkwell::values::BasicValueEnum<'ctx>>>
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
) -> anyhow::Result<Option<inkwell::values::BasicValueEnum<'ctx>>> {
if output_size > 1 {
anyhow::bail!(
"{} Verbatim instructions with multiple return values are not supported",
@@ -19,7 +18,7 @@ where
);
}
let mut arguments = call.pop_arguments::<D, 1>(context)?;
let mut arguments = call.pop_arguments::<1>(context)?;
let identifier = arguments[0]
.original
.take()
@@ -7,6 +7,12 @@ use num::Zero;
use serde::Deserialize;
use serde::Serialize;
use revive_common::BASE_DECIMAL;
use revive_common::BASE_HEXADECIMAL;
use revive_common::BYTE_LENGTH_WORD;
use revive_llvm_context::PolkaVMArgument;
use revive_llvm_context::PolkaVMContext;
use crate::error::Error;
use crate::lexer::token::lexeme::literal::boolean::Boolean as BooleanLiteral;
use crate::lexer::token::lexeme::literal::integer::Integer as IntegerLiteral;
@@ -72,13 +78,10 @@ impl Literal {
}
/// Converts the literal into its LLVM.
pub fn into_llvm<'ctx, D>(
pub fn into_llvm<'ctx>(
self,
context: &revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<revive_llvm_context::PolkaVMArgument<'ctx>>
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
context: &PolkaVMContext<'ctx>,
) -> anyhow::Result<PolkaVMArgument<'ctx>> {
match self.inner {
LexicalLiteral::Boolean(inner) => {
let value = self
@@ -99,7 +102,7 @@ impl Literal {
BooleanLiteral::True => num::BigUint::one(),
};
Ok(revive_llvm_context::PolkaVMArgument::value(value).with_constant(constant))
Ok(PolkaVMArgument::value(value).with_constant(constant))
}
LexicalLiteral::Integer(inner) => {
let r#type = self.yul_type.unwrap_or_default().into_llvm(context);
@@ -118,16 +121,15 @@ impl Literal {
let constant = match inner {
IntegerLiteral::Decimal { ref inner } => {
num::BigUint::from_str_radix(inner.as_str(), revive_common::BASE_DECIMAL)
num::BigUint::from_str_radix(inner.as_str(), BASE_DECIMAL)
}
IntegerLiteral::Hexadecimal { ref inner } => {
num::BigUint::from_str_radix(&inner["0x".len()..], BASE_HEXADECIMAL)
}
IntegerLiteral::Hexadecimal { ref inner } => num::BigUint::from_str_radix(
&inner["0x".len()..],
revive_common::BASE_HEXADECIMAL,
),
}
.expect("Always valid");
Ok(revive_llvm_context::PolkaVMArgument::value(value).with_constant(constant))
Ok(PolkaVMArgument::value(value).with_constant(constant))
}
LexicalLiteral::String(inner) => {
let string = inner.inner;
@@ -136,7 +138,7 @@ impl Literal {
let mut hex_string = if inner.is_hexadecimal {
string.clone()
} else {
let mut hex_string = String::with_capacity(revive_common::BYTE_LENGTH_WORD * 2);
let mut hex_string = String::with_capacity(BYTE_LENGTH_WORD * 2);
let mut index = 0;
loop {
if index >= string.len() {
@@ -151,17 +153,16 @@ impl Literal {
index += 3;
} else if string[index..].starts_with('u') {
let codepoint_str = &string[index + 1..index + 5];
let codepoint = u32::from_str_radix(
codepoint_str,
revive_common::BASE_HEXADECIMAL,
)
.map_err(|error| {
anyhow::anyhow!(
"Invalid codepoint `{}`: {}",
codepoint_str,
error
)
})?;
let codepoint =
u32::from_str_radix(codepoint_str, BASE_HEXADECIMAL).map_err(
|error| {
anyhow::anyhow!(
"Invalid codepoint `{}`: {}",
codepoint_str,
error
)
},
)?;
let unicode_char = char::from_u32(codepoint).ok_or_else(|| {
anyhow::anyhow!("Invalid codepoint {}", codepoint)
})?;
@@ -197,16 +198,16 @@ impl Literal {
hex_string
};
if hex_string.len() > revive_common::BYTE_LENGTH_WORD * 2 {
if hex_string.len() > BYTE_LENGTH_WORD * 2 {
return Ok(revive_llvm_context::PolkaVMArgument::value(
r#type.const_zero().as_basic_value_enum(),
)
.with_original(string));
}
if hex_string.len() < revive_common::BYTE_LENGTH_WORD * 2 {
if hex_string.len() < BYTE_LENGTH_WORD * 2 {
hex_string.push_str(
"0".repeat((revive_common::BYTE_LENGTH_WORD * 2) - hex_string.len())
"0".repeat((BYTE_LENGTH_WORD * 2) - hex_string.len())
.as_str(),
);
}
@@ -218,7 +219,7 @@ impl Literal {
)
.expect("The value is valid")
.as_basic_value_enum();
Ok(revive_llvm_context::PolkaVMArgument::value(value).with_original(string))
Ok(PolkaVMArgument::value(value).with_original(string))
}
}
}
@@ -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)),
}
}
}
+7 -7
View File
@@ -1,10 +1,13 @@
//! The for-loop statement.
use std::collections::HashSet;
use std::collections::BTreeSet;
use serde::Deserialize;
use serde::Serialize;
use revive_llvm_context::PolkaVMContext;
use revive_llvm_context::PolkaVMWriteLLVM;
use crate::error::Error;
use crate::lexer::token::location::Location;
use crate::lexer::token::Token;
@@ -53,7 +56,7 @@ impl ForLoop {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
let mut libraries = self.initializer.get_missing_libraries();
libraries.extend(self.condition.get_missing_libraries());
libraries.extend(self.finalizer.get_missing_libraries());
@@ -62,11 +65,8 @@ impl ForLoop {
}
}
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<()> {
impl PolkaVMWriteLLVM for ForLoop {
fn into_llvm(self, context: &mut PolkaVMContext) -> anyhow::Result<()> {
self.initializer.into_llvm(context)?;
let condition_block = context.append_basic_block("for_condition");
@@ -1,13 +1,20 @@
//! The function definition statement.
use std::collections::BTreeSet;
use std::collections::HashSet;
use inkwell::types::BasicType;
use serde::Deserialize;
use serde::Serialize;
use revive_common::BIT_LENGTH_X32;
use revive_llvm_context::PolkaVMAttribute;
use revive_llvm_context::PolkaVMContext;
use revive_llvm_context::PolkaVMFunction;
use revive_llvm_context::PolkaVMFunctionReturn;
use revive_llvm_context::PolkaVMFunctionYulData;
use revive_llvm_context::PolkaVMWriteLLVM;
use crate::error::Error;
use crate::lexer::token::lexeme::symbol::Symbol;
use crate::lexer::token::lexeme::Lexeme;
@@ -38,7 +45,7 @@ pub struct FunctionDefinition {
/// The function body block.
pub body: Block,
/// The function LLVM attributes encoded in the identifier.
pub attributes: BTreeSet<revive_llvm_context::PolkaVMAttribute>,
pub attributes: BTreeSet<PolkaVMAttribute>,
}
impl FunctionDefinition {
@@ -148,14 +155,14 @@ impl FunctionDefinition {
}
/// Gets the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
self.body.get_missing_libraries()
}
/// Gets the list of LLVM attributes provided in the function name.
pub fn get_llvm_attributes(
identifier: &Identifier,
) -> Result<BTreeSet<revive_llvm_context::PolkaVMAttribute>, Error> {
) -> Result<BTreeSet<PolkaVMAttribute>, Error> {
let mut valid_attributes = BTreeSet::new();
let llvm_begin = identifier.inner.find(Self::LLVM_ATTRIBUTE_PREFIX);
@@ -172,7 +179,7 @@ impl FunctionDefinition {
let mut invalid_attributes = BTreeSet::new();
for value in attribute_string.split('_') {
match revive_llvm_context::PolkaVMAttribute::try_from(value) {
match PolkaVMAttribute::try_from(value) {
Ok(attribute) => valid_attributes.insert(attribute),
Err(value) => invalid_attributes.insert(value),
};
@@ -190,14 +197,8 @@ impl FunctionDefinition {
}
}
impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for FunctionDefinition
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
fn declare(
&mut self,
context: &mut revive_llvm_context::PolkaVMContext<D>,
) -> anyhow::Result<()> {
impl PolkaVMWriteLLVM for FunctionDefinition {
fn declare(&mut self, context: &mut PolkaVMContext) -> anyhow::Result<()> {
context.set_debug_location(self.location.line, self.location.column, None)?;
let argument_types: Vec<_> = self
.arguments
@@ -217,7 +218,7 @@ where
Some(inkwell::module::Linkage::External),
Some((self.location.line, self.location.column)),
)?;
revive_llvm_context::PolkaVMFunction::set_attributes(
PolkaVMFunction::set_attributes(
context.llvm(),
function.borrow().declaration(),
&self.attributes.clone().into_iter().collect::<Vec<_>>(),
@@ -225,15 +226,12 @@ where
);
function
.borrow_mut()
.set_yul_data(revive_llvm_context::PolkaVMFunctionYulData::default());
.set_yul_data(PolkaVMFunctionYulData::default());
Ok(())
}
fn into_llvm(
mut self,
context: &mut revive_llvm_context::PolkaVMContext<D>,
) -> anyhow::Result<()> {
fn into_llvm(mut self, context: &mut PolkaVMContext) -> anyhow::Result<()> {
context.set_current_function(
self.identifier.as_str(),
Some((self.location.line, self.location.column)),
@@ -242,8 +240,8 @@ where
let r#return = context.current_function().borrow().r#return();
match r#return {
revive_llvm_context::PolkaVMFunctionReturn::None => {}
revive_llvm_context::PolkaVMFunctionReturn::Primitive { pointer } => {
PolkaVMFunctionReturn::None => {}
PolkaVMFunctionReturn::Primitive { pointer } => {
let identifier = self.result.pop().expect("Always exists");
let r#type = identifier.r#type.unwrap_or_default();
@@ -253,7 +251,7 @@ where
.borrow_mut()
.insert_stack_pointer(identifier.inner, pointer);
}
revive_llvm_context::PolkaVMFunctionReturn::Compound { pointer, .. } => {
PolkaVMFunctionReturn::Compound { pointer, .. } => {
for (index, identifier) in self.result.into_iter().enumerate() {
let r#type = identifier.r#type.unwrap_or_default().into_llvm(context);
let pointer = context.build_gep(
@@ -261,7 +259,7 @@ where
&[
context.word_const(0),
context
.integer_type(revive_common::BIT_LENGTH_X32)
.integer_type(BIT_LENGTH_X32)
.const_int(index as u64, false),
],
context.word_type(),
@@ -312,14 +310,14 @@ where
context.set_basic_block(context.current_function().borrow().return_block());
match context.current_function().borrow().r#return() {
revive_llvm_context::PolkaVMFunctionReturn::None => {
PolkaVMFunctionReturn::None => {
context.build_return(None);
}
revive_llvm_context::PolkaVMFunctionReturn::Primitive { pointer } => {
PolkaVMFunctionReturn::Primitive { pointer } => {
let return_value = context.build_load(pointer, "return_value")?;
context.build_return(Some(&return_value));
}
revive_llvm_context::PolkaVMFunctionReturn::Compound { pointer, .. } => {
PolkaVMFunctionReturn::Compound { pointer, .. } => {
let return_value = context.build_load(pointer, "return_value")?;
context.build_return(Some(&return_value));
}
@@ -1,10 +1,13 @@
//! The if-conditional statement.
use std::collections::HashSet;
use std::collections::BTreeSet;
use serde::Deserialize;
use serde::Serialize;
use revive_llvm_context::PolkaVMContext;
use revive_llvm_context::PolkaVMWriteLLVM;
use crate::error::Error;
use crate::lexer::token::location::Location;
use crate::lexer::token::Token;
@@ -43,18 +46,15 @@ impl IfConditional {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
let mut libraries = self.condition.get_missing_libraries();
libraries.extend(self.block.get_missing_libraries());
libraries
}
}
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<()> {
impl PolkaVMWriteLLVM for IfConditional {
fn into_llvm(self, context: &mut PolkaVMContext) -> anyhow::Result<()> {
let condition = self
.condition
.into_llvm(context)?
+16 -16
View File
@@ -1,17 +1,6 @@
//! The block statement.
pub mod assignment;
pub mod block;
pub mod code;
pub mod expression;
pub mod for_loop;
pub mod function_definition;
pub mod if_conditional;
pub mod object;
pub mod switch;
pub mod variable_declaration;
use std::collections::HashSet;
use std::collections::BTreeSet;
use serde::Deserialize;
use serde::Serialize;
@@ -37,6 +26,17 @@ use self::object::Object;
use self::switch::Switch;
use self::variable_declaration::VariableDeclaration;
pub mod assignment;
pub mod block;
pub mod code;
pub mod expression;
pub mod for_loop;
pub mod function_definition;
pub mod if_conditional;
pub mod object;
pub mod switch;
pub mod variable_declaration;
/// The Yul block statement.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub enum Statement {
@@ -142,7 +142,7 @@ impl Statement {
}
/// 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::Object(inner) => inner.get_missing_libraries(),
Self::Code(inner) => inner.get_missing_libraries(),
@@ -154,9 +154,9 @@ impl Statement {
Self::IfConditional(inner) => inner.get_missing_libraries(),
Self::Switch(inner) => inner.get_missing_libraries(),
Self::ForLoop(inner) => inner.get_missing_libraries(),
Self::Continue(_) => HashSet::new(),
Self::Break(_) => HashSet::new(),
Self::Leave(_) => HashSet::new(),
Self::Continue(_) => BTreeSet::new(),
Self::Break(_) => BTreeSet::new(),
Self::Leave(_) => BTreeSet::new(),
}
}
+8 -11
View File
@@ -1,12 +1,15 @@
//! The YUL object.
use std::collections::BTreeSet;
use std::collections::HashSet;
use inkwell::debug_info::AsDIScope;
use serde::Deserialize;
use serde::Serialize;
use revive_llvm_context::PolkaVMContext;
use revive_llvm_context::PolkaVMWriteLLVM;
use crate::error::Error;
use crate::lexer::token::lexeme::keyword::Keyword;
use crate::lexer::token::lexeme::literal::Literal;
@@ -170,7 +173,7 @@ impl Object {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
let mut missing_libraries = self.code.get_missing_libraries();
if let Some(inner_object) = &self.inner_object {
missing_libraries.extend(inner_object.get_missing_libraries());
@@ -179,14 +182,8 @@ impl Object {
}
}
impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for Object
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
fn declare(
&mut self,
context: &mut revive_llvm_context::PolkaVMContext<D>,
) -> anyhow::Result<()> {
impl PolkaVMWriteLLVM for Object {
fn declare(&mut self, context: &mut PolkaVMContext) -> anyhow::Result<()> {
revive_llvm_context::PolkaVMLoadImmutableDataFunction.declare(context)?;
revive_llvm_context::PolkaVMStoreImmutableDataFunction.declare(context)?;
@@ -270,7 +267,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) -> anyhow::Result<()> {
if let Some(debug_info) = context.debug_info() {
let di_builder = debug_info.builder();
let object_name: &str = self.identifier.as_str();
@@ -1,6 +1,6 @@
//! The switch statement case.
use std::collections::HashSet;
use std::collections::BTreeSet;
use serde::Deserialize;
use serde::Serialize;
@@ -58,7 +58,7 @@ impl Case {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
self.block.get_missing_libraries()
}
}
+10 -10
View File
@@ -1,12 +1,13 @@
//! The switch statement.
pub mod case;
use std::collections::HashSet;
use std::collections::BTreeSet;
use serde::Deserialize;
use serde::Serialize;
use revive_llvm_context::PolkaVMContext;
use revive_llvm_context::PolkaVMWriteLLVM;
use crate::error::Error;
use crate::lexer::token::lexeme::keyword::Keyword;
use crate::lexer::token::lexeme::Lexeme;
@@ -21,6 +22,8 @@ use crate::visitor::AstVisitor;
use self::case::Case;
pub mod case;
/// The Yul switch statement.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct Switch {
@@ -108,8 +111,8 @@ impl Switch {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
let mut libraries = HashSet::new();
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
let mut libraries = BTreeSet::new();
for case in self.cases.iter() {
libraries.extend(case.get_missing_libraries());
}
@@ -120,11 +123,8 @@ impl Switch {
}
}
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<()> {
impl PolkaVMWriteLLVM for Switch {
fn into_llvm(self, context: &mut PolkaVMContext) -> anyhow::Result<()> {
context.set_debug_location(self.location.line, self.location.column, None)?;
let scrutinee = self.expression.into_llvm(context)?;
@@ -1,12 +1,16 @@
//! The variable declaration statement.
use std::collections::HashSet;
use std::collections::BTreeSet;
use inkwell::types::BasicType;
use inkwell::values::BasicValue;
use serde::Deserialize;
use serde::Serialize;
use revive_common::BIT_LENGTH_X32;
use revive_llvm_context::PolkaVMContext;
use revive_llvm_context::PolkaVMWriteLLVM;
use crate::error::Error;
use crate::lexer::token::lexeme::symbol::Symbol;
use crate::lexer::token::lexeme::Lexeme;
@@ -84,23 +88,17 @@ impl VariableDeclaration {
}
/// Get the list of missing deployable libraries.
pub fn get_missing_libraries(&self) -> HashSet<String> {
pub fn get_missing_libraries(&self) -> BTreeSet<String> {
self.expression
.as_ref()
.map_or_else(HashSet::new, |expression| {
.map_or_else(BTreeSet::new, |expression| {
expression.get_missing_libraries()
})
}
}
impl<D> revive_llvm_context::PolkaVMWriteLLVM<D> for VariableDeclaration
where
D: revive_llvm_context::PolkaVMDependency + Clone,
{
fn into_llvm<'ctx>(
mut self,
context: &mut revive_llvm_context::PolkaVMContext<'ctx, D>,
) -> anyhow::Result<()> {
impl PolkaVMWriteLLVM for VariableDeclaration {
fn into_llvm<'ctx>(mut self, context: &mut PolkaVMContext<'ctx>) -> anyhow::Result<()> {
if self.bindings.len() == 1 {
let identifier = self.bindings.remove(0);
context.set_debug_location(self.location.line, self.location.column, None)?;
@@ -194,7 +192,7 @@ where
&[
context.word_const(0),
context
.integer_type(revive_common::BIT_LENGTH_X32)
.integer_type(BIT_LENGTH_X32)
.const_int(index as u64, false),
],
binding.r#type.unwrap_or_default().into_llvm(context),