Skip to content

Commit

Permalink
Move all tests out of cranelift-wasm (#8147)
Browse files Browse the repository at this point in the history
* Move remaining `*.wat` tests out of cranelift-wasm/wasmtests

Move these up to Wasmtime's misc testsuite to get translated and
instantiated by Wasmtime.

Note that the max-function-index-in-name-section test was removed here
as that's tested by the support added in #3509.

* Remove cranelift-wasm test for name section

This is pretty thoroughly tested elsewhere in Wasmtime that we respect
the name section, for example many of the trap tests assert that the
name of the function comes from the text format.

* Move reachability tests out of cranelift-wasm

Instead add them to the disassembly test suite to ensure we don't
generate dead code. Additionally this has a lot of coverage via fuzzing
too.

* Move more tests out of cranelift-wasm

Move them into `tests/disas` so we can easily see the CLIF.
  • Loading branch information
alexcrichton authored Mar 15, 2024
1 parent 375a3bd commit 27153d0
Show file tree
Hide file tree
Showing 10 changed files with 273 additions and 298 deletions.
136 changes: 0 additions & 136 deletions cranelift/wasm/src/func_translator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,139 +294,3 @@ fn cur_srcloc(reader: &BinaryReader) -> ir::SourceLoc {
// This will wrap around if byte code is larger than 4 GB.
ir::SourceLoc::new(reader.original_position() as u32)
}

#[cfg(test)]
mod tests {
use super::FuncTranslator;
use crate::environ::DummyEnvironment;
use cranelift_codegen::ir::types::I32;
use cranelift_codegen::{ir, isa, settings, Context};
use log::debug;
use target_lexicon::PointerWidth;
use wasmparser::{
FuncValidator, FunctionBody, Parser, ValidPayload, Validator, ValidatorResources,
};

#[test]
fn small1() {
// Implicit return.
let wasm = wat::parse_str(
"
(module
(func $small2 (param i32) (result i32)
(i32.add (local.get 0) (i32.const 1))
)
)
",
)
.unwrap();

let mut trans = FuncTranslator::new();
let flags = settings::Flags::new(settings::builder());
let runtime = DummyEnvironment::new(isa::TargetFrontendConfig {
default_call_conv: isa::CallConv::Fast,
pointer_width: PointerWidth::U64,
});

let mut ctx = Context::new();

ctx.func.name = ir::UserFuncName::testcase("small1");
ctx.func.signature.params.push(ir::AbiParam::new(I32));
ctx.func.signature.returns.push(ir::AbiParam::new(I32));

let (body, mut validator) = extract_func(&wasm);
trans
.translate_body(&mut validator, body, &mut ctx.func, &mut runtime.func_env())
.unwrap();
debug!("{}", ctx.func.display());
ctx.verify(&flags).unwrap();
}

#[test]
fn small2() {
// Same as above, but with an explicit return instruction.
let wasm = wat::parse_str(
"
(module
(func $small2 (param i32) (result i32)
(return (i32.add (local.get 0) (i32.const 1)))
)
)
",
)
.unwrap();

let mut trans = FuncTranslator::new();
let flags = settings::Flags::new(settings::builder());
let runtime = DummyEnvironment::new(isa::TargetFrontendConfig {
default_call_conv: isa::CallConv::Fast,
pointer_width: PointerWidth::U64,
});

let mut ctx = Context::new();

ctx.func.name = ir::UserFuncName::testcase("small2");
ctx.func.signature.params.push(ir::AbiParam::new(I32));
ctx.func.signature.returns.push(ir::AbiParam::new(I32));

let (body, mut validator) = extract_func(&wasm);
trans
.translate_body(&mut validator, body, &mut ctx.func, &mut runtime.func_env())
.unwrap();
debug!("{}", ctx.func.display());
ctx.verify(&flags).unwrap();
}

#[test]
fn infloop() {
// An infinite loop, no return instructions.
let wasm = wat::parse_str(
"
(module
(func $infloop (result i32)
(local i32)
(loop (result i32)
(i32.add (local.get 0) (i32.const 1))
(local.set 0)
(br 0)
)
)
)
",
)
.unwrap();

let mut trans = FuncTranslator::new();
let flags = settings::Flags::new(settings::builder());
let runtime = DummyEnvironment::new(isa::TargetFrontendConfig {
default_call_conv: isa::CallConv::Fast,
pointer_width: PointerWidth::U64,
});

let mut ctx = Context::new();

ctx.func.name = ir::UserFuncName::testcase("infloop");
ctx.func.signature.returns.push(ir::AbiParam::new(I32));

let (body, mut validator) = extract_func(&wasm);
trans
.translate_body(&mut validator, body, &mut ctx.func, &mut runtime.func_env())
.unwrap();
debug!("{}", ctx.func.display());
ctx.verify(&flags).unwrap();
}

fn extract_func(wat: &[u8]) -> (FunctionBody<'_>, FuncValidator<ValidatorResources>) {
let mut validator = Validator::new();
for payload in Parser::new(0).parse_all(wat) {
match validator.payload(&payload.unwrap()).unwrap() {
ValidPayload::Func(validator, body) => {
let validator = validator.into_validator(Default::default());
return (body, validator);
}
_ => {}
}
}
panic!("failed to find function");
}
}
153 changes: 0 additions & 153 deletions cranelift/wasm/tests/wasm_testsuite.rs

This file was deleted.

Binary file not shown.
91 changes: 91 additions & 0 deletions tests/disas/dead-code.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
;;! target = "x86_64"

(module
(func (param i32)
(loop
(block
local.get 0
br_if 0
br 1)))

(func (param i32)
(loop
(block
br 1
call $empty)))

(func $empty)

(func (param i32) (result i32)
i32.const 1
return
i32.const 42)
)
;; function u0:0(i64 vmctx, i64, i32) fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly gv0+8
;; gv2 = load.i64 notrap aligned gv1
;; sig0 = (i64 vmctx, i32 uext, i32 uext) -> i32 uext system_v
;; sig1 = (i64 vmctx, i32 uext) -> i32 uext system_v
;; stack_limit = gv2
;;
;; block0(v0: i64, v1: i64, v2: i32):
;; v3 -> v2
;; @0023 jump block2
;;
;; block2:
;; @0029 brif.i32 v3, block4, block5
;;
;; block5:
;; @002b jump block2
;;
;; block4:
;; @002e jump block3
;;
;; block3:
;; @002f jump block1
;;
;; block1:
;; @002f return
;; }
;;
;; function u0:1(i64 vmctx, i64, i32) fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly gv0+8
;; gv2 = load.i64 notrap aligned gv1
;; stack_limit = gv2
;;
;; block0(v0: i64, v1: i64, v2: i32):
;; @0032 jump block2
;;
;; block2:
;; @0036 jump block2
;; }
;;
;; function u0:2(i64 vmctx, i64) fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly gv0+8
;; gv2 = load.i64 notrap aligned gv1
;; sig0 = (i64 vmctx, i32 uext, i32 uext) -> i32 uext system_v
;; sig1 = (i64 vmctx, i32 uext) -> i32 uext system_v
;; stack_limit = gv2
;;
;; block0(v0: i64, v1: i64):
;; @003f jump block1
;;
;; block1:
;; @003f return
;; }
;;
;; function u0:3(i64 vmctx, i64, i32) -> i32 fast {
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly gv0+8
;; gv2 = load.i64 notrap aligned gv1
;; sig0 = (i64 vmctx, i32 uext, i32 uext) -> i32 uext system_v
;; sig1 = (i64 vmctx, i32 uext) -> i32 uext system_v
;; stack_limit = gv2
;;
;; block0(v0: i64, v1: i64, v2: i32):
;; @0042 v4 = iconst.i32 1
;; @0044 return v4 ; v4 = 1
;; }
Loading

0 comments on commit 27153d0

Please sign in to comment.