//! Translates the calldata instructions. use crate::polkavm::context::address_space::AddressSpace; use crate::polkavm::context::pointer::Pointer; use crate::polkavm::context::Context; use crate::polkavm::Dependency; use inkwell::types::BasicType; /// Translates the calldata load. pub fn load<'ctx, D>( context: &mut Context<'ctx, D>, offset: inkwell::values::IntValue<'ctx>, ) -> anyhow::Result> where D: Dependency + Clone, { let calldata_pointer = context .get_global(crate::polkavm::GLOBAL_CALLDATA_POINTER)? .value .as_pointer_value(); let offset = context.build_gep( Pointer::new(context.byte_type(), AddressSpace::Stack, calldata_pointer), &[offset], context.word_type().as_basic_type_enum(), "calldata_pointer_with_offset", ); context .build_load(offset, "calldata_value") .and_then(|value| context.build_byte_swap(value)) } /// Translates the calldata size. pub fn size<'ctx, D>( context: &mut Context<'ctx, D>, ) -> anyhow::Result> where D: Dependency + Clone, { let value = context.get_global_value(crate::polkavm::GLOBAL_CALLDATA_SIZE)?; Ok(value) } /// Translates the calldata copy. pub fn 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<()> where D: Dependency + Clone, { let offset = context.safe_truncate_int_to_xlen(destination_offset)?; let size = context.safe_truncate_int_to_xlen(size)?; let destination = context.build_heap_gep(offset, size)?; let calldata_pointer = context .get_global(crate::polkavm::GLOBAL_CALLDATA_POINTER)? .value .as_pointer_value(); let source = context.build_gep( Pointer::new(context.byte_type(), AddressSpace::Stack, calldata_pointer), &[context.safe_truncate_int_to_xlen(source_offset)?], context.byte_type(), "calldata_pointer_with_offset", ); context.build_memcpy(destination, source, size, "calldata_copy_memcpy_from_child") }