remove zkEVM extensions

Signed-off-by: xermicus <cyrill@parity.io>
This commit is contained in:
xermicus
2024-04-15 15:22:23 +02:00
parent 3f9a90fe79
commit 7aa27516e4
19 changed files with 99 additions and 2959 deletions
-3
View File
@@ -5,9 +5,6 @@
/// The corresponding simulation predefined address.
pub const ERAVM_ADDRESS_TO_L1: u16 = 0xFFFF;
/// The corresponding simulation predefined address.
pub const ERAVM_ADDRESS_CODE_ADDRESS: u16 = 0xFFFE;
/// The corresponding simulation predefined address.
pub const ERAVM_ADDRESS_PRECOMPILE: u16 = 0xFFFD;
-640
View File
@@ -4,11 +4,8 @@
use inkwell::values::BasicValue;
use crate::eravm::context::address_space::AddressSpace;
use crate::eravm::context::argument::Argument;
use crate::eravm::context::function::declaration::Declaration as FunctionDeclaration;
use crate::eravm::context::function::runtime::Runtime;
use crate::eravm::context::pointer::Pointer;
use crate::eravm::context::Context;
use crate::eravm::Dependency;
@@ -37,476 +34,6 @@ where
todo!();
/*
if context.is_system_mode() {
let simulation_address = constants
.get_mut(1)
.and_then(|option| option.take())
.and_then(|value| value.to_u16());
match simulation_address {
Some(revive_common::ERAVM_ADDRESS_TO_L1) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().far_call,
function,
"to_l1",
)?;
let is_first = gas;
let in_0 = value.expect("Always exists");
let in_1 = input_offset;
return crate::eravm::extensions::general::to_l1(context, is_first, in_0, in_1);
}
Some(revive_common::ERAVM_ADDRESS_CODE_ADDRESS) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"code_address",
)?;
return crate::eravm::extensions::general::code_source(context);
}
Some(revive_common::ERAVM_ADDRESS_PRECOMPILE) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"precompile",
)?;
let in_0 = gas;
let gas_left = input_offset;
return crate::eravm::extensions::general::precompile(context, in_0, gas_left);
}
Some(revive_common::ERAVM_ADDRESS_META) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"meta",
)?;
return crate::eravm::extensions::general::meta(context);
}
Some(revive_common::ERAVM_ADDRESS_MIMIC_CALL) => {
let address = gas;
let abi_data = input_offset;
let mimic = input_length;
return crate::eravm::extensions::call::mimic(
context,
context.llvm_runtime().mimic_call,
address,
mimic,
abi_data.as_basic_value_enum(),
vec![],
);
}
Some(revive_common::ERAVM_ADDRESS_SYSTEM_MIMIC_CALL) => {
let address = gas;
let abi_data = input_offset;
let mimic = input_length;
let extra_value_1 = output_offset;
let extra_value_2 = output_length;
return crate::eravm::extensions::call::mimic(
context,
context.llvm_runtime().mimic_call,
address,
mimic,
abi_data.as_basic_value_enum(),
vec![extra_value_1, extra_value_2],
);
}
Some(revive_common::ERAVM_ADDRESS_MIMIC_CALL_BYREF) => {
let address = gas;
let mimic = input_length;
let abi_data = context.get_global_value(crate::eravm::GLOBAL_ACTIVE_POINTER)?;
return crate::eravm::extensions::call::mimic(
context,
context.llvm_runtime().mimic_call_byref,
address,
mimic,
abi_data.as_basic_value_enum(),
vec![],
);
}
Some(revive_common::ERAVM_ADDRESS_SYSTEM_MIMIC_CALL_BYREF) => {
let address = gas;
let mimic = input_length;
let abi_data = context.get_global_value(crate::eravm::GLOBAL_ACTIVE_POINTER)?;
let extra_value_1 = output_offset;
let extra_value_2 = output_length;
return crate::eravm::extensions::call::mimic(
context,
context.llvm_runtime().mimic_call_byref,
address,
mimic,
abi_data,
vec![extra_value_1, extra_value_2],
);
}
Some(revive_common::ERAVM_ADDRESS_RAW_FAR_CALL) => {
let address = gas;
let abi_data = input_length;
return crate::eravm::extensions::call::raw_far(
context,
context.llvm_runtime().modify(function, false)?,
address,
abi_data.as_basic_value_enum(),
output_offset,
output_length,
);
}
Some(revive_common::ERAVM_ADDRESS_RAW_FAR_CALL_BYREF) => {
let address = gas;
let abi_data = context.get_global_value(crate::eravm::GLOBAL_ACTIVE_POINTER)?;
return crate::eravm::extensions::call::raw_far(
context,
context.llvm_runtime().modify(function, true)?,
address,
abi_data,
output_offset,
output_length,
);
}
Some(revive_common::ERAVM_ADDRESS_SYSTEM_CALL) => {
let address = gas;
let abi_data = input_length;
let extra_value_1 = value.expect("Always exists");
let extra_value_2 = input_offset;
let extra_value_3 = output_offset;
let extra_value_4 = output_length;
return crate::eravm::extensions::call::system(
context,
context.llvm_runtime().modify(function, false)?,
address,
abi_data.as_basic_value_enum(),
context.field_const(0),
context.field_const(0),
vec![extra_value_1, extra_value_2, extra_value_3, extra_value_4],
);
}
Some(revive_common::ERAVM_ADDRESS_SYSTEM_CALL_BYREF) => {
let address = gas;
let abi_data = context.get_global_value(crate::eravm::GLOBAL_ACTIVE_POINTER)?;
let extra_value_1 = value.expect("Always exists");
let extra_value_2 = input_offset;
let extra_value_3 = output_offset;
let extra_value_4 = output_length;
return crate::eravm::extensions::call::system(
context,
context.llvm_runtime().modify(function, true)?,
address,
abi_data,
context.field_const(0),
context.field_const(0),
vec![extra_value_1, extra_value_2, extra_value_3, extra_value_4],
);
}
Some(revive_common::ERAVM_ADDRESS_SET_CONTEXT_VALUE_CALL) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().far_call,
function,
"set_context_value",
)?;
let value = value.expect("Always exists");
return crate::eravm::extensions::general::set_context_value(context, value);
}
Some(revive_common::ERAVM_ADDRESS_SET_PUBDATA_PRICE) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().far_call,
function,
"set_pubdata_price",
)?;
let price = gas;
return crate::eravm::extensions::general::set_pubdata_price(context, price);
}
Some(revive_common::ERAVM_ADDRESS_INCREMENT_TX_COUNTER) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().far_call,
function,
"increment_tx_counter",
)?;
return crate::eravm::extensions::general::increment_tx_counter(context);
}
Some(revive_common::ERAVM_ADDRESS_GET_GLOBAL_PTR_CALLDATA) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"get_global_ptr_calldata",
)?;
let pointer = context.get_global_value(crate::eravm::GLOBAL_CALLDATA_POINTER)?;
let value = context.builder().build_ptr_to_int(
pointer.into_pointer_value(),
context.field_type(),
"calldata_abi_integer",
)?;
return Ok(value.as_basic_value_enum());
}
Some(revive_common::ERAVM_ADDRESS_GET_GLOBAL_CALL_FLAGS) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"get_global_call_flags",
)?;
return context.get_global_value(crate::eravm::GLOBAL_CALL_FLAGS);
}
Some(revive_common::ERAVM_ADDRESS_GET_GLOBAL_PTR_RETURN_DATA) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"get_global_ptr_return_data",
)?;
let pointer = context.get_global_value(crate::eravm::GLOBAL_RETURN_DATA_POINTER)?;
let value = context.builder().build_ptr_to_int(
pointer.into_pointer_value(),
context.field_type(),
"return_data_abi_integer",
)?;
return Ok(value.as_basic_value_enum());
}
Some(revive_common::ERAVM_ADDRESS_EVENT_INITIALIZE) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().far_call,
function,
"event_initialize",
)?;
let operand_1 = gas;
let operand_2 = value.expect("Always exists");
return crate::eravm::extensions::general::event(
context, operand_1, operand_2, true,
);
}
Some(revive_common::ERAVM_ADDRESS_EVENT_WRITE) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().far_call,
function,
"event_initialize",
)?;
let operand_1 = gas;
let operand_2 = value.expect("Always exists");
return crate::eravm::extensions::general::event(
context, operand_1, operand_2, false,
);
}
Some(revive_common::ERAVM_ADDRESS_ACTIVE_PTR_LOAD_CALLDATA) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"active_ptr_load_calldata",
)?;
return crate::eravm::extensions::abi::calldata_ptr_to_active(context);
}
Some(revive_common::ERAVM_ADDRESS_ACTIVE_PTR_LOAD_RETURN_DATA) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"active_ptr_load_return_data",
)?;
return crate::eravm::extensions::abi::return_data_ptr_to_active(context);
}
Some(revive_common::ERAVM_ADDRESS_ACTIVE_PTR_ADD) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"active_ptr_add",
)?;
let offset = gas;
return crate::eravm::extensions::abi::active_ptr_add_assign(context, offset);
}
Some(revive_common::ERAVM_ADDRESS_ACTIVE_PTR_SHRINK) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"active_ptr_shrink",
)?;
let offset = gas;
return crate::eravm::extensions::abi::active_ptr_shrink_assign(context, offset);
}
Some(revive_common::ERAVM_ADDRESS_ACTIVE_PTR_PACK) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"active_ptr_pack",
)?;
let data = gas;
return crate::eravm::extensions::abi::active_ptr_pack_assign(context, data);
}
Some(revive_common::ERAVM_ADDRESS_MULTIPLICATION_HIGH_REGISTER) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"multiplication_high_register",
)?;
let operand_1 = gas;
let operand_2 = input_offset;
return crate::eravm::extensions::math::multiplication_512(
context, operand_1, operand_2,
);
}
Some(revive_common::ERAVM_ADDRESS_GET_GLOBAL_EXTRA_ABI_DATA) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"get_global_extra_abi_data",
)?;
let index = gas;
return crate::eravm::extensions::abi::get_extra_abi_data(context, index);
}
Some(revive_common::ERAVM_ADDRESS_ACTIVE_PTR_DATA_LOAD) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"active_ptr_data_load",
)?;
let offset = gas;
return crate::eravm::extensions::abi::active_ptr_data_load(context, offset);
}
Some(revive_common::ERAVM_ADDRESS_ACTIVE_PTR_DATA_SIZE) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"active_ptr_data_size",
)?;
return crate::eravm::extensions::abi::active_ptr_data_size(context);
}
Some(revive_common::ERAVM_ADDRESS_ACTIVE_PTR_DATA_COPY) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"active_ptr_data_copy",
)?;
let destination_offset = gas;
let source_offset = input_offset;
let size = input_length;
return crate::eravm::extensions::abi::active_ptr_data_copy(
context,
destination_offset,
source_offset,
size,
);
}
Some(revive_common::ERAVM_ADDRESS_CONST_ARRAY_DECLARE) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"const_array_declare",
)?;
let index = constants
.get_mut(0)
.and_then(|option| option.take())
.ok_or_else(|| anyhow::anyhow!("Const array index is missing"))?
.to_u8()
.ok_or_else(|| anyhow::anyhow!("Const array index must fit into 8 bits"))?;
let size = constants
.get_mut(2)
.and_then(|option| option.take())
.ok_or_else(|| anyhow::anyhow!("Const array size is missing"))?
.to_u16()
.ok_or_else(|| anyhow::anyhow!("Const array size must fit into 16 bits"))?;
return crate::eravm::extensions::const_array::declare(context, index, size);
}
Some(revive_common::ERAVM_ADDRESS_CONST_ARRAY_SET) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"const_array_set",
)?;
let index = constants
.get_mut(0)
.and_then(|option| option.take())
.ok_or_else(|| anyhow::anyhow!("Const array index is missing"))?
.to_u8()
.ok_or_else(|| anyhow::anyhow!("Const array index must fit into 8 bits"))?;
let offset = constants
.get_mut(2)
.and_then(|option| option.take())
.ok_or_else(|| anyhow::anyhow!("Const array offset is missing"))?
.to_u16()
.ok_or_else(|| anyhow::anyhow!("Const array offset must fit into 16 bits"))?;
let value = constants
.get_mut(4)
.and_then(|option| option.take())
.ok_or_else(|| anyhow::anyhow!("Const array assigned value is missing"))?;
return crate::eravm::extensions::const_array::set(context, index, offset, value);
}
Some(revive_common::ERAVM_ADDRESS_CONST_ARRAY_FINALIZE) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"const_array_finalize",
)?;
let index = constants
.get_mut(0)
.and_then(|option| option.take())
.ok_or_else(|| anyhow::anyhow!("Const array index is missing"))?
.to_u8()
.ok_or_else(|| anyhow::anyhow!("Const array index must fit into 8 bits"))?;
return crate::eravm::extensions::const_array::finalize(context, index);
}
Some(revive_common::ERAVM_ADDRESS_CONST_ARRAY_GET) => {
crate::eravm::extensions::call::validate_call_type(
context.llvm_runtime().static_call,
function,
"const_array_get",
)?;
let index = constants
.get_mut(0)
.and_then(|option| option.take())
.ok_or_else(|| anyhow::anyhow!("Const array index is missing"))?
.to_u8()
.ok_or_else(|| anyhow::anyhow!("Const array index must fit into 8 bits"))?;
let offset = input_offset;
return crate::eravm::extensions::const_array::get(context, index, offset);
}
_ => {}
}
}
let identity_block = context.append_basic_block("contract_call_identity_block");
let ordinary_block = context.append_basic_block("contract_call_ordinary_block");
let join_block = context.append_basic_block("contract_call_join_block");
@@ -587,170 +114,3 @@ where
.resolve_library(path.as_str())?
.as_basic_value_enum())
}
///
/// Generates a custom request to a system contract.
///
pub fn request<'ctx, D>(
context: &mut Context<'ctx, D>,
address: inkwell::values::IntValue<'ctx>,
signature: &'static str,
arguments: Vec<inkwell::values::IntValue<'ctx>>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let signature_hash = crate::eravm::utils::keccak256(signature.as_bytes());
let signature_value = context.field_const_str_hex(signature_hash.as_str());
let calldata_size = context.field_const(
(revive_common::BYTE_LENGTH_X32 + (revive_common::BYTE_LENGTH_FIELD * arguments.len()))
as u64,
);
let calldata_array_pointer = context.build_alloca(
context.array_type(context.field_type(), arguments.len()),
"system_request_calldata_array_pointer",
);
for (index, argument) in arguments.into_iter().enumerate() {
let argument_pointer = context.build_gep(
calldata_array_pointer,
&[context.field_const(0), context.field_const(index as u64)],
context.field_type(),
"system_request_calldata_array_pointer",
);
context.build_store(argument_pointer, argument)?;
}
Ok(context
.build_invoke(
context.llvm_runtime().system_request,
&[
address.as_basic_value_enum(),
signature_value.as_basic_value_enum(),
calldata_size.as_basic_value_enum(),
calldata_array_pointer.value.as_basic_value_enum(),
],
"system_request_call",
)
.expect("Always exists"))
}
///
/// The default call wrapper, which redirects the call to the `msg.value` simulator if `msg.value`
/// is not zero.
///
#[allow(clippy::too_many_arguments)]
fn _default_wrapped<'ctx, D>(
context: &mut Context<'ctx, D>,
function: FunctionDeclaration<'ctx>,
gas: inkwell::values::IntValue<'ctx>,
value: inkwell::values::IntValue<'ctx>,
address: inkwell::values::IntValue<'ctx>,
input_offset: inkwell::values::IntValue<'ctx>,
input_length: inkwell::values::IntValue<'ctx>,
output_offset: inkwell::values::IntValue<'ctx>,
output_length: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let value_zero_block = context.append_basic_block("contract_call_value_zero_block");
let value_non_zero_block = context.append_basic_block("contract_call_value_non_zero_block");
let value_join_block = context.append_basic_block("contract_call_value_join_block");
let result_pointer =
context.build_alloca(context.field_type(), "contract_call_address_result_pointer");
context.build_store(result_pointer, context.field_const(0))?;
let is_value_zero = context.builder().build_int_compare(
inkwell::IntPredicate::EQ,
value,
context.field_const(0),
"contract_call_is_value_zero",
)?;
context.build_conditional_branch(is_value_zero, value_zero_block, value_non_zero_block)?;
context.set_basic_block(value_non_zero_block);
let abi_data = crate::eravm::utils::abi_data(
context,
input_offset,
input_length,
Some(gas),
AddressSpace::Heap,
true,
)?;
let result = crate::eravm::extensions::call::system(
context,
context.llvm_runtime().modify(function, false)?,
context.field_const(zkevm_opcode_defs::ADDRESS_MSG_VALUE.into()),
abi_data,
output_offset,
output_length,
vec![
value,
address,
context.field_const(u64::from(crate::eravm::r#const::NO_SYSTEM_CALL_BIT)),
],
)?;
context.build_store(result_pointer, result)?;
context.build_unconditional_branch(value_join_block);
context.set_basic_block(value_zero_block);
let function = Runtime::default_call(context, function);
let result = context
.build_call(
function,
&[
gas.as_basic_value_enum(),
address.as_basic_value_enum(),
input_offset.as_basic_value_enum(),
input_length.as_basic_value_enum(),
output_offset.as_basic_value_enum(),
output_length.as_basic_value_enum(),
],
"default_call",
)
.expect("Always exists");
context.build_store(result_pointer, result)?;
context.build_unconditional_branch(value_join_block);
context.set_basic_block(value_join_block);
context.build_load(result_pointer, "contract_call_address_result")
}
///
/// Generates a memory copy loop repeating the behavior of the EVM `Identity` precompile.
///
fn _identity<'ctx, D>(
context: &mut Context<'ctx, D>,
destination: inkwell::values::IntValue<'ctx>,
source: inkwell::values::IntValue<'ctx>,
size: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let destination = Pointer::new_with_offset(
context,
AddressSpace::Heap,
context.byte_type(),
destination,
"contract_call_identity_destination",
);
let source = Pointer::new_with_offset(
context,
AddressSpace::Heap,
context.byte_type(),
source,
"contract_call_identity_source",
);
context.build_memcpy(
context.intrinsics().memory_copy,
destination,
source,
size,
"contract_call_memcpy_to_child",
)?;
Ok(context.field_const(1).as_basic_value_enum())
}
+21 -71
View File
@@ -11,171 +11,121 @@ use crate::eravm::Dependency;
/// Translates the `gas_limit` instruction.
///
pub fn gas_limit<'ctx, D>(
context: &mut Context<'ctx, D>,
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_SYSTEM_CONTEXT.into()),
"blockGasLimit()",
vec![],
)
todo!()
}
///
/// Translates the `gas_price` instruction.
///
pub fn gas_price<'ctx, D>(
context: &mut Context<'ctx, D>,
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_SYSTEM_CONTEXT.into()),
"gasPrice()",
vec![],
)
todo!()
}
///
/// Translates the `tx.origin` instruction.
///
pub fn origin<'ctx, D>(
context: &mut Context<'ctx, D>,
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_SYSTEM_CONTEXT.into()),
"origin()",
vec![],
)
todo!()
}
///
/// Translates the `chain_id` instruction.
///
pub fn chain_id<'ctx, D>(
context: &mut Context<'ctx, D>,
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_SYSTEM_CONTEXT.into()),
"chainId()",
vec![],
)
todo!()
}
///
/// Translates the `block_number` instruction.
///
pub fn block_number<'ctx, D>(
context: &mut Context<'ctx, D>,
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_SYSTEM_CONTEXT.into()),
"getBlockNumber()",
vec![],
)
todo!()
}
///
/// Translates the `block_timestamp` instruction.
///
pub fn block_timestamp<'ctx, D>(
context: &mut Context<'ctx, D>,
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_SYSTEM_CONTEXT.into()),
"getBlockTimestamp()",
vec![],
)
todo!()
}
///
/// Translates the `block_hash` instruction.
///
pub fn block_hash<'ctx, D>(
context: &mut Context<'ctx, D>,
index: inkwell::values::IntValue<'ctx>,
_context: &mut Context<'ctx, D>,
_index: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_SYSTEM_CONTEXT.into()),
"getBlockHashEVM(uint256)",
vec![index],
)
todo!()
}
///
/// Translates the `difficulty` instruction.
///
pub fn difficulty<'ctx, D>(
context: &mut Context<'ctx, D>,
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_SYSTEM_CONTEXT.into()),
"difficulty()",
vec![],
)
todo!()
}
///
/// Translates the `coinbase` instruction.
///
pub fn coinbase<'ctx, D>(
context: &mut Context<'ctx, D>,
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_SYSTEM_CONTEXT.into()),
"coinbase()",
vec![],
)
todo!()
}
///
/// Translates the `basefee` instruction.
///
pub fn basefee<'ctx, D>(
context: &mut Context<'ctx, D>,
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_SYSTEM_CONTEXT.into()),
"baseFee()",
vec![],
)
todo!()
}
///
@@ -35,16 +35,11 @@ where
/// Translates the `balance` instructions.
///
pub fn balance<'ctx, D>(
context: &mut Context<'ctx, D>,
address: inkwell::values::IntValue<'ctx>,
_context: &mut Context<'ctx, D>,
_address: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_ETH_TOKEN.into()),
"balanceOf(uint256)",
vec![address],
)
todo!()
}
+6 -16
View File
@@ -9,34 +9,24 @@ use crate::eravm::Dependency;
/// Translates the `extcodesize` instruction.
///
pub fn size<'ctx, D>(
context: &mut Context<'ctx, D>,
address: inkwell::values::IntValue<'ctx>,
_context: &mut Context<'ctx, D>,
_address: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_ACCOUNT_CODE_STORAGE.into()),
"getCodeSize(uint256)",
vec![address],
)
todo!()
}
///
/// Translates the `extcodehash` instruction.
///
pub fn hash<'ctx, D>(
context: &mut Context<'ctx, D>,
address: inkwell::values::IntValue<'ctx>,
_context: &mut Context<'ctx, D>,
_address: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
crate::eravm::evm::call::request(
context,
context.field_const(zkevm_opcode_defs::ADDRESS_ACCOUNT_CODE_STORAGE.into()),
"getCodeHash(uint256)",
vec![address],
)
todo!()
}
@@ -1,225 +0,0 @@
//!
//! Translates the ABI instructions of the EraVM Yul extension.
//!
use inkwell::types::BasicType;
use inkwell::values::BasicValue;
use crate::eravm::context::address_space::AddressSpace;
use crate::eravm::context::pointer::Pointer;
use crate::eravm::context::Context;
use crate::eravm::Dependency;
///
/// Generates an extra ABI data getter call.
///
pub fn get_extra_abi_data<'ctx, D>(
context: &mut Context<'ctx, D>,
index: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let extra_active_data_global = context.get_global(crate::eravm::GLOBAL_EXTRA_ABI_DATA)?;
let extra_active_data_pointer = extra_active_data_global.into();
let extra_active_data_element_pointer = context.build_gep(
extra_active_data_pointer,
&[context.field_const(0), index],
context.field_type().as_basic_type_enum(),
"extra_active_data_element_pointer",
);
context.build_load(
extra_active_data_element_pointer,
"extra_active_data_element_value",
)
}
///
/// Loads the calldata pointer to the active pointer.
///
pub fn calldata_ptr_to_active<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let calldata_pointer = context.get_global_value(crate::eravm::GLOBAL_CALLDATA_POINTER)?;
context.set_global(
crate::eravm::GLOBAL_ACTIVE_POINTER,
context.byte_type().ptr_type(AddressSpace::Generic.into()),
AddressSpace::Stack,
calldata_pointer,
);
Ok(context.field_const(1).as_basic_value_enum())
}
///
/// Loads the return data pointer to the active pointer.
///
pub fn return_data_ptr_to_active<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let calldata_pointer = context.get_global_value(crate::eravm::GLOBAL_RETURN_DATA_POINTER)?;
context.set_global(
crate::eravm::GLOBAL_ACTIVE_POINTER,
context.byte_type().ptr_type(AddressSpace::Generic.into()),
AddressSpace::Stack,
calldata_pointer,
);
Ok(context.field_const(1).as_basic_value_enum())
}
///
/// Shifts the active pointer by the specified `offset`.
///
pub fn active_ptr_add_assign<'ctx, D>(
context: &mut Context<'ctx, D>,
offset: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let active_pointer = context.get_global_value(crate::eravm::GLOBAL_ACTIVE_POINTER)?;
let active_pointer_shifted = context.build_gep(
Pointer::new(
context.byte_type(),
AddressSpace::Generic,
active_pointer.into_pointer_value(),
),
&[offset],
context.byte_type().as_basic_type_enum(),
"active_pointer_shifted",
);
context.set_global(
crate::eravm::GLOBAL_ACTIVE_POINTER,
context.byte_type().ptr_type(AddressSpace::Generic.into()),
AddressSpace::Stack,
active_pointer_shifted.value,
);
Ok(context.field_const(1).as_basic_value_enum())
}
///
/// Shrinks the active pointer by the specified `offset`.
///
pub fn active_ptr_shrink_assign<'ctx, D>(
_context: &mut Context<'ctx, D>,
_offset: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
unimplemented!()
}
///
/// Writes the specified `data` into the upper 128 bits of the active pointer.
///
pub fn active_ptr_pack_assign<'ctx, D>(
_context: &mut Context<'ctx, D>,
_data: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
unimplemented!()
}
///
/// Loads a single word from the active pointer to the stack.
///
pub fn active_ptr_data_load<'ctx, D>(
context: &mut Context<'ctx, D>,
offset: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let active_pointer = context.get_global_value(crate::eravm::GLOBAL_ACTIVE_POINTER)?;
let active_pointer = context.build_gep(
Pointer::new(
context.byte_type(),
AddressSpace::Generic,
active_pointer.into_pointer_value(),
),
&[offset],
context.field_type().as_basic_type_enum(),
"active_pointer_with_offset",
);
context.build_load(active_pointer, "active_pointer_value")
}
///
/// Returns the active pointer data size.
///
pub fn active_ptr_data_size<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let active_pointer = context.get_global_value(crate::eravm::GLOBAL_ACTIVE_POINTER)?;
let active_pointer_value = context.builder().build_ptr_to_int(
active_pointer.into_pointer_value(),
context.field_type(),
"active_pointer_value",
)?;
let active_pointer_value_shifted = context.builder().build_right_shift(
active_pointer_value,
context.field_const((revive_common::BIT_LENGTH_X32 * 3) as u64),
false,
"active_pointer_value_shifted",
)?;
let active_pointer_length = context.builder().build_and(
active_pointer_value_shifted,
context.field_const(u32::MAX as u64),
"active_pointer_length",
)?;
Ok(active_pointer_length.as_basic_value_enum())
}
///
/// Copies a chunk of data from the active pointer to the heap.
///
pub fn active_ptr_data_copy<'ctx, D>(
context: &mut Context<'ctx, D>,
destination_offset: inkwell::values::IntValue<'ctx>,
source_offset: inkwell::values::IntValue<'ctx>,
size: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let destination = Pointer::new_with_offset(
context,
AddressSpace::Heap,
context.byte_type(),
destination_offset,
"active_pointer_data_copy_destination_pointer",
);
let active_pointer = context.get_global_value(crate::eravm::GLOBAL_ACTIVE_POINTER)?;
let source = context.build_gep(
Pointer::new(
context.byte_type(),
AddressSpace::Generic,
active_pointer.into_pointer_value(),
),
&[source_offset],
context.byte_type().as_basic_type_enum(),
"active_pointer_data_copy_source_pointer",
);
context.build_memcpy(
context.intrinsics().memory_copy_from_generic,
destination,
source,
size,
"active_pointer_data_copy_memcpy_from_child",
)?;
Ok(context.field_const(1).as_basic_value_enum())
}
@@ -1,302 +0,0 @@
//!
//! Translates the call instructions of the EraVM Yul extension.
//!
use crate::eravm::context::address_space::AddressSpace;
use crate::eravm::context::function::declaration::Declaration as FunctionDeclaration;
use crate::eravm::context::pointer::Pointer;
use crate::eravm::context::Context;
use crate::eravm::Dependency;
///
/// Generates a mimic call.
///
/// The mimic call is a special type of call that can only be used in the system contracts of
/// zkSync. The call allows to call a contract with custom `msg.sender`, allowing to insert
/// system contracts as middlewares.
///
pub fn mimic<'ctx, D>(
context: &mut Context<'ctx, D>,
function: FunctionDeclaration<'ctx>,
address: inkwell::values::IntValue<'ctx>,
mimic: inkwell::values::IntValue<'ctx>,
abi_data: inkwell::values::BasicValueEnum<'ctx>,
extra_abi_data: Vec<inkwell::values::IntValue<'ctx>>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let status_code_result_pointer = context.build_alloca(
context.field_type(),
"mimic_call_result_status_code_pointer",
);
context.build_store(status_code_result_pointer, context.field_const(0))?;
let far_call_result = context
.build_call(
function,
crate::eravm::utils::external_call_arguments(
context,
abi_data,
address,
extra_abi_data,
Some(mimic),
)
.as_slice(),
"mimic_call_external",
)
.expect("IntrinsicFunction always returns a flag");
let result_abi_data = context
.builder()
.build_extract_value(
far_call_result.into_struct_value(),
0,
"mimic_call_external_result_abi_data",
)
.expect("Always exists");
let result_abi_data_pointer = Pointer::new(
context.byte_type(),
AddressSpace::Generic,
result_abi_data.into_pointer_value(),
);
let result_status_code_boolean = context
.builder()
.build_extract_value(
far_call_result.into_struct_value(),
1,
"mimic_call_external_result_status_code_boolean",
)
.expect("Always exists");
let result_status_code = context.builder().build_int_z_extend_or_bit_cast(
result_status_code_boolean.into_int_value(),
context.field_type(),
"mimic_call_external_result_status_code",
)?;
context.build_store(status_code_result_pointer, result_status_code)?;
context.write_abi_pointer(
result_abi_data_pointer,
crate::eravm::GLOBAL_RETURN_DATA_POINTER,
);
context.write_abi_data_size(
result_abi_data_pointer,
crate::eravm::GLOBAL_RETURN_DATA_SIZE,
);
context.build_load(status_code_result_pointer, "mimic_call_status_code")
}
///
/// Generates a raw far call.
///
/// Such calls can accept extra ABI arguments passed via the virtual machine registers.
///
pub fn raw_far<'ctx, D>(
_context: &mut Context<'ctx, D>,
_function: FunctionDeclaration<'ctx>,
_address: inkwell::values::IntValue<'ctx>,
_abi_data: inkwell::values::BasicValueEnum<'ctx>,
_output_offset: inkwell::values::IntValue<'ctx>,
_output_length: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
todo!();
/*
let status_code_result_pointer = context.build_alloca(
context.field_type(),
"system_far_call_result_status_code_pointer",
);
context.build_store(status_code_result_pointer, context.field_const(0));
let far_call_result = context
.build_call(
function,
crate::eravm::utils::external_call_arguments(context, abi_data, address, vec![], None)
.as_slice(),
"system_far_call_external",
)
.expect("IntrinsicFunction always returns a flag");
let result_abi_data = context
.builder()
.build_extract_value(
far_call_result.into_struct_value(),
0,
"system_far_call_external_result_abi_data",
)
.expect("Always exists");
let result_abi_data_pointer = Pointer::new(
context.byte_type(),
AddressSpace::Generic,
result_abi_data.into_pointer_value(),
);
let result_status_code_boolean = context
.builder()
.build_extract_value(
far_call_result.into_struct_value(),
1,
"system_far_call_external_result_status_code_boolean",
)
.expect("Always exists");
let result_status_code = context.builder().build_int_z_extend_or_bit_cast(
result_status_code_boolean.into_int_value(),
context.field_type(),
"system_far_call_external_result_status_code",
);
context.build_store(status_code_result_pointer, result_status_code);
let source = result_abi_data_pointer;
let destination = Pointer::new_with_offset(
context,
AddressSpace::Heap,
context.byte_type(),
output_offset,
"system_far_call_destination",
);
context.build_memcpy_return_data(
context.intrinsics().memory_copy_from_generic,
destination,
source,
output_length,
"system_far_call_memcpy_from_child",
);
context.write_abi_pointer(
result_abi_data_pointer,
crate::eravm::GLOBAL_RETURN_DATA_POINTER,
);
context.write_abi_data_size(
result_abi_data_pointer,
crate::eravm::GLOBAL_RETURN_DATA_SIZE,
);
let status_code_result =
context.build_load(status_code_result_pointer, "system_call_status_code");
Ok(status_code_result)
*/
}
///
/// Generates a system call.
///
/// Such calls can accept extra ABI arguments passed via the virtual machine registers. It is used,
/// for example, to pass the callee address and the Ether value to the `msg.value` simulator.
///
pub fn system<'ctx, D>(
context: &mut Context<'ctx, D>,
function: FunctionDeclaration<'ctx>,
address: inkwell::values::IntValue<'ctx>,
abi_data: inkwell::values::BasicValueEnum<'ctx>,
output_offset: inkwell::values::IntValue<'ctx>,
output_length: inkwell::values::IntValue<'ctx>,
extra_abi_data: Vec<inkwell::values::IntValue<'ctx>>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let status_code_result_pointer = context.build_alloca(
context.field_type(),
"system_far_call_result_status_code_pointer",
);
context.build_store(status_code_result_pointer, context.field_const(0))?;
let far_call_result = context
.build_call(
function,
crate::eravm::utils::external_call_arguments(
context,
abi_data,
address,
extra_abi_data,
None,
)
.as_slice(),
"system_far_call_external",
)
.expect("IntrinsicFunction always returns a flag");
let result_abi_data = context
.builder()
.build_extract_value(
far_call_result.into_struct_value(),
0,
"system_far_call_external_result_abi_data",
)
.expect("Always exists");
let result_abi_data_pointer = Pointer::new(
context.byte_type(),
AddressSpace::Generic,
result_abi_data.into_pointer_value(),
);
let result_status_code_boolean = context
.builder()
.build_extract_value(
far_call_result.into_struct_value(),
1,
"system_far_call_external_result_status_code_boolean",
)
.expect("Always exists");
let result_status_code = context.builder().build_int_z_extend_or_bit_cast(
result_status_code_boolean.into_int_value(),
context.field_type(),
"system_far_call_external_result_status_code",
)?;
context.build_store(status_code_result_pointer, result_status_code)?;
let source = result_abi_data_pointer;
let destination = Pointer::new_with_offset(
context,
AddressSpace::Heap,
context.byte_type(),
output_offset,
"system_far_call_destination",
);
context.build_memcpy_return_data(
context.intrinsics().memory_copy_from_generic,
destination,
source,
output_length,
"system_far_call_memcpy_from_child",
)?;
context.write_abi_pointer(
result_abi_data_pointer,
crate::eravm::GLOBAL_RETURN_DATA_POINTER,
);
context.write_abi_data_size(
result_abi_data_pointer,
crate::eravm::GLOBAL_RETURN_DATA_SIZE,
);
context.build_load(status_code_result_pointer, "system_call_status_code")
}
///
/// Checks if the instruction was called with a correct call type.
///
pub fn validate_call_type<'ctx>(
expected: FunctionDeclaration<'ctx>,
found: FunctionDeclaration<'ctx>,
instruction_name: &'static str,
) -> anyhow::Result<()> {
if expected != found {
anyhow::bail!(
"Only `{}` is allowed for the `{}` simulation, found `{}`",
expected.value.get_name().to_string_lossy(),
instruction_name,
found.value.get_name().to_string_lossy()
);
}
Ok(())
}
@@ -1,107 +0,0 @@
//!
//! Translates the const array instructions of the EraVM Yul extension.
//!
use inkwell::types::BasicType;
use inkwell::values::BasicValue;
use crate::eravm::context::address_space::AddressSpace;
use crate::eravm::context::Context;
use crate::eravm::Dependency;
///
/// Declares a constant array in the code section.
///
pub fn _declare<'ctx, D>(
context: &mut Context<'ctx, D>,
index: u8,
size: u16,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
context.yul_mut().const_array_declare(index, size)?;
Ok(context.field_const(1).as_basic_value_enum())
}
///
/// Sets a value in a constant array in the code section.
///
pub fn _set<'ctx, D>(
context: &mut Context<'ctx, D>,
index: u8,
offset: u16,
value: num::BigUint,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
context.yul_mut().const_array_set(index, offset, value)?;
Ok(context.field_const(1).as_basic_value_enum())
}
///
/// Finalizes a constant array in the code section, by extracting it from
/// the temporary compile-time storage, and initializing it in LLVM IR.
///
pub fn _finalize<'ctx, D>(
context: &mut Context<'ctx, D>,
index: u8,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let const_array = context.yul_mut().const_array_take(index)?;
let array_type = context.field_type().array_type(const_array.len() as u32);
let array_value = context.field_type().const_array(
const_array
.into_iter()
.map(|value| context.field_const_str_dec(value.to_string().as_str()))
.collect::<Vec<inkwell::values::IntValue<'ctx>>>()
.as_slice(),
);
context.set_global(
format!(
"{}{:03}",
crate::eravm::r#const::GLOBAL_CONST_ARRAY_PREFIX,
index
)
.as_str(),
array_type,
AddressSpace::Code,
array_value,
);
Ok(context.field_const(1).as_basic_value_enum())
}
///
/// Gets a value from a constant array in the code section.
///
pub fn _get<'ctx, D>(
context: &mut Context<'ctx, D>,
index: u8,
offset: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let identifier = format!(
"{}{:03}",
crate::eravm::r#const::GLOBAL_CONST_ARRAY_PREFIX,
index
);
let global = context.get_global(identifier.as_str())?;
let pointer = global.into();
let pointer = context.build_gep(
pointer,
&[context.field_const(0), offset],
context.field_type().as_basic_type_enum(),
format!("{}_pointer", identifier).as_str(),
);
context.build_load(pointer, format!("{}_value", identifier).as_str())
}
@@ -1,112 +0,0 @@
//!
//! Translates the general instructions of the EraVM Yul extension.
//!
use crate::eravm::context::Context;
use crate::eravm::Dependency;
///
/// Generates a call to L1.
///
pub fn to_l1<'ctx, D>(
_context: &mut Context<'ctx, D>,
_is_first: inkwell::values::IntValue<'ctx>,
_in_0: inkwell::values::IntValue<'ctx>,
_in_1: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
unimplemented!()
}
///
/// Generates a `code source` call.
///
pub fn code_source<'ctx, D>(
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
todo!()
}
///
/// Generates a precompile call.
///
pub fn precompile<'ctx, D>(
_context: &mut Context<'ctx, D>,
_in_0: inkwell::values::IntValue<'ctx>,
_gas_left: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
todo!()
}
///
/// Generates a `meta` call.
///
pub fn meta<'ctx, D>(
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
unimplemented!()
}
///
/// Generates a `u128` context value setter call.
///
pub fn set_context_value<'ctx, D>(
_context: &mut Context<'ctx, D>,
_value: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
unimplemented!()
}
///
/// Generates a public data price setter call.
///
pub fn set_pubdata_price<'ctx, D>(
_context: &mut Context<'ctx, D>,
_value: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
unimplemented!()
}
///
/// Generates a transaction counter increment call.
///
pub fn increment_tx_counter<'ctx, D>(
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
unimplemented!()
}
///
/// Generates an event call.
///
pub fn event<'ctx, D>(
_context: &mut Context<'ctx, D>,
_operand_1: inkwell::values::IntValue<'ctx>,
_operand_2: inkwell::values::IntValue<'ctx>,
_is_initializer: bool,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
todo!()
}
@@ -1,52 +0,0 @@
//!
//! Translates the math instructions of the EraVM Yul extension.
//!
use inkwell::values::BasicValue;
use crate::eravm::context::Context;
use crate::eravm::Dependency;
///
/// Performs a multiplication, returning the higher register, that is the overflown part.
///
pub fn multiplication_512<'ctx, D>(
context: &mut Context<'ctx, D>,
operand_1: inkwell::values::IntValue<'ctx>,
operand_2: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let operand_1_extended = context.builder().build_int_z_extend_or_bit_cast(
operand_1,
context.integer_type(revive_common::BIT_LENGTH_FIELD * 2),
"multiplication_512_operand_1_extended",
)?;
let operand_2_extended = context.builder().build_int_z_extend_or_bit_cast(
operand_2,
context.integer_type(revive_common::BIT_LENGTH_FIELD * 2),
"multiplication_512_operand_2_extended",
)?;
let result_extended = context.builder().build_int_mul(
operand_1_extended,
operand_2_extended,
"multiplication_512_result_extended",
)?;
let result_shifted = context.builder().build_right_shift(
result_extended,
context.integer_const(
revive_common::BIT_LENGTH_FIELD * 2,
revive_common::BIT_LENGTH_FIELD as u64,
),
false,
"multiplication_512_result_shifted",
)?;
let result = context.builder().build_int_truncate_or_bit_cast(
result_shifted,
context.field_type(),
"multiplication_512_result",
)?;
Ok(result.as_basic_value_enum())
}
@@ -1,9 +0,0 @@
//!
//! The EraVM instructions translation utils.
//!
pub mod abi;
pub mod call;
pub mod const_array;
pub mod general;
pub mod math;
-1
View File
@@ -5,7 +5,6 @@
pub mod r#const;
pub mod context;
pub mod evm;
pub mod extensions;
pub mod metadata_hash;
pub mod utils;
-4
View File
@@ -55,10 +55,6 @@ pub use self::eravm::evm::memory as eravm_evm_memory;
pub use self::eravm::evm::r#return as eravm_evm_return;
pub use self::eravm::evm::return_data as eravm_evm_return_data;
pub use self::eravm::evm::storage as eravm_evm_storage;
pub use self::eravm::extensions::abi as eravm_abi;
pub use self::eravm::extensions::call as eravm_call;
pub use self::eravm::extensions::general as eravm_general;
pub use self::eravm::extensions::math as eravm_math;
pub use self::eravm::metadata_hash::MetadataHash as EraVMMetadataHash;
pub use self::eravm::r#const as eravm_const;
pub use self::eravm::utils as eravm_utils;
@@ -855,13 +855,7 @@ where
era_compiler_llvm_context::eravm_evm_calldata::size(context).map(Some)
}
era_compiler_llvm_context::EraVMCodeType::Runtime => {
let code_source =
era_compiler_llvm_context::eravm_general::code_source(context)?;
era_compiler_llvm_context::eravm_evm_ext_code::size(
context,
code_source.into_int_value(),
)
.map(Some)
todo!()
}
}
}
@@ -599,13 +599,7 @@ impl FunctionCall {
era_compiler_llvm_context::eravm_evm_calldata::size(context).map(Some)
}
era_compiler_llvm_context::EraVMCodeType::Runtime => {
let code_source =
era_compiler_llvm_context::eravm_general::code_source(context)?;
era_compiler_llvm_context::eravm_evm_ext_code::size(
context,
code_source.into_int_value(),
)
.map(Some)
todo!()
}
}
}
@@ -837,7 +831,7 @@ impl FunctionCall {
.map(Some)
}
Name::Create | Name::ZkCreate => {
Name::Create => {
let arguments = self.pop_arguments_llvm::<D, 3>(context)?;
let value = arguments[0].into_int_value();
@@ -852,7 +846,7 @@ impl FunctionCall {
)
.map(Some)
}
Name::Create2 | Name::ZkCreate2 => {
Name::Create2 => {
let arguments = self.pop_arguments_llvm::<D, 4>(context)?;
let value = arguments[0].into_int_value();
@@ -1016,416 +1010,6 @@ impl FunctionCall {
location
)
}
Name::ZkToL1 => {
let [is_first, in_0, in_1] = self.pop_arguments_llvm::<D, 3>(context)?;
era_compiler_llvm_context::eravm_general::to_l1(
context,
is_first.into_int_value(),
in_0.into_int_value(),
in_1.into_int_value(),
)
.map(Some)
}
Name::ZkCodeSource => {
era_compiler_llvm_context::eravm_general::code_source(context).map(Some)
}
Name::ZkPrecompile => {
let [in_0, in_1] = self.pop_arguments_llvm::<D, 2>(context)?;
era_compiler_llvm_context::eravm_general::precompile(
context,
in_0.into_int_value(),
in_1.into_int_value(),
)
.map(Some)
}
Name::ZkMeta => era_compiler_llvm_context::eravm_general::meta(context).map(Some),
Name::ZkSetContextU128 => {
let [value] = self.pop_arguments_llvm::<D, 1>(context)?;
era_compiler_llvm_context::eravm_general::set_context_value(
context,
value.into_int_value(),
)
.map(|_| None)
}
Name::ZkSetPubdataPrice => {
let [value] = self.pop_arguments_llvm::<D, 1>(context)?;
era_compiler_llvm_context::eravm_general::set_pubdata_price(
context,
value.into_int_value(),
)
.map(|_| None)
}
Name::ZkIncrementTxCounter => {
era_compiler_llvm_context::eravm_general::increment_tx_counter(context)
.map(|_| None)
}
Name::ZkEventInitialize => {
let [operand_1, operand_2] = self.pop_arguments_llvm::<D, 2>(context)?;
era_compiler_llvm_context::eravm_general::event(
context,
operand_1.into_int_value(),
operand_2.into_int_value(),
true,
)
.map(|_| None)
}
Name::ZkEventWrite => {
let [operand_1, operand_2] = self.pop_arguments_llvm::<D, 2>(context)?;
era_compiler_llvm_context::eravm_general::event(
context,
operand_1.into_int_value(),
operand_2.into_int_value(),
false,
)
.map(|_| None)
}
Name::ZkMimicCall => {
let [address, abi_data, mimic] = self.pop_arguments_llvm::<D, 3>(context)?;
era_compiler_llvm_context::eravm_call::mimic(
context,
context.llvm_runtime().mimic_call,
address.into_int_value(),
mimic.into_int_value(),
abi_data.as_basic_value_enum(),
vec![],
)
.map(Some)
}
Name::ZkSystemMimicCall => {
let [address, abi_data, mimic, extra_value_1, extra_value_2] =
self.pop_arguments_llvm::<D, 5>(context)?;
era_compiler_llvm_context::eravm_call::mimic(
context,
context.llvm_runtime().mimic_call,
address.into_int_value(),
mimic.into_int_value(),
abi_data.as_basic_value_enum(),
vec![
extra_value_1.into_int_value(),
extra_value_2.into_int_value(),
],
)
.map(Some)
}
Name::ZkMimicCallByRef => {
let [address, mimic] = self.pop_arguments_llvm::<D, 2>(context)?;
let abi_data = context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?;
era_compiler_llvm_context::eravm_call::mimic(
context,
context.llvm_runtime().mimic_call_byref,
address.into_int_value(),
mimic.into_int_value(),
abi_data,
vec![],
)
.map(Some)
}
Name::ZkSystemMimicCallByRef => {
let [address, mimic, extra_value_1, extra_value_2] =
self.pop_arguments_llvm::<D, 4>(context)?;
let abi_data = context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?;
era_compiler_llvm_context::eravm_call::mimic(
context,
context.llvm_runtime().mimic_call_byref,
address.into_int_value(),
mimic.into_int_value(),
abi_data,
vec![
extra_value_1.into_int_value(),
extra_value_2.into_int_value(),
],
)
.map(Some)
}
Name::ZkRawCall => {
unimplemented!()
}
Name::ZkRawCallByRef => {
let [address, output_offset, output_length] =
self.pop_arguments_llvm::<D, 3>(context)?;
let abi_data = context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?;
era_compiler_llvm_context::eravm_call::raw_far(
context,
context.llvm_runtime().far_call_byref,
address.into_int_value(),
abi_data,
output_offset.into_int_value(),
output_length.into_int_value(),
)
.map(Some)
}
Name::ZkSystemCall => {
unimplemented!()
}
Name::ZkSystemCallByRef => {
let [address, extra_value_1, extra_value_2, extra_value_3, extra_value_4] =
self.pop_arguments_llvm::<D, 5>(context)?;
let abi_data = context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?;
era_compiler_llvm_context::eravm_call::system(
context,
context.llvm_runtime().far_call_byref,
address.into_int_value(),
abi_data,
context.field_const(0),
context.field_const(0),
vec![
extra_value_1.into_int_value(),
extra_value_2.into_int_value(),
extra_value_3.into_int_value(),
extra_value_4.into_int_value(),
],
)
.map(Some)
}
Name::ZkStaticRawCall => {
let [address, abi_data, output_offset, output_length] =
self.pop_arguments_llvm::<D, 4>(context)?;
era_compiler_llvm_context::eravm_call::raw_far(
context,
context.llvm_runtime().static_call,
address.into_int_value(),
abi_data.as_basic_value_enum(),
output_offset.into_int_value(),
output_length.into_int_value(),
)
.map(Some)
}
Name::ZkStaticRawCallByRef => {
let [address, output_offset, output_length] =
self.pop_arguments_llvm::<D, 3>(context)?;
let abi_data = context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?;
era_compiler_llvm_context::eravm_call::raw_far(
context,
context.llvm_runtime().static_call_byref,
address.into_int_value(),
abi_data,
output_offset.into_int_value(),
output_length.into_int_value(),
)
.map(Some)
}
Name::ZkStaticSystemCall => {
let [address, abi_data, extra_value_1, extra_value_2, extra_value_3, extra_value_4] =
self.pop_arguments_llvm::<D, 6>(context)?;
era_compiler_llvm_context::eravm_call::system(
context,
context.llvm_runtime().static_call,
address.into_int_value(),
abi_data,
context.field_const(0),
context.field_const(0),
vec![
extra_value_1.into_int_value(),
extra_value_2.into_int_value(),
extra_value_3.into_int_value(),
extra_value_4.into_int_value(),
],
)
.map(Some)
}
Name::ZkStaticSystemCallByRef => {
let [address, extra_value_1, extra_value_2, extra_value_3, extra_value_4] =
self.pop_arguments_llvm::<D, 5>(context)?;
let abi_data = context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?;
era_compiler_llvm_context::eravm_call::system(
context,
context.llvm_runtime().static_call_byref,
address.into_int_value(),
abi_data,
context.field_const(0),
context.field_const(0),
vec![
extra_value_1.into_int_value(),
extra_value_2.into_int_value(),
extra_value_3.into_int_value(),
extra_value_4.into_int_value(),
],
)
.map(Some)
}
Name::ZkDelegateRawCall => {
let [address, abi_data, output_offset, output_length] =
self.pop_arguments_llvm::<D, 4>(context)?;
era_compiler_llvm_context::eravm_call::raw_far(
context,
context.llvm_runtime().delegate_call,
address.into_int_value(),
abi_data.as_basic_value_enum(),
output_offset.into_int_value(),
output_length.into_int_value(),
)
.map(Some)
}
Name::ZkDelegateRawCallByRef => {
let [address, output_offset, output_length] =
self.pop_arguments_llvm::<D, 3>(context)?;
let abi_data = context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?;
era_compiler_llvm_context::eravm_call::raw_far(
context,
context.llvm_runtime().delegate_call_byref,
address.into_int_value(),
abi_data,
output_offset.into_int_value(),
output_length.into_int_value(),
)
.map(Some)
}
Name::ZkDelegateSystemCall => {
let [address, abi_data, extra_value_1, extra_value_2, extra_value_3, extra_value_4] =
self.pop_arguments_llvm::<D, 6>(context)?;
era_compiler_llvm_context::eravm_call::system(
context,
context.llvm_runtime().delegate_call,
address.into_int_value(),
abi_data,
context.field_const(0),
context.field_const(0),
vec![
extra_value_1.into_int_value(),
extra_value_2.into_int_value(),
extra_value_3.into_int_value(),
extra_value_4.into_int_value(),
],
)
.map(Some)
}
Name::ZkDelegateSystemCallByRef => {
let [address, extra_value_1, extra_value_2, extra_value_3, extra_value_4] =
self.pop_arguments_llvm::<D, 5>(context)?;
let abi_data = context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?;
era_compiler_llvm_context::eravm_call::system(
context,
context.llvm_runtime().delegate_call_byref,
address.into_int_value(),
abi_data,
context.field_const(0),
context.field_const(0),
vec![
extra_value_1.into_int_value(),
extra_value_2.into_int_value(),
extra_value_3.into_int_value(),
extra_value_4.into_int_value(),
],
)
.map(Some)
}
Name::ZkLoadCalldataIntoActivePtr => {
era_compiler_llvm_context::eravm_abi::calldata_ptr_to_active(context).map(|_| None)
}
Name::ZkLoadReturndataIntoActivePtr => {
era_compiler_llvm_context::eravm_abi::return_data_ptr_to_active(context)
.map(|_| None)
}
Name::ZkPtrAddIntoActive => {
let [offset] = self.pop_arguments_llvm::<D, 1>(context)?;
era_compiler_llvm_context::eravm_abi::active_ptr_add_assign(
context,
offset.into_int_value(),
)
.map(|_| None)
}
Name::ZkPtrShrinkIntoActive => {
let [offset] = self.pop_arguments_llvm::<D, 1>(context)?;
era_compiler_llvm_context::eravm_abi::active_ptr_shrink_assign(
context,
offset.into_int_value(),
)
.map(|_| None)
}
Name::ZkPtrPackIntoActive => {
let [data] = self.pop_arguments_llvm::<D, 1>(context)?;
era_compiler_llvm_context::eravm_abi::active_ptr_pack_assign(
context,
data.into_int_value(),
)
.map(|_| None)
}
Name::ZkMultiplicationHigh => {
let [operand_1, operand_2] = self.pop_arguments_llvm::<D, 2>(context)?;
era_compiler_llvm_context::eravm_math::multiplication_512(
context,
operand_1.into_int_value(),
operand_2.into_int_value(),
)
.map(Some)
}
Name::ZkGlobalLoad => {
let [mut key] = self.pop_arguments::<D, 1>(context)?;
let key = key.original.take().ok_or_else(|| {
anyhow::anyhow!("{} `$zk_global_load` literal is missing", location)
})?;
context.get_global_value(key.as_str()).map(Some)
}
Name::ZkGlobalExtraAbiData => {
let [index] = self.pop_arguments_llvm::<D, 1>(context)?;
era_compiler_llvm_context::eravm_abi::get_extra_abi_data(
context,
index.into_int_value(),
)
.map(Some)
}
Name::ZkGlobalStore => {
let [mut key, value] = self.pop_arguments::<D, 2>(context)?;
let key = key.original.take().ok_or_else(|| {
anyhow::anyhow!("{} `$zk_global_store` literal is missing", location)
})?;
let value = value.value.into_int_value();
context.set_global(
key.as_str(),
context.field_type(),
era_compiler_llvm_context::EraVMAddressSpace::Stack,
value,
);
Ok(None)
}
}
}
@@ -157,17 +157,6 @@ pub enum Name {
///
/// Passes bytecode to the system contracts.
Create2,
/// create new contract with code `mem[p…(p+n))` and send `v` wei and return the new address
///
/// Passes hash to the system contracts.
ZkCreate,
/// create new contract with code `mem[p…(p+n))` at address
/// `keccak256(0xff . this . s . keccak256(mem[p…(p+n)))` and send `v` wei and return the
/// new address, where `0xff` is a 1-byte value, this is the current contracts address as a
/// 20-byte value and `s` is a big-endian 256-bit value
///
/// Passes hash to the system contracts.
ZkCreate2,
/// returns the size in the data area
DataSize,
/// is equivalent to `CodeCopy`
@@ -238,79 +227,6 @@ pub enum Name {
ExtCodeCopy,
/// end execution, destroy current contract and send funds to `a`
SelfDestruct,
/// The eponymous EraVM Yul extension instruction.
ZkToL1,
/// The eponymous EraVM Yul extension instruction.
ZkCodeSource,
/// The eponymous EraVM Yul extension instruction.
ZkPrecompile,
/// The eponymous EraVM Yul extension instruction.
ZkMeta,
/// The eponymous EraVM Yul extension instruction.
ZkSetContextU128,
/// The eponymous EraVM Yul extension instruction.
ZkSetPubdataPrice,
/// The eponymous EraVM Yul extension instruction.
ZkIncrementTxCounter,
/// The eponymous EraVM Yul extension instruction.
ZkEventInitialize,
/// The eponymous EraVM Yul extension instruction.
ZkEventWrite,
/// The eponymous EraVM Yul extension instruction.
ZkMimicCall,
/// The eponymous EraVM Yul extension instruction.
ZkSystemMimicCall,
/// The eponymous EraVM Yul extension instruction.
ZkMimicCallByRef,
/// The eponymous EraVM Yul extension instruction.
ZkSystemMimicCallByRef,
/// The eponymous EraVM Yul extension instruction.
ZkRawCall,
/// The eponymous EraVM Yul extension instruction.
ZkRawCallByRef,
/// The eponymous EraVM Yul extension instruction.
ZkSystemCall,
/// The eponymous EraVM Yul extension instruction.
ZkSystemCallByRef,
/// The eponymous EraVM Yul extension instruction.
ZkStaticRawCall,
/// The eponymous EraVM Yul extension instruction.
ZkStaticRawCallByRef,
/// The eponymous EraVM Yul extension instruction.
ZkStaticSystemCall,
/// The eponymous EraVM Yul extension instruction.
ZkStaticSystemCallByRef,
/// The eponymous EraVM Yul extension instruction.
ZkDelegateRawCall,
/// The eponymous EraVM Yul extension instruction.
ZkDelegateRawCallByRef,
/// The eponymous EraVM Yul extension instruction.
ZkDelegateSystemCall,
/// The eponymous EraVM Yul extension instruction.
ZkDelegateSystemCallByRef,
/// The eponymous EraVM Yul extension instruction.
ZkLoadCalldataIntoActivePtr,
/// The eponymous EraVM Yul extension instruction.
ZkLoadReturndataIntoActivePtr,
/// The eponymous EraVM Yul extension instruction.
ZkPtrAddIntoActive,
/// The eponymous EraVM Yul extension instruction.
ZkPtrShrinkIntoActive,
/// The eponymous EraVM Yul extension instruction.
ZkPtrPackIntoActive,
/// The eponymous EraVM Yul extension instruction.
ZkMultiplicationHigh,
/// The eponymous EraVM Yul extension instruction.
ZkGlobalLoad,
/// The eponymous EraVM Yul extension instruction.
ZkGlobalExtraAbiData,
/// The eponymous EraVM Yul extension instruction.
ZkGlobalStore,
}
impl Name {
@@ -406,8 +322,6 @@ impl From<&str> for Name {
"create" => Self::Create,
"create2" => Self::Create2,
"$zk_create" => Self::ZkCreate,
"$zk_create2" => Self::ZkCreate2,
"datasize" => Self::DataSize,
"dataoffset" => Self::DataOffset,
"datacopy" => Self::DataCopy,
@@ -446,45 +360,6 @@ impl From<&str> for Name {
"extcodecopy" => Self::ExtCodeCopy,
"selfdestruct" => Self::SelfDestruct,
"$zk_to_l1" => Self::ZkToL1,
"$zk_code_source" => Self::ZkCodeSource,
"$zk_precompile" => Self::ZkPrecompile,
"$zk_meta" => Self::ZkMeta,
"$zk_set_context_u128" => Self::ZkSetContextU128,
"$zk_set_pubdata_price" => Self::ZkSetPubdataPrice,
"$zk_increment_tx_counter" => Self::ZkIncrementTxCounter,
"$zk_event_initialize" => Self::ZkEventInitialize,
"$zk_event_write" => Self::ZkEventWrite,
"$zk_mimic_call" => Self::ZkMimicCall,
"$zk_system_mimic_call" => Self::ZkSystemMimicCall,
"$zk_mimic_call_byref" => Self::ZkMimicCallByRef,
"$zk_system_mimic_call_byref" => Self::ZkSystemMimicCallByRef,
"$zk_raw_call" => Self::ZkRawCall,
"$zk_raw_call_byref" => Self::ZkRawCallByRef,
"$zk_system_call" => Self::ZkSystemCall,
"$zk_system_call_byref" => Self::ZkSystemCallByRef,
"$zk_static_raw_call" => Self::ZkStaticRawCall,
"$zk_static_raw_call_byref" => Self::ZkStaticRawCallByRef,
"$zk_static_system_call" => Self::ZkStaticSystemCall,
"$zk_static_system_call_byref" => Self::ZkStaticSystemCallByRef,
"$zk_delegate_raw_call" => Self::ZkDelegateRawCall,
"$zk_delegate_raw_call_byref" => Self::ZkDelegateRawCallByRef,
"$zk_delegate_system_call" => Self::ZkDelegateSystemCall,
"$zk_delegate_system_call_byref" => Self::ZkDelegateSystemCallByRef,
"$zk_load_calldata_into_active_ptr" => Self::ZkLoadCalldataIntoActivePtr,
"$zk_load_returndata_into_active_ptr" => Self::ZkLoadReturndataIntoActivePtr,
"$zk_ptr_add_into_active" => Self::ZkPtrAddIntoActive,
"$zk_ptr_shrink_into_active" => Self::ZkPtrShrinkIntoActive,
"$zk_ptr_pack_into_active" => Self::ZkPtrPackIntoActive,
"$zk_multiplication_high" => Self::ZkMultiplicationHigh,
"$zk_global_load" => Self::ZkGlobalLoad,
"$zk_global_extra_abi_data" => Self::ZkGlobalExtraAbiData,
"$zk_global_store" => Self::ZkGlobalStore,
input => Self::UserDefined(input.to_owned()),
}
}
@@ -2,8 +2,6 @@
//! Translates the verbatim simulations.
//!
use anyhow::Ok;
use crate::yul::parser::statement::expression::function_call::FunctionCall;
///
@@ -12,7 +10,7 @@ use crate::yul::parser::statement::expression::function_call::FunctionCall;
pub fn verbatim<'ctx, D>(
context: &mut era_compiler_llvm_context::EraVMContext<'ctx, D>,
call: &mut FunctionCall,
input_size: usize,
_input_size: usize,
output_size: usize,
) -> anyhow::Result<Option<inkwell::values::BasicValueEnum<'ctx>>>
where
@@ -31,808 +29,7 @@ where
.take()
.ok_or_else(|| anyhow::anyhow!("{} Verbatim literal is missing", call.location))?;
match identifier.as_str() {
identifier @ "to_l1" => {
const ARGUMENTS_COUNT: usize = 3;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_general::to_l1(
context,
arguments[0].into_int_value(),
arguments[1].into_int_value(),
arguments[2].into_int_value(),
)
.map(Some)
}
identifier @ "code_source" => {
const ARGUMENTS_COUNT: usize = 0;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
era_compiler_llvm_context::eravm_general::code_source(context).map(Some)
}
identifier @ "precompile" => {
const ARGUMENTS_COUNT: usize = 2;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_general::precompile(
context,
arguments[0].into_int_value(),
arguments[1].into_int_value(),
)
.map(Some)
}
identifier @ "meta" => {
const ARGUMENTS_COUNT: usize = 0;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
era_compiler_llvm_context::eravm_general::meta(context).map(Some)
}
identifier @ "mimic_call" => {
const ARGUMENTS_COUNT: usize = 3;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::mimic(
context,
context.llvm_runtime().mimic_call,
arguments[0].into_int_value(),
arguments[1].into_int_value(),
arguments[2],
vec![context.field_const(0), context.field_const(0)],
)
.map(Some)
}
identifier @ "mimic_call_byref" => {
const ARGUMENTS_COUNT: usize = 2;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::mimic(
context,
context.llvm_runtime().mimic_call_byref,
arguments[0].into_int_value(),
arguments[1].into_int_value(),
context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?,
vec![context.field_const(0), context.field_const(0)],
)
.map(Some)
}
identifier @ "system_mimic_call" => {
const ARGUMENTS_COUNT: usize = 7;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::mimic(
context,
context.llvm_runtime().mimic_call,
arguments[0].into_int_value(),
arguments[1].into_int_value(),
arguments[2],
vec![
arguments[3].into_int_value(),
arguments[4].into_int_value(),
arguments[5].into_int_value(),
arguments[6].into_int_value(),
],
)
.map(Some)
}
identifier @ "system_mimic_call_byref" => {
const ARGUMENTS_COUNT: usize = 6;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::mimic(
context,
context.llvm_runtime().mimic_call_byref,
arguments[0].into_int_value(),
arguments[1].into_int_value(),
context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?,
vec![
arguments[2].into_int_value(),
arguments[3].into_int_value(),
arguments[4].into_int_value(),
arguments[5].into_int_value(),
],
)
.map(Some)
}
identifier @ "raw_call" => {
const ARGUMENTS_COUNT: usize = 4;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let _arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
todo!()
//era_compiler_llvm_context::eravm_call::raw_far(
// context,
// context.llvm_runtime().far_call,
// arguments[0].into_int_value(),
// arguments[1],
// arguments[2].into_int_value(),
// arguments[3].into_int_value(),
//)
//.map(Some)
}
identifier @ "raw_call_byref" => {
const ARGUMENTS_COUNT: usize = 3;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::raw_far(
context,
context.llvm_runtime().far_call_byref,
arguments[0].into_int_value(),
context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?,
arguments[1].into_int_value(),
arguments[2].into_int_value(),
)
.map(Some)
}
_identifier @ "system_call" => {
unimplemented!()
}
identifier @ "system_call_byref" => {
const ARGUMENTS_COUNT: usize = 5;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::system(
context,
context.llvm_runtime().far_call_byref,
arguments[0].into_int_value(),
context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?,
context.field_const(0),
context.field_const(0),
vec![
arguments[1].into_int_value(),
arguments[2].into_int_value(),
arguments[3].into_int_value(),
arguments[4].into_int_value(),
],
)
.map(Some)
}
identifier @ "raw_static_call" => {
const ARGUMENTS_COUNT: usize = 4;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::raw_far(
context,
context.llvm_runtime().static_call,
arguments[0].into_int_value(),
arguments[1],
arguments[2].into_int_value(),
arguments[3].into_int_value(),
)
.map(Some)
}
identifier @ "raw_static_call_byref" => {
const ARGUMENTS_COUNT: usize = 3;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::raw_far(
context,
context.llvm_runtime().static_call_byref,
arguments[0].into_int_value(),
context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?,
arguments[1].into_int_value(),
arguments[2].into_int_value(),
)
.map(Some)
}
identifier @ "system_static_call" => {
const ARGUMENTS_COUNT: usize = 6;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::system(
context,
context.llvm_runtime().static_call,
arguments[0].into_int_value(),
arguments[1],
arguments[4].into_int_value(),
arguments[5].into_int_value(),
vec![arguments[2].into_int_value(), arguments[3].into_int_value()],
)
.map(Some)
}
identifier @ "system_static_call_byref" => {
const ARGUMENTS_COUNT: usize = 5;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::system(
context,
context.llvm_runtime().static_call_byref,
arguments[0].into_int_value(),
context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?,
arguments[3].into_int_value(),
arguments[4].into_int_value(),
vec![arguments[1].into_int_value(), arguments[2].into_int_value()],
)
.map(Some)
}
identifier @ "raw_delegate_call" => {
const ARGUMENTS_COUNT: usize = 4;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::raw_far(
context,
context.llvm_runtime().delegate_call,
arguments[0].into_int_value(),
arguments[1],
arguments[2].into_int_value(),
arguments[3].into_int_value(),
)
.map(Some)
}
identifier @ "raw_delegate_call_byref" => {
const ARGUMENTS_COUNT: usize = 3;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::raw_far(
context,
context.llvm_runtime().delegate_call_byref,
arguments[0].into_int_value(),
context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?,
arguments[1].into_int_value(),
arguments[2].into_int_value(),
)
.map(Some)
}
identifier @ "system_delegate_call" => {
const ARGUMENTS_COUNT: usize = 6;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::system(
context,
context.llvm_runtime().delegate_call,
arguments[0].into_int_value(),
arguments[1],
arguments[4].into_int_value(),
arguments[5].into_int_value(),
vec![arguments[2].into_int_value(), arguments[3].into_int_value()],
)
.map(Some)
}
identifier @ "system_delegate_call_byref" => {
const ARGUMENTS_COUNT: usize = 5;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_call::system(
context,
context.llvm_runtime().delegate_call_byref,
arguments[0].into_int_value(),
context.get_global_value(
era_compiler_llvm_context::eravm_const::GLOBAL_ACTIVE_POINTER,
)?,
arguments[3].into_int_value(),
arguments[4].into_int_value(),
vec![arguments[1].into_int_value(), arguments[2].into_int_value()],
)
.map(Some)
}
identifier @ "set_context_u128" => {
const ARGUMENTS_COUNT: usize = 1;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_general::set_context_value(
context,
arguments[0].into_int_value(),
)
.map(Some)
}
identifier @ "set_pubdata_price" => {
const ARGUMENTS_COUNT: usize = 1;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_general::set_pubdata_price(
context,
arguments[0].into_int_value(),
)
.map(Some)
}
identifier @ "increment_tx_counter" => {
const ARGUMENTS_COUNT: usize = 0;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
era_compiler_llvm_context::eravm_general::increment_tx_counter(context).map(Some)
}
identifier @ "event_initialize" => {
const ARGUMENTS_COUNT: usize = 2;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_general::event(
context,
arguments[0].into_int_value(),
arguments[1].into_int_value(),
true,
)
.map(Some)
}
identifier @ "event_write" => {
const ARGUMENTS_COUNT: usize = 2;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_general::event(
context,
arguments[0].into_int_value(),
arguments[1].into_int_value(),
false,
)
.map(Some)
}
identifier @ "calldata_ptr_to_active" => {
const ARGUMENTS_COUNT: usize = 0;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
era_compiler_llvm_context::eravm_abi::calldata_ptr_to_active(context).map(Some)
}
identifier @ "return_data_ptr_to_active" => {
const ARGUMENTS_COUNT: usize = 0;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
era_compiler_llvm_context::eravm_abi::return_data_ptr_to_active(context).map(Some)
}
identifier @ "active_ptr_add_assign" => {
const ARGUMENTS_COUNT: usize = 1;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_abi::active_ptr_add_assign(
context,
arguments[0].into_int_value(),
)
.map(Some)
}
identifier @ "active_ptr_shrink_assign" => {
const ARGUMENTS_COUNT: usize = 1;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_abi::active_ptr_shrink_assign(
context,
arguments[0].into_int_value(),
)
.map(Some)
}
identifier @ "active_ptr_pack_assign" => {
const ARGUMENTS_COUNT: usize = 1;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_abi::active_ptr_pack_assign(
context,
arguments[0].into_int_value(),
)
.map(Some)
}
identifier @ "mul_high" => {
const ARGUMENTS_COUNT: usize = 2;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_math::multiplication_512(
context,
arguments[0].into_int_value(),
arguments[1].into_int_value(),
)
.map(Some)
}
identifier @ "throw" => {
const ARGUMENTS_COUNT: usize = 0;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
era_compiler_llvm_context::eravm_utils::throw(context);
Ok(None)
}
identifier
if identifier.starts_with(
era_compiler_llvm_context::eravm_const::GLOBAL_VERBATIM_GETTER_PREFIX,
) =>
{
const ARGUMENTS_COUNT: usize = 0;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
match identifier
.strip_prefix(era_compiler_llvm_context::eravm_const::GLOBAL_VERBATIM_GETTER_PREFIX)
{
Some(identifier)
if identifier
== era_compiler_llvm_context::eravm_const::GLOBAL_CALLDATA_POINTER =>
{
context.get_global_value(identifier).map(Some)
}
Some(identifier)
if identifier == era_compiler_llvm_context::eravm_const::GLOBAL_CALL_FLAGS =>
{
context.get_global_value(identifier).map(Some)
}
Some(identifier)
if identifier
== era_compiler_llvm_context::eravm_const::GLOBAL_RETURN_DATA_POINTER =>
{
context.get_global_value(identifier).map(Some)
}
Some(identifier)
if identifier.starts_with(
era_compiler_llvm_context::eravm_const::GLOBAL_EXTRA_ABI_DATA,
) =>
{
let stripped = identifier
.strip_prefix(era_compiler_llvm_context::eravm_const::GLOBAL_EXTRA_ABI_DATA)
.expect("Always exists");
let stripped = stripped.strip_prefix('_').ok_or_else(|| {
anyhow::anyhow!(
"{} Invalid global variable identifier `{:?}`",
call.location,
identifier
)
})?;
let index = stripped.parse::<u64>().map_err(|error| {
anyhow::anyhow!(
"{} Invalid global variable identifier `{:?}`: {}",
call.location,
identifier,
error,
)
})?;
if index >= (era_compiler_llvm_context::eravm_const::EXTRA_ABI_DATA_SIZE as u64)
{
anyhow::bail!(
"{} Extra ABI data overflow. Only indexes `0..=9` are allowed",
call.location,
);
}
era_compiler_llvm_context::eravm_abi::get_extra_abi_data(
context,
context.field_const(index),
)
.map(Some)
}
identifier => Err(anyhow::anyhow!(
"{} Invalid global variable identifier `{:?}`",
call.location,
identifier
)),
}
}
identifier @ "active_ptr_data_load" => {
const ARGUMENTS_COUNT: usize = 1;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_abi::active_ptr_data_load(
context,
arguments[0].into_int_value(),
)
.map(Some)
}
identifier @ "active_ptr_data_size" => {
const ARGUMENTS_COUNT: usize = 0;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
era_compiler_llvm_context::eravm_abi::active_ptr_data_size(context).map(Some)
}
identifier @ "active_ptr_data_copy" => {
const ARGUMENTS_COUNT: usize = 3;
if input_size != ARGUMENTS_COUNT {
anyhow::bail!(
"{} Internal function `{}` expected {} arguments, found {}",
call.location,
identifier,
ARGUMENTS_COUNT,
input_size
);
}
let arguments = call.pop_arguments_llvm::<D, ARGUMENTS_COUNT>(context)?;
era_compiler_llvm_context::eravm_abi::active_ptr_data_copy(
context,
arguments[0].into_int_value(),
arguments[1].into_int_value(),
arguments[2].into_int_value(),
)
.map(|_| None)
}
identifier => anyhow::bail!(
_ => anyhow::bail!(
"{} Found unknown internal function `{}`",
call.location,
identifier