1 #pragma once 2 #include <string_view> 3 4 #define CHECK_ERR(err) \ 5 do { \ 6 if (err) { \ 7 auto msg = wasm_name_t{}; \ 8 wasmtime_error_message(err, &msg); \ 9 EXPECT_EQ(err, nullptr) << std::string_view{msg.data, msg.size}; \ 10 } \ 11 } while (false) 12 13 // From crates/component-util/src/lib.rs 14 inline constexpr std::string_view REALLOC_AND_FREE = 15 R"END( 16 (global $last (mut i32) (i32.const 8)) 17 (func $realloc (export "realloc") 18 (param $old_ptr i32) 19 (param $old_size i32) 20 (param $align i32) 21 (param $new_size i32) 22 (result i32) 23 24 (local $ret i32) 25 26 ;; Test if the old pointer is non-null 27 local.get $old_ptr 28 if 29 ;; If the old size is bigger than the new size then 30 ;; this is a shrink and transparently allow it 31 local.get $old_size 32 local.get $new_size 33 i32.gt_u 34 if 35 local.get $old_ptr 36 return 37 end 38 39 ;; otherwise fall through to allocate a new chunk which will later 40 ;; copy data over 41 end 42 43 ;; align up `$last` 44 (global.set $last 45 (i32.and 46 (i32.add 47 (global.get $last) 48 (i32.add 49 (local.get $align) 50 (i32.const -1))) 51 (i32.xor 52 (i32.add 53 (local.get $align) 54 (i32.const -1)) 55 (i32.const -1)))) 56 57 ;; save the current value of `$last` as the return value 58 global.get $last 59 local.set $ret 60 61 ;; bump our pointer 62 (global.set $last 63 (i32.add 64 (global.get $last) 65 (local.get $new_size))) 66 67 ;; while `memory.size` is less than `$last`, grow memory 68 ;; by one page 69 (loop $loop 70 (if 71 (i32.lt_u 72 (i32.mul (memory.size) (i32.const 65536)) 73 (global.get $last)) 74 (then 75 i32.const 1 76 memory.grow 77 ;; test to make sure growth succeeded 78 i32.const -1 79 i32.eq 80 if unreachable end 81 82 br $loop))) 83 84 85 ;; ensure anything necessary is set to valid data by spraying a bit 86 ;; pattern that is invalid 87 local.get $ret 88 i32.const 0xde 89 local.get $new_size 90 memory.fill 91 92 ;; If the old pointer is present then that means this was a reallocation 93 ;; of an existing chunk which means the existing data must be copied. 94 local.get $old_ptr 95 if 96 local.get $ret ;; destination 97 local.get $old_ptr ;; source 98 local.get $old_size ;; size 99 memory.copy 100 end 101 102 local.get $ret 103 ) 104 )END"; 105