diff --git a/crates/llvm-context/src/eravm/context/mod.rs b/crates/llvm-context/src/eravm/context/mod.rs index 67c2724..e76d3d6 100644 --- a/crates/llvm-context/src/eravm/context/mod.rs +++ b/crates/llvm-context/src/eravm/context/mod.rs @@ -119,6 +119,9 @@ where /// The loop stack default capacity. const LOOP_STACK_INITIAL_CAPACITY: usize = 16; + /// The PolkaVM minimum stack size. + const POLKAVM_STACK_SIZE: u32 = 0x4000; + /// Link in the stdlib module. fn link_stdlib_module( llvm: &'ctx inkwell::context::Context, @@ -161,6 +164,21 @@ where } } + /// Configure the PolkaVM minimum stack size. + fn set_polkavm_stack_size( + llvm: &'ctx inkwell::context::Context, + module: &inkwell::module::Module<'ctx>, + size: u32, + ) { + module + .link_in_module(pallet_contracts_pvm_llapi::min_stack_size( + llvm, + "polkavm_stack_size", + size, + )) + .expect("the PolkaVM minimum stack size module should be linkable"); + } + /// PolkaVM wants PIE code; we set this flag on the module here. fn set_module_flags( llvm: &'ctx inkwell::context::Context, @@ -186,6 +204,7 @@ where ) -> Self { Self::link_stdlib_module(llvm, &module); Self::link_polkavm_guest_module(llvm, &module); + Self::set_polkavm_stack_size(llvm, &module, Self::POLKAVM_STACK_SIZE); Self::set_module_flags(llvm, &module); let intrinsics = Intrinsics::new(llvm, &module); diff --git a/crates/pallet-contracts-pvm-llapi/src/lib.rs b/crates/pallet-contracts-pvm-llapi/src/lib.rs index 6e9217f..ebfc5bb 100644 --- a/crates/pallet-contracts-pvm-llapi/src/lib.rs +++ b/crates/pallet-contracts-pvm-llapi/src/lib.rs @@ -28,6 +28,21 @@ pub fn module<'context>( Module::parse_bitcode_from_buffer(&buf, context) } +/// Creates a module that sets the PolkaVM minimum stack size to [`size`] if linked in. +pub fn min_stack_size<'context>( + context: &'context Context, + module_name: &str, + size: u32, +) -> Module<'context> { + let module = context.create_module(module_name); + module.set_inline_assembly(&format!( + ".pushsection .polkavm_min_stack_size,\"\",@progbits + .word {size} + .popsection" + )); + module +} + #[cfg(test)] mod tests { #[test]