| 72 | // Call a func that turns a `list<u8>` into a `string`, to ensure that `realloc` calls are counted. |
| 73 | #[test] |
| 74 | fn call_func_with_realloc() -> Result<()> { |
| 75 | let wat = format!( |
| 76 | r#"(component |
| 77 | (core module $m |
| 78 | (memory (export "memory") 1) |
| 79 | (func (export "roundtrip") (param i32 i32) (result i32) |
| 80 | (local $base i32) |
| 81 | (local.set $base |
| 82 | (call $realloc |
| 83 | (i32.const 0) |
| 84 | (i32.const 0) |
| 85 | (i32.const 4) |
| 86 | (i32.const 8))) |
| 87 | (i32.store offset=0 |
| 88 | (local.get $base) |
| 89 | (local.get 0)) |
| 90 | (i32.store offset=4 |
| 91 | (local.get $base) |
| 92 | (local.get 1)) |
| 93 | (local.get $base) |
| 94 | ) |
| 95 | |
| 96 | {REALLOC_AND_FREE} |
| 97 | ) |
| 98 | (core instance $i (instantiate $m)) |
| 99 | |
| 100 | (func (export "list8-to-str") (param "a" (list u8)) (result string) |
| 101 | (canon lift |
| 102 | (core func $i "roundtrip") |
| 103 | (memory $i "memory") |
| 104 | (realloc (func $i "realloc")) |
| 105 | ) |
| 106 | ) |
| 107 | )"# |
| 108 | ); |
| 109 | |
| 110 | let engine = Engine::default(); |
| 111 | let component = Component::new(&engine, wat)?; |
| 112 | let linker = Linker::<State>::new(&engine); |
| 113 | let mut store = Store::new(&engine, State::default()); |
| 114 | store.call_hook(sync_call_hook); |
| 115 | let inst = linker |
| 116 | .instantiate(&mut store, &component) |
| 117 | .expect("instantiate"); |
| 118 | |
| 119 | let export = inst |
| 120 | .get_typed_func::<(&[u8],), (WasmStr,)>(&mut store, "list8-to-str") |
| 121 | .expect("looking up `list8-to-str`"); |
| 122 | |
| 123 | let message = String::from("hello, world!"); |
| 124 | let res = export.call(&mut store, (message.as_bytes(),))?.0; |
| 125 | let result = res.to_str(&store)?; |
| 126 | assert_eq!(&message, &result); |
| 127 | |
| 128 | // There are two wasm calls for the `list8-to-str` call and the guest realloc call for the list |
| 129 | // argument. |
| 130 | let s = store.into_data(); |
| 131 | assert_eq!(s.calls_into_host, 0); |