@ -14,9 +14,11 @@ pub mod dummy;
use dummy ::{ dummy_imports , dummy_values } ;
use dummy ::{ dummy_imports , dummy_values } ;
use std ::collections ::{ HashMap , HashSet } ;
use std ::collections ::{ HashMap , HashSet } ;
use std ::sync ::atomic ::{ AtomicUsize , Ordering ::SeqCst } ;
use wasmtime ::* ;
use wasmtime ::* ;
fn fuzz_default_config ( strategy : Strategy ) -> Config {
fn fuzz_default_config ( strategy : Strategy ) -> Config {
drop ( env_logger ::try_init ( ) ) ;
let mut config = Config ::new ( ) ;
let mut config = Config ::new ( ) ;
config
config
. cranelift_debug_verifier ( true )
. cranelift_debug_verifier ( true )
@ -26,6 +28,22 @@ fn fuzz_default_config(strategy: Strategy) -> Config {
return config ;
return config ;
}
}
fn log_wasm ( wasm : & [ u8 ] ) {
static CNT : AtomicUsize = AtomicUsize ::new ( 0 ) ;
if ! log ::log_enabled ! ( log ::Level ::Debug ) {
return ;
}
let i = CNT . fetch_add ( 1 , SeqCst ) ;
let name = format ! ( "testcase{}.wasm" , i ) ;
std ::fs ::write ( & name , wasm ) . expect ( "failed to write wasm file" ) ;
log ::debug ! ( "wrote wasm file to `{}`" , name ) ;
if let Ok ( s ) = wasmprinter ::print_bytes ( wasm ) {
let name = format ! ( "testcase{}.wat" , i ) ;
std ::fs ::write ( & name , s ) . expect ( "failed to write wat file" ) ;
}
}
/// Instantiate the Wasm buffer, and implicitly fail if we have an unexpected
/// Instantiate the Wasm buffer, and implicitly fail if we have an unexpected
/// panic or segfault or anything else that can be detected "passively".
/// panic or segfault or anything else that can be detected "passively".
///
///
@ -46,6 +64,7 @@ pub fn instantiate_with_config(wasm: &[u8], config: Config) {
let engine = Engine ::new ( & config ) ;
let engine = Engine ::new ( & config ) ;
let store = Store ::new ( & engine ) ;
let store = Store ::new ( & engine ) ;
log_wasm ( wasm ) ;
let module = match Module ::new ( & store , wasm ) {
let module = match Module ::new ( & store , wasm ) {
Ok ( module ) = > module ,
Ok ( module ) = > module ,
Err ( _ ) = > return ,
Err ( _ ) = > return ,
@ -77,6 +96,7 @@ pub fn instantiate_with_config(wasm: &[u8], config: Config) {
pub fn compile ( wasm : & [ u8 ] , strategy : Strategy ) {
pub fn compile ( wasm : & [ u8 ] , strategy : Strategy ) {
let engine = Engine ::new ( & fuzz_default_config ( strategy ) ) ;
let engine = Engine ::new ( & fuzz_default_config ( strategy ) ) ;
let store = Store ::new ( & engine ) ;
let store = Store ::new ( & engine ) ;
log_wasm ( wasm ) ;
let _ = Module ::new ( & store , wasm ) ;
let _ = Module ::new ( & store , wasm ) ;
}
}
@ -88,6 +108,7 @@ pub fn differential_execution(
ttf : & crate ::generators ::WasmOptTtf ,
ttf : & crate ::generators ::WasmOptTtf ,
configs : & [ crate ::generators ::DifferentialConfig ] ,
configs : & [ crate ::generators ::DifferentialConfig ] ,
) {
) {
drop ( env_logger ::try_init ( ) ) ;
// We need at least two configs.
// We need at least two configs.
if configs . len ( ) < 2
if configs . len ( ) < 2
// And all the configs should be unique.
// And all the configs should be unique.
@ -104,6 +125,7 @@ pub fn differential_execution(
} ;
} ;
let mut export_func_results : HashMap < String , Result < Box < [ Val ] > , Trap > > = Default ::default ( ) ;
let mut export_func_results : HashMap < String , Result < Box < [ Val ] > , Trap > > = Default ::default ( ) ;
log_wasm ( & ttf . wasm ) ;
for config in & configs {
for config in & configs {
let engine = Engine ::new ( config ) ;
let engine = Engine ::new ( config ) ;
@ -258,6 +280,8 @@ fn assert_same_export_func_result(
pub fn make_api_calls ( api : crate ::generators ::api ::ApiCalls ) {
pub fn make_api_calls ( api : crate ::generators ::api ::ApiCalls ) {
use crate ::generators ::api ::ApiCall ;
use crate ::generators ::api ::ApiCall ;
drop ( env_logger ::try_init ( ) ) ;
let mut config : Option < Config > = None ;
let mut config : Option < Config > = None ;
let mut engine : Option < Engine > = None ;
let mut engine : Option < Engine > = None ;
let mut store : Option < Store > = None ;
let mut store : Option < Store > = None ;
@ -267,6 +291,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) {
for call in api . calls {
for call in api . calls {
match call {
match call {
ApiCall ::ConfigNew = > {
ApiCall ::ConfigNew = > {
log ::trace ! ( "creating config" ) ;
assert ! ( config . is_none ( ) ) ;
assert ! ( config . is_none ( ) ) ;
let mut cfg = Config ::new ( ) ;
let mut cfg = Config ::new ( ) ;
cfg . cranelift_debug_verifier ( true ) ;
cfg . cranelift_debug_verifier ( true ) ;
@ -274,20 +299,25 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) {
}
}
ApiCall ::ConfigDebugInfo ( b ) = > {
ApiCall ::ConfigDebugInfo ( b ) = > {
log ::trace ! ( "enabling debuginfo" ) ;
config . as_mut ( ) . unwrap ( ) . debug_info ( b ) ;
config . as_mut ( ) . unwrap ( ) . debug_info ( b ) ;
}
}
ApiCall ::EngineNew = > {
ApiCall ::EngineNew = > {
log ::trace ! ( "creating engine" ) ;
assert ! ( engine . is_none ( ) ) ;
assert ! ( engine . is_none ( ) ) ;
engine = Some ( Engine ::new ( config . as_ref ( ) . unwrap ( ) ) ) ;
engine = Some ( Engine ::new ( config . as_ref ( ) . unwrap ( ) ) ) ;
}
}
ApiCall ::StoreNew = > {
ApiCall ::StoreNew = > {
log ::trace ! ( "creating store" ) ;
assert ! ( store . is_none ( ) ) ;
assert ! ( store . is_none ( ) ) ;
store = Some ( Store ::new ( engine . as_ref ( ) . unwrap ( ) ) ) ;
store = Some ( Store ::new ( engine . as_ref ( ) . unwrap ( ) ) ) ;
}
}
ApiCall ::ModuleNew { id , wasm } = > {
ApiCall ::ModuleNew { id , wasm } = > {
log ::debug ! ( "creating module: {}" , id ) ;
log_wasm ( & wasm . wasm ) ;
let module = match Module ::new ( store . as_ref ( ) . unwrap ( ) , & wasm . wasm ) {
let module = match Module ::new ( store . as_ref ( ) . unwrap ( ) , & wasm . wasm ) {
Ok ( m ) = > m ,
Ok ( m ) = > m ,
Err ( _ ) = > continue ,
Err ( _ ) = > continue ,
@ -297,10 +327,12 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) {
}
}
ApiCall ::ModuleDrop { id } = > {
ApiCall ::ModuleDrop { id } = > {
log ::trace ! ( "dropping module: {}" , id ) ;
drop ( modules . remove ( & id ) ) ;
drop ( modules . remove ( & id ) ) ;
}
}
ApiCall ::InstanceNew { id , module } = > {
ApiCall ::InstanceNew { id , module } = > {
log ::trace ! ( "instantiating module {} as {}" , module , id ) ;
let module = match modules . get ( & module ) {
let module = match modules . get ( & module ) {
Some ( m ) = > m ,
Some ( m ) = > m ,
None = > continue ,
None = > continue ,
@ -326,10 +358,12 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) {
}
}
ApiCall ::InstanceDrop { id } = > {
ApiCall ::InstanceDrop { id } = > {
log ::trace ! ( "dropping instance {}" , id ) ;
drop ( instances . remove ( & id ) ) ;
drop ( instances . remove ( & id ) ) ;
}
}
ApiCall ::CallExportedFunc { instance , nth } = > {
ApiCall ::CallExportedFunc { instance , nth } = > {
log ::trace ! ( "calling instance export {} / {}" , instance , nth ) ;
let instance = match instances . get ( & instance ) {
let instance = match instances . get ( & instance ) {
Some ( i ) = > i ,
Some ( i ) = > i ,
None = > {
None = > {