Updated call semantics (#56)

- Update pallet-revive dependency
- Implement calls according to pallet-revive call semantics
- Switch to the new return data API in pallet revive and get rid of return data buffer
- Remove a bunch of resulting dead code
This commit is contained in:
Cyrill Leutwiler
2024-09-28 20:03:03 +02:00
committed by GitHub
parent 066acc4663
commit 6585973e99
24 changed files with 1001 additions and 886 deletions
+21 -47
View File
@@ -3,7 +3,7 @@ use inkwell::{
context::Context,
module::Module,
types::{BasicType, StructType},
values::{BasicValue, PointerValue},
values::{BasicValueEnum, PointerValue},
};
/// Creates a module that sets the PolkaVM minimum stack size to [`size`] if linked in.
@@ -21,56 +21,33 @@ pub fn min_stack_size<'context>(
module
}
pub struct Spill<'a, 'ctx> {
/// Helper for building function calls with stack spilled arguments.
/// - `pointer`: points to a struct of the packed argument struct type
/// - `type`: the packed argument struct type
/// - `arguments`: a correctly ordered list of the struct field values
pub fn spill<'ctx>(
builder: &Builder<'ctx>,
pointer: PointerValue<'ctx>,
builder: &'a Builder<'ctx>,
r#type: StructType<'ctx>,
current_field: u32,
}
impl<'a, 'ctx> Spill<'a, 'ctx> {
pub fn new(
builder: &'a Builder<'ctx>,
r#type: StructType<'ctx>,
name: &str,
) -> anyhow::Result<Self> {
Ok(Self {
pointer: builder.build_alloca(r#type, name)?,
builder,
arguments: &[BasicValueEnum<'ctx>],
) -> anyhow::Result<()> {
for index in 0..r#type.get_field_types().len() {
let field_pointer = builder.build_struct_gep(
r#type,
current_field: 0,
})
}
pub fn next<V: BasicValue<'ctx>>(mut self, value: V) -> anyhow::Result<Self> {
let field_pointer = self.builder.build_struct_gep(
self.r#type,
self.pointer,
self.current_field,
&format!("spill_parameter_{}", self.current_field),
pointer,
index as u32,
&format!("spill_parameter_{}", index),
)?;
self.builder.build_store(field_pointer, value)?;
self.current_field += 1;
Ok(self)
let field_value = arguments
.get(index)
.ok_or_else(|| anyhow::anyhow!("invalid index {index} for struct type {}", r#type))?;
builder.build_store(field_pointer, *field_value)?;
}
pub fn skip(mut self) -> Self {
self.current_field += 1;
self
}
pub fn done(self) -> PointerValue<'ctx> {
assert!(
self.r#type
.get_field_type_at_index(self.current_field)
.is_none(),
"there must not be any missing parameters"
);
self.pointer
}
Ok(())
}
/// Returns a packed struct argument type for the `instantiate` API.
pub fn instantiate(context: &Context) -> StructType {
context.struct_type(
&[
@@ -90,21 +67,18 @@ pub fn instantiate(context: &Context) -> StructType {
context.i32_type().as_basic_type_enum(),
// address_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(),
// address_len_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(),
// output_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(),
// output_len_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(),
// salt_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(),
// salt_len: u32
context.i32_type().as_basic_type_enum(),
],
true,
)
}
/// Returns a packed struct argument type for the `call` API.
pub fn call(context: &Context) -> StructType {
context.struct_type(
&[
+3 -1
View File
@@ -55,7 +55,9 @@ POLKAVM_IMPORT(void, input, uint32_t, uint32_t)
POLKAVM_IMPORT(void, seal_return, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(void, returndatacopy, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(void, return_data_copy, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(void, return_data_size, uint32_t)
POLKAVM_IMPORT(void, value_transferred, uint32_t)