summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wasm-smith/tests
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/wasm-smith/tests/available_imports.rs46
-rw-r--r--third_party/rust/wasm-smith/tests/common/mod.rs43
-rw-r--r--third_party/rust/wasm-smith/tests/core.rs3
-rw-r--r--third_party/rust/wasm-smith/tests/exports.rs147
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);
+ }
+}