diff --git a/substrate/client/executor/runtime-test/src/lib.rs b/substrate/client/executor/runtime-test/src/lib.rs index 115683bffa..0cfa06a94c 100644 --- a/substrate/client/executor/runtime-test/src/lib.rs +++ b/substrate/client/executor/runtime-test/src/lib.rs @@ -39,6 +39,14 @@ extern "C" { /// the initialized value at the start of a runtime call. static mut MUTABLE_STATIC: u64 = 32; +#[cfg(not(feature = "std"))] +/// This is similar to `MUTABLE_STATIC`. The tests need `MUTABLE_STATIC` for testing that +/// non-null initialization data is properly restored during instance reusing. +/// +/// `MUTABLE_STATIC_BSS` on the other hand focuses on the zeroed data. This is important since there +/// may be differences in handling zeroed and non-zeroed data. +static mut MUTABLE_STATIC_BSS: u64 = 0; + sp_core::wasm_export_functions! { fn test_calling_missing_external() { unsafe { missing_external() } @@ -309,6 +317,13 @@ sp_core::wasm_export_functions! { } } + fn returns_mutable_static_bss() -> u64 { + unsafe { + MUTABLE_STATIC_BSS += 1; + MUTABLE_STATIC_BSS + } + } + fn allocates_huge_stack_array(trap: bool) -> Vec { // Allocate a stack frame that is approx. 75% of the stack (assuming it is 1MB). // This will just decrease (stacks in wasm32-u-u grow downwards) the stack diff --git a/substrate/client/executor/src/integration_tests/mod.rs b/substrate/client/executor/src/integration_tests/mod.rs index 8c8674fc3c..0762306309 100644 --- a/substrate/client/executor/src/integration_tests/mod.rs +++ b/substrate/client/executor/src/integration_tests/mod.rs @@ -588,6 +588,25 @@ fn returns_mutable_static(wasm_method: WasmExecutionMethod) { assert_eq!(33, u64::decode(&mut &res[..]).unwrap()); } +test_wasm_execution!(returns_mutable_static_bss); +fn returns_mutable_static_bss(wasm_method: WasmExecutionMethod) { + let runtime = mk_test_runtime(wasm_method, 1024); + + let instance = runtime.new_instance().unwrap(); + let res = instance + .call_export("returns_mutable_static_bss", &[0]) + .unwrap(); + assert_eq!(1, u64::decode(&mut &res[..]).unwrap()); + + // We expect that every invocation will need to return the initial + // value plus one. If the value increases more than that then it is + // a sign that the wasm runtime preserves the memory content. + let res = instance + .call_export("returns_mutable_static_bss", &[0]) + .unwrap(); + assert_eq!(1, u64::decode(&mut &res[..]).unwrap()); +} + // If we didn't restore the wasm instance properly, on a trap the stack pointer would not be // returned to its initial value and thus the stack space is going to be leaked. //