Remove vyper and dead code (#23)

This commit is contained in:
Cyrill Leutwiler
2024-06-05 13:29:07 +02:00
committed by GitHub
parent a04eacabff
commit 9e9227d740
18 changed files with 34 additions and 422 deletions
@@ -11,8 +11,6 @@ pub enum IRType {
EVMLA,
/// Whether to dump the Ethereal IR code.
EthIR,
/// Whether to dump the Vyper LLL IR code.
LLL,
/// Whether to dump the LLVM IR code.
LLVM,
/// Whether to dump the assembly code.
@@ -26,7 +24,6 @@ impl IRType {
Self::Yul => revive_common::EXTENSION_YUL,
Self::EthIR => revive_common::EXTENSION_ETHIR,
Self::EVMLA => revive_common::EXTENSION_EVMLA,
Self::LLL => revive_common::EXTENSION_LLL,
Self::LLVM => revive_common::EXTENSION_LLVM_SOURCE,
Self::Assembly => revive_common::EXTENSION_POLKAVM_ASSEMBLY,
}
@@ -52,16 +52,6 @@ impl DebugConfig {
Ok(())
}
/// Dumps the LLL IR.
pub fn dump_lll(&self, contract_path: &str, code: &str) -> anyhow::Result<()> {
let mut file_path = self.output_directory.to_owned();
let full_file_name = Self::full_file_name(contract_path, None, IRType::LLL);
file_path.push(full_file_name);
std::fs::write(file_path, code)?;
Ok(())
}
/// Dumps the unoptimized LLVM IR.
pub fn dump_llvm_ir_unoptimized(
&self,
+3 -3
View File
@@ -28,15 +28,15 @@ pub use self::polkavm::context::function::r#return::Return as PolkaVMFunctionRet
pub use self::polkavm::context::function::runtime::deploy_code::DeployCode as PolkaVMDeployCodeFunction;
pub use self::polkavm::context::function::runtime::entry::Entry as PolkaVMEntryFunction;
pub use self::polkavm::context::function::runtime::runtime_code::RuntimeCode as PolkaVMRuntimeCodeFunction;
pub use self::polkavm::context::function::runtime::Runtime as PolkaVMRuntime;
pub use self::polkavm::context::function::vyper_data::VyperData as PolkaVMFunctionVyperData;
pub use self::polkavm::context::function::runtime::FUNCTION_DEPLOY_CODE as PolkaVMFunctionDeployCode;
pub use self::polkavm::context::function::runtime::FUNCTION_ENTRY as PolkaVMFunctionEntry;
pub use self::polkavm::context::function::runtime::FUNCTION_RUNTIME_CODE as PolkaVMFunctionRuntimeCode;
pub use self::polkavm::context::function::yul_data::YulData as PolkaVMFunctionYulData;
pub use self::polkavm::context::function::Function as PolkaVMFunction;
pub use self::polkavm::context::global::Global as PolkaVMGlobal;
pub use self::polkavm::context::pointer::Pointer as PolkaVMPointer;
pub use self::polkavm::context::r#loop::Loop as PolkaVMLoop;
pub use self::polkavm::context::solidity_data::SolidityData as PolkaVMContextSolidityData;
pub use self::polkavm::context::vyper_data::VyperData as PolkaVMContextVyperData;
pub use self::polkavm::context::yul_data::YulData as PolkaVMContextYulData;
pub use self::polkavm::context::Context as PolkaVMContext;
pub use self::polkavm::evm::arithmetic as polkavm_evm_arithmetic;
@@ -8,13 +8,7 @@ pub enum AddressSpace {
Stack,
/// The heap memory.
Heap,
/// The auxiliary heap memory.
HeapAuxiliary,
/// The generic memory page.
Generic,
/// The code area.
Code,
/// The storage.
Storage,
/// The transient storage.
TransientStorage,
@@ -25,9 +19,6 @@ impl From<AddressSpace> for inkwell::AddressSpace {
match value {
AddressSpace::Stack => Self::from(0),
AddressSpace::Heap => Self::from(1),
AddressSpace::HeapAuxiliary => Self::from(2),
AddressSpace::Generic => Self::from(3),
AddressSpace::Code => Self::from(4),
AddressSpace::Storage => Self::from(5),
AddressSpace::TransientStorage => Self::from(6),
}
@@ -7,7 +7,6 @@ pub mod intrinsics;
pub mod llvm_runtime;
pub mod r#return;
pub mod runtime;
pub mod vyper_data;
pub mod yul_data;
use std::collections::HashMap;
@@ -20,8 +19,6 @@ use crate::polkavm::context::pointer::Pointer;
use self::declaration::Declaration;
use self::evmla_data::EVMLAData;
use self::r#return::Return;
use self::runtime::Runtime;
use self::vyper_data::VyperData;
use self::yul_data::YulData;
/// The LLVM IR generator function.
@@ -48,8 +45,6 @@ pub struct Function<'ctx> {
yul_data: Option<YulData>,
/// The EVM legacy assembly compiler data.
evmla_data: Option<EVMLAData<'ctx>>,
/// The Vyper data.
vyper_data: Option<VyperData>,
}
impl<'ctx> Function<'ctx> {
@@ -82,7 +77,6 @@ impl<'ctx> Function<'ctx> {
yul_data: None,
evmla_data: None,
vyper_data: None,
}
}
@@ -95,9 +89,9 @@ impl<'ctx> Function<'ctx> {
pub fn is_name_external(name: &str) -> bool {
name.starts_with("llvm.")
|| (name.starts_with("__")
&& name != Runtime::FUNCTION_ENTRY
&& name != Runtime::FUNCTION_DEPLOY_CODE
&& name != Runtime::FUNCTION_RUNTIME_CODE)
&& name != self::runtime::FUNCTION_ENTRY
&& name != self::runtime::FUNCTION_DEPLOY_CODE
&& name != self::runtime::FUNCTION_RUNTIME_CODE)
}
/// Checks whether the function is related to the near call ABI.
@@ -330,29 +324,6 @@ impl<'ctx> Function<'ctx> {
.expect("The EVM data must have been initialized")
}
/// Sets the Vyper data.
pub fn set_vyper_data(&mut self, data: VyperData) {
self.vyper_data = Some(data);
}
/// Returns the Vyper data reference.
/// # Panics
/// If the Vyper data has not been initialized.
pub fn vyper(&self) -> &VyperData {
self.vyper_data
.as_ref()
.expect("The Vyper data must have been initialized")
}
/// Returns the Vyper data mutable reference.
/// # Panics
/// If the Vyper data has not been initialized.
pub fn vyper_mut(&mut self) -> &mut VyperData {
self.vyper_data
.as_mut()
.expect("The Vyper data must have been initialized")
}
/// Sets the Yul data.
pub fn set_yul_data(&mut self, data: YulData) {
self.yul_data = Some(data);
@@ -2,10 +2,8 @@
use std::marker::PhantomData;
use crate::polkavm::context::address_space::AddressSpace;
use crate::polkavm::context::code_type::CodeType;
use crate::polkavm::context::function::runtime::Runtime;
use crate::polkavm::context::pointer::Pointer;
use crate::polkavm::context::function::runtime;
use crate::polkavm::context::Context;
use crate::polkavm::Dependency;
use crate::polkavm::WriteLLVM;
@@ -47,7 +45,7 @@ where
let function_type =
context.function_type::<inkwell::types::BasicTypeEnum>(vec![], 0, false);
context.add_function(
Runtime::FUNCTION_DEPLOY_CODE,
runtime::FUNCTION_DEPLOY_CODE,
function_type,
0,
Some(inkwell::module::Linkage::External),
@@ -57,26 +55,10 @@ where
}
fn into_llvm(self, context: &mut Context<D>) -> anyhow::Result<()> {
context.set_current_function(Runtime::FUNCTION_DEPLOY_CODE)?;
context.set_current_function(runtime::FUNCTION_DEPLOY_CODE)?;
context.set_basic_block(context.current_function().borrow().entry_block());
context.set_code_type(CodeType::Deploy);
if let Some(vyper) = context.vyper_data.as_ref() {
for index in 0..vyper.immutables_size() / revive_common::BYTE_LENGTH_WORD {
let offset = (crate::polkavm::r#const::HEAP_AUX_OFFSET_CONSTRUCTOR_RETURN_DATA
as usize)
+ (1 + index) * 2 * revive_common::BYTE_LENGTH_WORD;
let value = index * revive_common::BYTE_LENGTH_WORD;
let pointer = Pointer::new_with_offset(
context,
AddressSpace::HeapAuxiliary,
context.word_type(),
context.word_const(offset as u64),
"immutable_index_initializer",
);
context.build_store(pointer, context.word_const(value as u64))?;
}
}
self.inner.into_llvm(context)?;
match context
@@ -4,7 +4,7 @@ use inkwell::types::BasicType;
use inkwell::values::BasicValue;
use crate::polkavm::context::address_space::AddressSpace;
use crate::polkavm::context::function::runtime::Runtime;
use crate::polkavm::context::function::runtime;
use crate::polkavm::context::Context;
use crate::polkavm::r#const::*;
use crate::polkavm::Dependency;
@@ -53,7 +53,7 @@ impl Entry {
context.set_global(
crate::polkavm::GLOBAL_HEAP_MEMORY_POINTER,
context.llvm().ptr_type(AddressSpace::Generic.into()),
context.llvm().ptr_type(AddressSpace::Heap.into()),
AddressSpace::Stack,
context.xlen_type().get_undef(),
);
@@ -205,12 +205,12 @@ impl Entry {
let deploy_code = context
.functions
.get(Runtime::FUNCTION_DEPLOY_CODE)
.get(runtime::FUNCTION_DEPLOY_CODE)
.cloned()
.ok_or_else(|| anyhow::anyhow!("Contract deploy code not found"))?;
let runtime_code = context
.functions
.get(Runtime::FUNCTION_RUNTIME_CODE)
.get(runtime::FUNCTION_RUNTIME_CODE)
.cloned()
.ok_or_else(|| anyhow::anyhow!("Contract runtime code not found"))?;
@@ -233,7 +233,7 @@ where
fn declare(&mut self, context: &mut Context<D>) -> anyhow::Result<()> {
let entry_arguments = vec![context.bool_type().as_basic_type_enum()];
let entry_function_type = context.function_type(entry_arguments, 0, false);
context.add_function(Runtime::FUNCTION_ENTRY, entry_function_type, 0, None)?;
context.add_function(runtime::FUNCTION_ENTRY, entry_function_type, 0, None)?;
for symbol in runtime_api::exports::EXPORTS {
context.declare_extern_function(symbol)?;
@@ -247,7 +247,7 @@ where
/// The `entry` function loads calldata, sets globals and calls the runtime or deploy code.
fn into_llvm(self, context: &mut Context<D>) -> anyhow::Result<()> {
let entry = context
.get_function(Runtime::FUNCTION_ENTRY)
.get_function(runtime::FUNCTION_ENTRY)
.expect("the entry function should already be declared")
.borrow()
.declaration;
@@ -278,7 +278,7 @@ where
context.set_basic_block(context.current_function().borrow().return_block);
context.build_unreachable();
context.set_current_function(Runtime::FUNCTION_ENTRY)?;
context.set_current_function(runtime::FUNCTION_ENTRY)?;
context.set_basic_block(context.current_function().borrow().entry_block());
Self::initialize_globals(context)?;
@@ -4,28 +4,11 @@ pub mod deploy_code;
pub mod entry;
pub mod runtime_code;
use crate::polkavm::context::address_space::AddressSpace;
/// The main entry function name.
pub const FUNCTION_ENTRY: &str = "__entry";
/// The front-end runtime functions.
#[derive(Debug, Clone)]
pub struct Runtime {
/// The address space where the calldata is allocated.
/// Solidity uses the ordinary heap. Vyper uses the auxiliary heap.
_address_space: AddressSpace,
}
/// The deploy code function name.
pub const FUNCTION_DEPLOY_CODE: &str = "__deploy";
impl Runtime {
/// The main entry function name.
pub const FUNCTION_ENTRY: &'static str = "__entry";
/// The deploy code function name.
pub const FUNCTION_DEPLOY_CODE: &'static str = "__deploy";
/// The runtime code function name.
pub const FUNCTION_RUNTIME_CODE: &'static str = "__runtime";
/// A shortcut constructor.
pub fn new(_address_space: AddressSpace) -> Self {
Self { _address_space }
}
}
/// The runtime code function name.
pub const FUNCTION_RUNTIME_CODE: &str = "__runtime";
@@ -3,7 +3,7 @@
use std::marker::PhantomData;
use crate::polkavm::context::code_type::CodeType;
use crate::polkavm::context::function::runtime::Runtime;
use crate::polkavm::context::function::runtime;
use crate::polkavm::context::Context;
use crate::polkavm::Dependency;
use crate::polkavm::WriteLLVM;
@@ -45,7 +45,7 @@ where
let function_type =
context.function_type::<inkwell::types::BasicTypeEnum>(vec![], 0, false);
context.add_function(
Runtime::FUNCTION_RUNTIME_CODE,
runtime::FUNCTION_RUNTIME_CODE,
function_type,
0,
Some(inkwell::module::Linkage::External),
@@ -55,7 +55,7 @@ where
}
fn into_llvm(self, context: &mut Context<D>) -> anyhow::Result<()> {
context.set_current_function(Runtime::FUNCTION_RUNTIME_CODE)?;
context.set_current_function(runtime::FUNCTION_RUNTIME_CODE)?;
context.set_basic_block(context.current_function().borrow().entry_block());
context.set_code_type(CodeType::Runtime);
@@ -1,41 +0,0 @@
//! The LLVM function Vyper data.
use std::collections::HashMap;
/// The LLVM function Vyper data.
/// Describes some data that is only relevant to Vyper.
#[derive(Debug)]
pub struct VyperData {
/// The block-local variables. They are still allocated at the beginning of the function,
/// but their parent block must be known in order to pass the implicit arguments thereto.
/// Is only used by the Vyper LLL IR compiler.
label_arguments: HashMap<String, Vec<String>>,
}
impl Default for VyperData {
fn default() -> Self {
Self {
label_arguments: HashMap::with_capacity(Self::LABEL_ARGUMENTS_HASHMAP_INITIAL_CAPACITY),
}
}
}
impl VyperData {
/// The label arguments hashmap default capacity.
const LABEL_ARGUMENTS_HASHMAP_INITIAL_CAPACITY: usize = 16;
/// A shortcut constructor.
pub fn new() -> Self {
Self::default()
}
/// Returns the list of a Vyper label arguments.
pub fn label_arguments(&self, label_name: &str) -> Option<Vec<String>> {
self.label_arguments.get(label_name).cloned()
}
/// Inserts arguments for the specified label.
pub fn insert_label_arguments(&mut self, label_name: String, arguments: Vec<String>) {
self.label_arguments.insert(label_name, arguments);
}
}
@@ -42,9 +42,6 @@ impl<'ctx> Global<'ctx> {
.value
.set_visibility(inkwell::GlobalVisibility::Default);
global.value.set_externally_initialized(false);
if let AddressSpace::Code = address_space {
global.value.set_constant(true);
}
if !r#type.is_pointer_type() {
global.value.set_initializer(&initializer);
} else {
@@ -12,7 +12,6 @@ pub mod global;
pub mod r#loop;
pub mod pointer;
pub mod solidity_data;
pub mod vyper_data;
pub mod yul_data;
#[cfg(test)]
@@ -37,7 +36,6 @@ use self::address_space::AddressSpace;
use self::attribute::Attribute;
use self::build::Build;
use self::code_type::CodeType;
// TODO
// use self::debug_info::DebugInfo;
use self::evmla_data::EVMLAData;
use self::function::declaration::Declaration as FunctionDeclaration;
@@ -49,7 +47,6 @@ use self::global::Global;
use self::pointer::Pointer;
use self::r#loop::Loop;
use self::solidity_data::SolidityData;
use self::vyper_data::VyperData;
use self::yul_data::YulData;
/// The LLVM IR generator context.
@@ -99,8 +96,6 @@ where
yul_data: Option<YulData>,
/// The EVM legacy assembly data.
evmla_data: Option<EVMLAData<'ctx>>,
/// The Vyper data.
vyper_data: Option<VyperData>,
}
impl<'ctx, D> Context<'ctx, D>
@@ -224,7 +219,6 @@ where
solidity_data: None,
yul_data: None,
evmla_data: None,
vyper_data: None,
}
}
@@ -522,9 +516,6 @@ where
/// Compiles a contract dependency, if the dependency manager is set.
pub fn compile_dependency(&mut self, name: &str) -> anyhow::Result<String> {
if let Some(vyper_data) = self.vyper_data.as_mut() {
vyper_data.set_is_forwarder_used();
}
self.dependency_manager
.to_owned()
.ok_or_else(|| anyhow::anyhow!("The dependency manager is unset"))
@@ -717,11 +708,6 @@ where
self.build_load(storage_value_pointer, "storage_value_load")
}
AddressSpace::Code | AddressSpace::HeapAuxiliary => todo!(),
AddressSpace::Generic => Ok(self.build_byte_swap(self.build_load(
pointer.address_space_cast(self, AddressSpace::Stack, &format!("{}_cast", name))?,
name,
)?)?),
AddressSpace::Stack => {
let value = self
.builder()
@@ -813,11 +799,6 @@ where
],
);
}
AddressSpace::Code | AddressSpace::HeapAuxiliary => {}
AddressSpace::Generic => self.build_store(
pointer.address_space_cast(self, AddressSpace::Stack, "cast")?,
self.build_byte_swap(value.as_basic_value_enum())?,
)?,
AddressSpace::Stack => {
let instruction = self.builder.build_store(pointer.value, value).unwrap();
instruction
@@ -1185,49 +1166,6 @@ where
))
}
/// Writes the ABI pointer to the global variable.
pub fn write_abi_pointer(&mut self, pointer: Pointer<'ctx>, global_name: &str) {
self.set_global(
global_name,
self.llvm().ptr_type(AddressSpace::Generic.into()),
AddressSpace::Stack,
pointer.value,
);
}
/// Writes the ABI data size to the global variable.
pub fn write_abi_data_size(&mut self, _pointer: Pointer<'ctx>, _global_name: &str) {
/*
let abi_pointer_value = self
.builder()
.build_ptr_to_int(pointer.value, self.field_type(), "abi_pointer_value")
.unwrap();
let abi_pointer_value_shifted = self
.builder()
.build_right_shift(
abi_pointer_value,
self.field_const((revive_common::BIT_LENGTH_X32 * 3) as u64),
false,
"abi_pointer_value_shifted",
)
.unwrap();
let abi_length_value = self
.builder()
.build_and(
abi_pointer_value_shifted,
self.field_const(u32::MAX as u64),
"abi_length_value",
)
.unwrap();
self.set_global(
global_name,
self.field_type(),
AddressSpace::Stack,
abi_length_value,
);
*/
}
/// Returns a boolean type constant.
pub fn bool_const(&self, value: bool) -> inkwell::values::IntValue<'ctx> {
self.bool_type().const_int(u64::from(value), false)
@@ -1537,28 +1475,12 @@ where
.expect("The EVMLA data must have been initialized")
}
/// Sets the EVM legacy assembly data.
pub fn set_vyper_data(&mut self, data: VyperData) {
self.vyper_data = Some(data);
}
/// Returns the Vyper data reference.
/// # Panics
/// If the Vyper data has not been initialized.
pub fn vyper(&self) -> &VyperData {
self.vyper_data
.as_ref()
.expect("The Solidity data must have been initialized")
}
/// Returns the current number of immutables values in the contract.
/// If the size is set manually, then it is returned. Otherwise, the number of elements in
/// the identifier-to-offset mapping tree is returned.
pub fn immutables_size(&self) -> anyhow::Result<usize> {
if let Some(solidity) = self.solidity_data.as_ref() {
Ok(solidity.immutables_size())
} else if let Some(vyper) = self.vyper_data.as_ref() {
Ok(vyper.immutables_size())
} else {
anyhow::bail!("The immutable size data is not available");
}
@@ -1,37 +0,0 @@
//! The LLVM IR generator Vyper data.
/// The LLVM IR generator Vyper data.
/// Describes some data that is only relevant to Vyper.
#[derive(Debug)]
pub struct VyperData {
/// The immutables size tracker. Stores the size in bytes.
/// Does not take into account the size of the indexes.
immutables_size: usize,
/// Whether the contract forwarder has been used.
is_forwarder_used: bool,
}
impl VyperData {
/// A shortcut constructor.
pub fn new(immutables_size: usize, is_forwarder_used: bool) -> Self {
Self {
immutables_size,
is_forwarder_used,
}
}
/// Returns the size of the immutables data of the contract.
pub fn immutables_size(&self) -> usize {
self.immutables_size
}
/// Sets the forwarder usage flag.
pub fn set_is_forwarder_used(&mut self) {
self.is_forwarder_used = true;
}
/// Returns the forwarder usage flag.
pub fn is_forwarder_used(&self) -> bool {
self.is_forwarder_used
}
}
@@ -36,7 +36,7 @@ where
)?;
let immutable_pointer = Pointer::new_with_offset(
context,
AddressSpace::HeapAuxiliary,
AddressSpace::default(),
context.word_type(),
offset_absolute,
"immutable_pointer",
@@ -81,7 +81,7 @@ where
)?;
let index_offset_pointer = Pointer::new_with_offset(
context,
AddressSpace::HeapAuxiliary,
AddressSpace::default(),
context.word_type(),
index_offset_absolute,
"immutable_index_pointer",
@@ -95,7 +95,7 @@ where
)?;
let value_offset_pointer = Pointer::new_with_offset(
context,
AddressSpace::HeapAuxiliary,
AddressSpace::default(),
context.word_type(),
value_offset_absolute,
"immutable_value_pointer",
-140
View File
@@ -1,8 +1,5 @@
//! Some LLVM IR generator utilies.
use inkwell::values::BasicValue;
use crate::polkavm::context::address_space::AddressSpace;
use crate::polkavm::context::Context;
use crate::polkavm::Dependency;
@@ -39,143 +36,6 @@ where
Ok(result.into_int_value())
}
/// Returns the full list of arguments for an external call.
/// Performs the extra ABI data padding and adds the mimic call extra argument.
pub fn external_call_arguments<'ctx, D>(
_context: &Context<'ctx, D>,
abi_data: inkwell::values::BasicValueEnum<'ctx>,
address: inkwell::values::IntValue<'ctx>,
_extra_abi_data: Vec<inkwell::values::IntValue<'ctx>>,
mimic: Option<inkwell::values::IntValue<'ctx>>,
) -> Vec<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let mut result = Vec::with_capacity(
crate::polkavm::context::function::runtime::entry::Entry::MANDATORY_ARGUMENTS_COUNT
+ crate::polkavm::EXTRA_ABI_DATA_SIZE
+ usize::from(mimic.is_some()),
);
result.push(abi_data);
result.push(address.as_basic_value_enum());
//result.extend(
// pad_extra_abi_data(context, extra_abi_data)
// .into_iter()
// .map(|value| value.as_basic_value_enum()),
//);
if let Some(mimic) = mimic {
result.push(mimic.as_basic_value_enum());
}
result
}
/// Generates an ABI data for an external call.
/// If `gas` is `None`, it is fetched from the contract context.
pub fn abi_data<'ctx, D>(
context: &mut Context<'ctx, D>,
input_offset: inkwell::values::IntValue<'ctx>,
input_length: inkwell::values::IntValue<'ctx>,
gas: Option<inkwell::values::IntValue<'ctx>>,
address_space: AddressSpace,
is_system_call: bool,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let input_offset = crate::polkavm::utils::clamp(
context,
input_offset,
context.word_const(u32::MAX as u64),
"abi_data_input_offset",
)?;
let input_length = crate::polkavm::utils::clamp(
context,
input_length,
context.word_const(u32::MAX as u64),
"abi_data_input_length",
)?;
let gas = match gas {
Some(gas) => gas,
None => crate::polkavm::evm::ether_gas::gas(context)?.into_int_value(),
};
let gas = crate::polkavm::utils::clamp(
context,
gas,
context.word_const(u32::MAX as u64),
"abi_data_gas",
)?;
let input_offset_shifted = context.builder().build_left_shift(
input_offset,
context.word_const((revive_common::BIT_LENGTH_X32 * 2) as u64),
"abi_data_input_offset_shifted",
)?;
let input_length_shifted = context.builder().build_left_shift(
input_length,
context.word_const((revive_common::BIT_LENGTH_X32 * 3) as u64),
"abi_data_input_length_shifted",
)?;
let gas_shifted = context.builder().build_left_shift(
gas,
context.word_const((revive_common::BIT_LENGTH_X32 * 6) as u64),
"abi_data_gas_shifted",
)?;
let mut abi_data = context.builder().build_int_add(
input_offset_shifted,
input_length_shifted,
"abi_data_offset_and_length",
)?;
abi_data = context
.builder()
.build_int_add(abi_data, gas_shifted, "abi_data_add_gas")?;
if let AddressSpace::HeapAuxiliary = address_space {
let auxiliary_heap_marker_shifted = context.builder().build_left_shift(
context.word_const(zkevm_opcode_defs::FarCallForwardPageType::UseAuxHeap as u64),
context.word_const((revive_common::BIT_LENGTH_X32 * 7) as u64),
"abi_data_auxiliary_heap_marker_shifted",
)?;
abi_data = context.builder().build_int_add(
abi_data,
auxiliary_heap_marker_shifted,
"abi_data_add_heap_auxiliary_marker",
)?;
}
if is_system_call {
let auxiliary_heap_marker_shifted = context.builder().build_left_shift(
context.word_const(zkevm_opcode_defs::FarCallForwardPageType::UseAuxHeap as u64),
context.word_const(
((revive_common::BIT_LENGTH_X32 * 7) + (revive_common::BIT_LENGTH_BYTE * 3)) as u64,
),
"abi_data_system_call_marker_shifted",
)?;
abi_data = context.builder().build_int_add(
abi_data,
auxiliary_heap_marker_shifted,
"abi_data_add_system_call_marker",
)?;
}
Ok(abi_data.as_basic_value_enum())
}
/// Pads the extra ABI data with `i256::undef`, so it always consists of 10 values.
pub fn pad_extra_abi_data<'ctx, D>(
context: &Context<'ctx, D>,
initial_data: Vec<inkwell::values::IntValue<'ctx>>,
) -> [inkwell::values::IntValue<'ctx>; crate::polkavm::EXTRA_ABI_DATA_SIZE]
where
D: Dependency + Clone,
{
let mut padded_data = initial_data;
padded_data.extend(vec![
context.word_undef();
crate::polkavm::EXTRA_ABI_DATA_SIZE - padded_data.len()
]);
padded_data.try_into().expect("Always valid")
}
/// Computes the `keccak256` hash for `preimage`.
pub fn keccak256(preimage: &[u8]) -> String {
use sha3::Digest;