implement fuzzing for component types (#4537)
This addresses #4307. For the static API we generate 100 arbitrary test cases at build time, each of which includes 0-5 parameter types, a result type, and a WAT fragment containing an imported function and an exported function. The exported function calls the imported function, which is implemented by the host. At runtime, the fuzz test selects a test case at random and feeds it zero or more sets of arbitrary parameters and results, checking that values which flow host-to-guest and guest-to-host make the transition unchanged. The fuzz test for the dynamic API follows a similar pattern, the only difference being that test cases are generated at runtime. Signed-off-by: Joel Dice <joel.dice@fermyon.com>
This commit is contained in:
@@ -77,3 +77,62 @@ impl FlagsSize {
|
||||
fn ceiling_divide(n: usize, d: usize) -> usize {
|
||||
(n + d - 1) / d
|
||||
}
|
||||
|
||||
/// A simple bump allocator which can be used with modules
|
||||
pub const REALLOC_AND_FREE: &str = r#"
|
||||
(global $last (mut i32) (i32.const 8))
|
||||
(func $realloc (export "realloc")
|
||||
(param $old_ptr i32)
|
||||
(param $old_size i32)
|
||||
(param $align i32)
|
||||
(param $new_size i32)
|
||||
(result i32)
|
||||
|
||||
;; Test if the old pointer is non-null
|
||||
local.get $old_ptr
|
||||
if
|
||||
;; If the old size is bigger than the new size then
|
||||
;; this is a shrink and transparently allow it
|
||||
local.get $old_size
|
||||
local.get $new_size
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $old_ptr
|
||||
return
|
||||
end
|
||||
|
||||
;; ... otherwise this is unimplemented
|
||||
unreachable
|
||||
end
|
||||
|
||||
;; align up `$last`
|
||||
(global.set $last
|
||||
(i32.and
|
||||
(i32.add
|
||||
(global.get $last)
|
||||
(i32.add
|
||||
(local.get $align)
|
||||
(i32.const -1)))
|
||||
(i32.xor
|
||||
(i32.add
|
||||
(local.get $align)
|
||||
(i32.const -1))
|
||||
(i32.const -1))))
|
||||
|
||||
;; save the current value of `$last` as the return value
|
||||
global.get $last
|
||||
|
||||
;; ensure anything necessary is set to valid data by spraying a bit
|
||||
;; pattern that is invalid
|
||||
global.get $last
|
||||
i32.const 0xde
|
||||
local.get $new_size
|
||||
memory.fill
|
||||
|
||||
;; bump our pointer
|
||||
(global.set $last
|
||||
(i32.add
|
||||
(global.get $last)
|
||||
(local.get $new_size)))
|
||||
)
|
||||
"#;
|
||||
|
||||
Reference in New Issue
Block a user