Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
Cyrill Leutwiler
2025-04-17 12:43:26 +02:00
parent cf2fd2f1e8
commit 52bf16a383
13 changed files with 112 additions and 46 deletions
+48 -14
View File
@@ -773,27 +773,49 @@ where
.into())
}
/// Builds a stack load instruction.
/// Builds a stack load instruction with a direct assignment.
/// Sets the alignment to 256 bits for the stack and 1 bit for the heap, parent, and child.
pub fn build_load(
pub fn build_load_assign(
&self,
pointer: Pointer<'ctx>,
name: &str,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>> {
assignment_pointer: &mut Option<inkwell::values::PointerValue<'ctx>>,
) -> anyhow::Result<Option<inkwell::values::BasicValueEnum<'ctx>>> {
match pointer.address_space {
AddressSpace::Heap => {
let name = <PolkaVMLoadHeapWordFunction as RuntimeFunction<D>>::NAME;
let declaration =
<PolkaVMLoadHeapWordFunction as RuntimeFunction<D>>::declaration(self);
let arguments = [self
.builder()
.build_ptr_to_int(pointer.value, self.xlen_type(), "offset_ptrtoint")?
.as_basic_value_enum()];
Ok(self
.build_call(declaration, &arguments, "heap_load")
.unwrap_or_else(|| {
panic!("revive runtime function {name} should return a value")
}))
match assignment_pointer.take() {
Some(assignment_pointer) => {
let arguments = [
self.builder()
.build_ptr_to_int(
pointer.value,
self.xlen_type(),
"offset_ptrtoint",
)?
.as_basic_value_enum(),
assignment_pointer.into(),
];
self.build_call(declaration, &arguments, "heap_load");
Ok(None)
}
None => {
let pointer = self.build_alloca_at_entry(self.word_type(), "pointer");
let arguments = [
self.builder()
.build_ptr_to_int(
pointer.value,
self.xlen_type(),
"offset_ptrtoint",
)?
.as_basic_value_enum(),
pointer.value.into(),
];
self.build_call(declaration, &arguments, "heap_load");
Ok(Some(self.build_load(pointer, "storage_value")?))
}
}
}
AddressSpace::Stack => {
let value = self
@@ -806,11 +828,23 @@ where
.set_alignment(revive_common::BYTE_LENGTH_STACK_ALIGN as u32)
.expect("Alignment is valid");
Ok(value)
Ok(Some(value))
}
}
}
/// Builds a stack load instruction.
/// Sets the alignment to 256 bits for the stack and 1 bit for the heap, parent, and child.
pub fn build_load(
&self,
pointer: Pointer<'ctx>,
name: &str,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>> {
Ok(self
.build_load_assign(pointer, name, &mut None)?
.expect("without an assignment pointer loads return a value"))
}
/// Builds a stack store instruction.
/// Sets the alignment to 256 bits for the stack and 1 bit for the heap, parent, and child.
pub fn build_store<V>(&self, pointer: Pointer<'ctx>, value: V) -> anyhow::Result<()>
@@ -2,6 +2,8 @@
use inkwell::values::BasicValueEnum;
use crate::polkavm::context::address_space::AddressSpace;
use crate::polkavm::context::pointer::Pointer;
use crate::polkavm::context::runtime::RuntimeFunction;
use crate::polkavm::context::Context;
use crate::polkavm::Dependency;
@@ -17,9 +19,13 @@ where
const NAME: &'static str = "__revive_load_heap_word";
fn r#type<'ctx>(context: &Context<'ctx, D>) -> inkwell::types::FunctionType<'ctx> {
context
.word_type()
.fn_type(&[context.xlen_type().into()], false)
context.void_type().fn_type(
&[
context.xlen_type().into(),
context.llvm().ptr_type(Default::default()).into(),
],
false,
)
}
fn emit_body<'ctx>(
@@ -27,6 +33,7 @@ where
context: &mut Context<'ctx, D>,
) -> anyhow::Result<Option<BasicValueEnum<'ctx>>> {
let offset = Self::paramater(context, 0).into_int_value();
let assignment_pointer = Self::paramater(context, 1).into_pointer_value();
let length = context
.xlen_type()
.const_int(revive_common::BYTE_LENGTH_WORD as u64, false);
@@ -42,7 +49,11 @@ where
.expect("Alignment is valid");
let swapped_value = context.build_byte_swap(value)?;
Ok(Some(swapped_value))
context.build_store(
Pointer::new(context.word_type(), AddressSpace::Stack, assignment_pointer),
swapped_value,
)?;
Ok(None)
}
}
@@ -29,7 +29,8 @@ where
pub fn load<'ctx, D>(
context: &mut Context<'ctx, D>,
offset: inkwell::values::IntValue<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
assignment_pointer: &mut Option<inkwell::values::PointerValue<'ctx>>,
) -> anyhow::Result<Option<inkwell::values::BasicValueEnum<'ctx>>>
where
D: Dependency + Clone,
{
@@ -40,7 +41,7 @@ where
offset,
"memory_load_pointer",
);
context.build_load(pointer, "memory_load_result")
context.build_load_assign(pointer, "memory_load_result", assignment_pointer)
}
/// Translates the `mstore` instruction.
@@ -13,14 +13,14 @@ use crate::PolkaVMStoreTransientStorageWordFunction;
pub fn load<'ctx, D>(
context: &mut Context<'ctx, D>,
position: &PolkaVMArgument<'ctx>,
assignment_pointer: Option<inkwell::values::PointerValue<'ctx>>,
assignment_pointer: &mut Option<inkwell::values::PointerValue<'ctx>>,
) -> anyhow::Result<Option<inkwell::values::BasicValueEnum<'ctx>>>
where
D: Dependency + Clone,
{
let _name = <PolkaVMLoadStorageWordFunction as RuntimeFunction<D>>::NAME;
let declaration = <PolkaVMLoadStorageWordFunction as RuntimeFunction<D>>::declaration(context);
match assignment_pointer {
match assignment_pointer.take() {
Some(assignment_pointer) => {
let arguments = [
position.as_pointer(context)?.value.into(),