diff options
Diffstat (limited to 'third_party/rust/wasm-smith/tests')
-rw-r--r-- | third_party/rust/wasm-smith/tests/available_imports.rs | 46 | ||||
-rw-r--r-- | third_party/rust/wasm-smith/tests/common/mod.rs | 43 | ||||
-rw-r--r-- | third_party/rust/wasm-smith/tests/core.rs | 3 | ||||
-rw-r--r-- | third_party/rust/wasm-smith/tests/exports.rs | 147 |
4 files changed, 196 insertions, 43 deletions
diff --git a/third_party/rust/wasm-smith/tests/available_imports.rs b/third_party/rust/wasm-smith/tests/available_imports.rs index 2ccc4c1cea..27e4852da9 100644 --- a/third_party/rust/wasm-smith/tests/available_imports.rs +++ b/third_party/rust/wasm-smith/tests/available_imports.rs @@ -4,8 +4,11 @@ use arbitrary::{Arbitrary, Unstructured}; use rand::{rngs::SmallRng, RngCore, SeedableRng}; use std::collections::HashMap; use wasm_smith::{Config, Module}; +use wasmparser::Validator; use wasmparser::{Parser, TypeRef, ValType}; -use wasmparser::{Validator, WasmFeatures}; + +mod common; +use common::{parser_features_from_config, validate}; #[test] fn smoke_test_imports_config() { @@ -159,44 +162,3 @@ fn import_config( ); (config, available) } - -fn parser_features_from_config(config: &Config) -> WasmFeatures { - WasmFeatures { - mutable_global: true, - saturating_float_to_int: config.saturating_float_to_int_enabled, - sign_extension: config.sign_extension_ops_enabled, - reference_types: config.reference_types_enabled, - multi_value: config.multi_value_enabled, - bulk_memory: config.bulk_memory_enabled, - simd: config.simd_enabled, - relaxed_simd: config.relaxed_simd_enabled, - multi_memory: config.max_memories > 1, - exceptions: config.exceptions_enabled, - memory64: config.memory64_enabled, - tail_call: config.tail_call_enabled, - function_references: config.gc_enabled, - gc: config.gc_enabled, - - threads: false, - floats: true, - extended_const: false, - component_model: false, - memory_control: false, - component_model_values: false, - component_model_nested_names: false, - } -} - -fn validate(validator: &mut Validator, bytes: &[u8]) { - let err = match validator.validate_all(bytes) { - Ok(_) => return, - Err(e) => e, - }; - eprintln!("Writing Wasm to `test.wasm`"); - drop(std::fs::write("test.wasm", &bytes)); - if let Ok(text) = wasmprinter::print_bytes(bytes) { - eprintln!("Writing WAT to `test.wat`"); - drop(std::fs::write("test.wat", &text)); - } - panic!("wasm failed to validate: {}", err); -} diff --git a/third_party/rust/wasm-smith/tests/common/mod.rs b/third_party/rust/wasm-smith/tests/common/mod.rs new file mode 100644 index 0000000000..cc24eed278 --- /dev/null +++ b/third_party/rust/wasm-smith/tests/common/mod.rs @@ -0,0 +1,43 @@ +use wasm_smith::Config; +use wasmparser::{types::Types, Validator, WasmFeatures}; + +pub fn parser_features_from_config(config: &Config) -> WasmFeatures { + WasmFeatures { + mutable_global: true, + saturating_float_to_int: config.saturating_float_to_int_enabled, + sign_extension: config.sign_extension_ops_enabled, + reference_types: config.reference_types_enabled, + multi_value: config.multi_value_enabled, + bulk_memory: config.bulk_memory_enabled, + simd: config.simd_enabled, + relaxed_simd: config.relaxed_simd_enabled, + multi_memory: config.max_memories > 1, + exceptions: config.exceptions_enabled, + memory64: config.memory64_enabled, + tail_call: config.tail_call_enabled, + function_references: config.gc_enabled, + gc: config.gc_enabled, + + threads: false, + floats: true, + extended_const: false, + component_model: false, + memory_control: false, + component_model_values: false, + component_model_nested_names: false, + } +} + +pub fn validate(validator: &mut Validator, bytes: &[u8]) -> Types { + let err = match validator.validate_all(bytes) { + Ok(types) => return types, + Err(e) => e, + }; + eprintln!("Writing Wasm to `test.wasm`"); + drop(std::fs::write("test.wasm", &bytes)); + if let Ok(text) = wasmprinter::print_bytes(bytes) { + eprintln!("Writing WAT to `test.wat`"); + drop(std::fs::write("test.wat", &text)); + } + panic!("wasm failed to validate: {}", err); +} diff --git a/third_party/rust/wasm-smith/tests/core.rs b/third_party/rust/wasm-smith/tests/core.rs index 5816f8e38b..7286952dc6 100644 --- a/third_party/rust/wasm-smith/tests/core.rs +++ b/third_party/rust/wasm-smith/tests/core.rs @@ -27,7 +27,7 @@ fn smoke_test_ensure_termination() { rng.fill_bytes(&mut buf); let u = Unstructured::new(&buf); if let Ok(mut module) = Module::arbitrary_take_rest(u) { - module.ensure_termination(10); + module.ensure_termination(10).unwrap(); let wasm_bytes = module.to_bytes(); let mut validator = Validator::new_with_features(wasm_features()); @@ -128,6 +128,7 @@ fn smoke_test_wasm_gc() { let mut u = Unstructured::new(&buf); let config = Config { gc_enabled: true, + reference_types_enabled: true, ..Config::default() }; if let Ok(module) = Module::new(config, &mut u) { diff --git a/third_party/rust/wasm-smith/tests/exports.rs b/third_party/rust/wasm-smith/tests/exports.rs new file mode 100644 index 0000000000..ff1dac0cbe --- /dev/null +++ b/third_party/rust/wasm-smith/tests/exports.rs @@ -0,0 +1,147 @@ +use arbitrary::{Arbitrary, Unstructured}; +use rand::{rngs::SmallRng, RngCore, SeedableRng}; +use wasm_smith::{Config, Module}; +use wasmparser::{ + types::EntityType, CompositeType, FuncType, GlobalType, Parser, Validator, WasmFeatures, +}; + +mod common; +use common::{parser_features_from_config, validate}; + +#[derive(Debug, PartialEq)] +enum ExportType { + Func(FuncType), + Global(GlobalType), +} + +#[test] +fn smoke_test_single_export() { + let test = r#" + (module + (func (export "foo") (param i32) (result i64) + unreachable + ) + ) + "#; + smoke_test_exports(test, 11) +} + +#[test] +fn smoke_test_multiple_exports() { + let test = r#" + (module + (func (export "a") (param i32) (result i64) + unreachable + ) + (func (export "b") + unreachable + ) + (func (export "c") + unreachable + ) + ) + "#; + smoke_test_exports(test, 12) +} + +#[test] +fn smoke_test_exported_global() { + let test = r#" + (module + (func (export "a") (param i32 i32 f32 f64) (result f32) + unreachable + ) + (global (export "glob") f64 f64.const 0) + ) + "#; + smoke_test_exports(test, 20) +} + +#[test] +fn smoke_test_export_with_imports() { + let test = r#" + (module + (import "" "foo" (func (param i32))) + (import "" "bar" (global (mut f32))) + (func (param i64) unreachable) + (global i32 (i32.const 0)) + (export "a" (func 0)) + (export "b" (global 0)) + (export "c" (func 1)) + (export "d" (global 1)) + ) + "#; + smoke_test_exports(test, 21) +} + +#[test] +fn smoke_test_with_mutable_global_exports() { + let test = r#" + (module + (global (export "1i32") (mut i32) (i32.const 0)) + (global (export "2i32") (mut i32) (i32.const 0)) + (global (export "1i64") (mut i64) (i64.const 0)) + (global (export "2i64") (mut i64) (i64.const 0)) + (global (export "3i32") (mut i32) (i32.const 0)) + (global (export "3i64") (mut i64) (i64.const 0)) + (global (export "4i32") i32 (i32.const 0)) + (global (export "4i64") i64 (i64.const 0)) + )"#; + smoke_test_exports(test, 22) +} + +fn get_func_and_global_exports(features: WasmFeatures, module: &[u8]) -> Vec<(String, ExportType)> { + let mut validator = Validator::new_with_features(features); + let types = validate(&mut validator, module); + let mut exports = vec![]; + + for payload in Parser::new(0).parse_all(module) { + let payload = payload.unwrap(); + if let wasmparser::Payload::ExportSection(rdr) = payload { + for export in rdr { + let export = export.unwrap(); + match types.entity_type_from_export(&export).unwrap() { + EntityType::Func(core_id) => { + let sub_type = types.get(core_id).expect("Failed to lookup core id"); + assert!(sub_type.is_final); + assert!(sub_type.supertype_idx.is_none()); + let CompositeType::Func(func_type) = &sub_type.composite_type else { + panic!("Expected Func CompositeType, but found {:?}", sub_type); + }; + exports + .push((export.name.to_string(), ExportType::Func(func_type.clone()))); + } + EntityType::Global(global_type) => { + exports.push((export.name.to_string(), ExportType::Global(global_type))) + } + other => { + panic!("Unexpected entity type {:?}", other) + } + } + } + } + } + exports +} + +fn smoke_test_exports(exports_test_case: &str, seed: u64) { + let mut rng = SmallRng::seed_from_u64(seed); + let mut buf = vec![0; 512]; + let wasm = wat::parse_str(exports_test_case).unwrap(); + let expected_exports = get_func_and_global_exports(WasmFeatures::default(), &wasm); + + for _ in 0..1024 { + rng.fill_bytes(&mut buf); + let mut u = Unstructured::new(&buf); + + let mut config = Config::arbitrary(&mut u).expect("arbitrary config"); + config.exports = Some(wasm.clone()); + + let features = parser_features_from_config(&config); + let module = Module::new(config, &mut u).unwrap(); + let wasm_bytes = module.to_bytes(); + + let generated_exports = get_func_and_global_exports(features, &wasm_bytes); + assert_eq!(expected_exports, generated_exports); + } +} |