(config: &mut Config)
| 122 | |
| 123 | #[wasmtime_test] |
| 124 | fn big_stack_works_ok(config: &mut Config) -> Result<()> { |
| 125 | // This test takes 1m+ in ASAN and isn't too useful, so prune it. |
| 126 | if cfg!(asan) { |
| 127 | return Ok(()); |
| 128 | } |
| 129 | |
| 130 | const N: usize = 10000; |
| 131 | |
| 132 | // Build a module with a function that uses a very large amount of stack space, |
| 133 | // modeled here by calling an i64-returning-function many times followed by |
| 134 | // adding them all into one i64. |
| 135 | // |
| 136 | // This should exercise the ability to consume multi-page stacks and |
| 137 | // only touch a few internals of it at a time. |
| 138 | let mut s = String::new(); |
| 139 | s.push_str("(module\n"); |
| 140 | s.push_str("(func (export \"\") (result i64)\n"); |
| 141 | s.push_str("i64.const 0\n"); |
| 142 | for _ in 0..N { |
| 143 | s.push_str("call $get\n"); |
| 144 | } |
| 145 | for _ in 0..N { |
| 146 | s.push_str("i64.add\n"); |
| 147 | } |
| 148 | s.push_str(")\n"); |
| 149 | s.push_str("(func $get (result i64) i64.const 0)\n"); |
| 150 | s.push_str(")\n"); |
| 151 | |
| 152 | // Disable cranelift optimizations to ensure that this test doesn't take too |
| 153 | // long in debug mode due to the large size of its code. |
| 154 | config.cranelift_opt_level(OptLevel::None); |
| 155 | config.cranelift_regalloc_algorithm(RegallocAlgorithm::SinglePass); |
| 156 | let engine = Engine::new(config)?; |
| 157 | |
| 158 | let mut store = Store::new(&engine, ()); |
| 159 | let module = Module::new(store.engine(), &s)?; |
| 160 | let instance = Instance::new(&mut store, &module, &[])?; |
| 161 | let func = instance.get_typed_func::<(), i64>(&mut store, "")?; |
| 162 | assert_eq!(func.call(&mut store, ())?, 0); |
| 163 | Ok(()) |
| 164 | } |
| 165 | |
| 166 | #[test] |
| 167 | fn infinite_wasm_stack_does_not_panic() -> Result<()> { |
nothing calls this directly
no test coverage detected