Skip to content

Commit

Permalink
Fix wasm stack limiter unit tests on Apple silicon
Browse files Browse the repository at this point in the history
  • Loading branch information
sug0 committed Jul 31, 2023
1 parent 33c7016 commit ab73d6c
Showing 1 changed file with 56 additions and 19 deletions.
75 changes: 56 additions & 19 deletions shared/src/vm/wasm/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,43 +485,80 @@ 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);
}

/// Test that when a VP wasm goes over the stack-height limit, the execution
/// 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);
}

Expand Down

0 comments on commit ab73d6c

Please sign in to comment.