From ab73d6c199f4e727ac11532b03f1f8d732497dc6 Mon Sep 17 00:00:00 2001 From: Tiago Carvalho Date: Mon, 31 Jul 2023 11:08:28 +0100 Subject: [PATCH] Fix wasm stack limiter unit tests on Apple silicon --- shared/src/vm/wasm/run.rs | 75 +++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 19 deletions(-) diff --git a/shared/src/vm/wasm/run.rs b/shared/src/vm/wasm/run.rs index 9ac4852eede..54a2942c044 100644 --- a/shared/src/vm/wasm/run.rs +++ b/shared/src/vm/wasm/run.rs @@ -485,24 +485,62 @@ mod tests { use crate::types::validity_predicate::EvalVp; use crate::vm::wasm; + /// Test the wasm stack limiter, with a function looping over N times, + /// consuming 5 stack frames per loop. + struct TestStackLimiter { + /// Number of loops in the test wasm that are required to trip + /// the stack limiter. + trip_over_limit_loops: u32, + /// Number of loops in the test wasm that make it up to the top of + /// the stack without tripping the limiter. + up_to_limit_loops: u32, + } + + impl TestStackLimiter { + const fn setup() -> Self { + // Because each call into `$loop` inside the wasm consumes 5 stack + // heights except for the terminal call, this should hit the stack + // limit. + let trip_over_limit_loops = WASM_STACK_LIMIT / 5 - 1; + + #[cfg(not(all(target_os = "macos", target_arch = "aarch64")))] + let up_to_limit_loops = { + // one less loop shouldn't go over the limit + trip_over_limit_loops - 1 + }; + + #[cfg(all(target_os = "macos", target_arch = "aarch64"))] + let up_to_limit_loops = { + // TODO: for some reaosn, with wasmer:df6aa26f (based on 2.3.0), + // less stack space is available(???) in the vm (around 200 + // bytes less than WASM_STACK_LIMIT) + trip_over_limit_loops - 38 + }; + + Self { + trip_over_limit_loops, + up_to_limit_loops, + } + } + } + /// Test that when a transaction wasm goes over the stack-height limit, the /// execution is aborted. #[test] fn test_tx_stack_limiter() { - // Because each call into `$loop` inside the wasm consumes 5 stack - // heights except for the terminal call, this should hit the stack - // limit. - let loops = WASM_STACK_LIMIT / 5 - 1; - - let error = loop_in_tx_wasm(loops).expect_err(&format!( - "Expecting runtime error \"unreachable\" caused by stack-height \ - overflow, loops {}. Got", - loops, - )); + let TestStackLimiter { + up_to_limit_loops, + trip_over_limit_loops, + } = TestStackLimiter::setup(); + + let error = + loop_in_tx_wasm(trip_over_limit_loops).expect_err(&format!( + "Expecting runtime error \"unreachable\" caused by \ + stack-height overflow, loops {trip_over_limit_loops}. Got", + )); assert_stack_overflow(&error); - // one less loop shouldn't go over the limit - let result = loop_in_tx_wasm(loops - 1); + let result = loop_in_tx_wasm(up_to_limit_loops); assert!(result.is_ok(), "Expected success. Got {:?}", result); } @@ -510,18 +548,17 @@ mod tests { /// is aborted. #[test] fn test_vp_stack_limiter() { - // Because each call into `$loop` inside the wasm consumes 5 stack - // heights except for the terminal call, this should hit the stack - // limit. - let loops = WASM_STACK_LIMIT / 5 - 1; + let TestStackLimiter { + up_to_limit_loops, + trip_over_limit_loops, + } = TestStackLimiter::setup(); - let error = loop_in_vp_wasm(loops).expect_err( + let error = loop_in_vp_wasm(trip_over_limit_loops).expect_err( "Expecting runtime error caused by stack-height overflow. Got", ); assert_stack_overflow(&error); - // one less loop shouldn't go over the limit - let result = loop_in_vp_wasm(loops - 1); + let result = loop_in_vp_wasm(up_to_limit_loops); assert!(result.is_ok(), "Expected success. Got {:?}", result); }