Files
revive/crates/llvm-context/src/polkavm/evm/context.rs
T
Cyrill Leutwiler d2f76b645f switch to pallet_revive runtime (#40)
Signed-off-by: xermicus <cyrill@parity.io>
2024-09-03 17:18:22 +02:00

212 lines
5.9 KiB
Rust

//! Translates the context getter instructions.
use inkwell::values::BasicValue;
use crate::polkavm::context::Context;
use crate::polkavm::Dependency;
use crate::polkavm_const::runtime_api;
/// Translates the `gas_limit` instruction.
pub fn gas_limit<'ctx, D>(
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
todo!()
}
/// Translates the `gas_price` instruction.
pub fn gas_price<'ctx, D>(
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
todo!()
}
/// Translates the `tx.origin` instruction.
pub fn origin<'ctx, D>(
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
todo!()
}
/// Translates the `chain_id` instruction.
pub fn chain_id<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
Ok(context.word_const(0).as_basic_value_enum())
}
/// Translates the `block_number` instruction.
pub fn block_number<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let (output_pointer, output_length_pointer) = context.build_stack_parameter(
revive_common::BIT_LENGTH_BLOCK_NUMBER,
"block_timestamp_output",
);
context.build_runtime_call(
runtime_api::imports::BLOCK_NUMBER,
&[
output_pointer.to_int(context).into(),
output_length_pointer.to_int(context).into(),
],
);
context.build_load_word(
output_pointer,
revive_common::BIT_LENGTH_BLOCK_NUMBER,
"block_number",
)
}
/// Translates the `block_timestamp` instruction.
pub fn block_timestamp<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let (output_pointer, output_length_pointer) = context.build_stack_parameter(
revive_common::BIT_LENGTH_BLOCK_TIMESTAMP,
"block_timestamp_output",
);
context.build_runtime_call(
runtime_api::imports::NOW,
&[
output_pointer.to_int(context).into(),
output_length_pointer.to_int(context).into(),
],
);
context.build_load_word(
output_pointer,
revive_common::BIT_LENGTH_BLOCK_TIMESTAMP,
"block_timestamp",
)
}
/// Translates the `block_hash` instruction.
pub fn block_hash<'ctx, D>(
_context: &mut Context<'ctx, D>,
_index: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
todo!()
}
/// Translates the `difficulty` instruction.
pub fn difficulty<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
Ok(context.word_const(2500000000000000).as_basic_value_enum())
}
/// Translates the `coinbase` instruction.
pub fn coinbase<'ctx, D>(
_context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
todo!()
}
/// Translates the `basefee` instruction.
pub fn basefee<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
Ok(context.word_const(0).as_basic_value_enum())
}
/// Translates the `msize` instruction.
pub fn msize<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let heap_end = context.build_sbrk(context.xlen_type().const_zero())?;
let heap_start = context
.get_global(crate::polkavm::GLOBAL_HEAP_MEMORY_POINTER)?
.value
.as_pointer_value();
let heap_size = context.builder().build_int_nuw_sub(
context
.builder()
.build_ptr_to_int(heap_end, context.xlen_type(), "heap_end")?,
context
.builder()
.build_ptr_to_int(heap_start, context.xlen_type(), "heap_start")?,
"heap_size",
)?;
Ok(context
.builder()
.build_int_z_extend(heap_size, context.word_type(), "heap_size_extended")?
.as_basic_value_enum())
}
/// Translates the `address` instruction.
pub fn address<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let (output_pointer, output_length_pointer) =
context.build_stack_parameter(revive_common::BIT_LENGTH_ETH_ADDRESS, "address_output");
context.build_runtime_call(
runtime_api::imports::ADDRESS,
&[
output_pointer.to_int(context).into(),
output_length_pointer.to_int(context).into(),
],
);
let value = context.build_byte_swap(context.build_load(output_pointer, "address")?)?;
Ok(context
.builder()
.build_int_z_extend(value.into_int_value(), context.word_type(), "address_zext")?
.into())
}
/// Translates the `caller` instruction.
pub fn caller<'ctx, D>(
context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where
D: Dependency + Clone,
{
let (output_pointer, output_length_pointer) =
context.build_stack_parameter(revive_common::BIT_LENGTH_ETH_ADDRESS, "caller_output");
context.build_runtime_call(
runtime_api::imports::CALLER,
&[
output_pointer.to_int(context).into(),
output_length_pointer.to_int(context).into(),
],
);
let value = context.build_byte_swap(context.build_load(output_pointer, "caller")?)?;
Ok(context
.builder()
.build_int_z_extend(value.into_int_value(), context.word_type(), "caller_zext")?
.into())
}