Skip to content

Commit f063a7c

Browse files
authored
wasm-smith: Add config option to disallow floats (#1818)
* Distinguish non-float InstructionKinds * Avoid duplicated config logic in arbitrary_valtype * Add disallow_floats config option * Add disallow_floats test * Switch to a positive allow_floats option * Don't add GC valtypes when reference_types_enabled: false * Rename NonFloat to Int
1 parent a55438b commit f063a7c

File tree

4 files changed

+391
-308
lines changed

4 files changed

+391
-308
lines changed

crates/wasm-smith/src/config.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,23 @@ define_config! {
253253
/// specification](https://webassembly.github.io/spec/core/syntax/instructions.html);
254254
/// e.g., numeric, vector, control, memory, etc.
255255
///
256+
/// Additionally, we include finer-grained categories which exclude floating point
257+
/// instructions, e.g. [`InstructionKind::NumericInt`] is a subset of
258+
/// [`InstructionKind::Numeric`] consisting of all numeric instructions which
259+
/// don't involve floats.
260+
///
256261
/// Note that modifying this setting is separate from the proposal
257262
/// flags; that is, if `simd_enabled() == true` but
258263
/// `allowed_instruction()` does not include vector instructions, the
259264
/// generated programs will not include these instructions but could
260265
/// contain vector types.
261266
pub allowed_instructions: InstructionKinds = InstructionKinds::all(),
262267

268+
/// Determines whether we generate floating point instructions and types.
269+
///
270+
/// Defaults to `true`.
271+
pub allow_floats: bool = true,
272+
263273
/// Determines whether the bulk memory proposal is enabled for
264274
/// generating instructions.
265275
///
@@ -698,6 +708,7 @@ impl<'a> Arbitrary<'a> for Config {
698708
table_max_size_required: u.arbitrary()?,
699709
max_table_elements: u.int_in_range(0..=1_000_000)?,
700710
disallow_traps: u.arbitrary()?,
711+
allow_floats: u.arbitrary()?,
701712

702713
// These fields, unlike the ones above, are less useful to set.
703714
// They either make weird inputs or are for features not widely

crates/wasm-smith/src/core.rs

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,7 +1465,7 @@ impl Module {
14651465
}
14661466

14671467
fn arbitrary_valtype(&self, u: &mut Unstructured) -> Result<ValType> {
1468-
#[derive(Arbitrary)]
1468+
#[derive(PartialEq, Eq, PartialOrd, Ord)]
14691469
enum ValTypeClass {
14701470
I32,
14711471
I64,
@@ -1475,25 +1475,28 @@ impl Module {
14751475
Ref,
14761476
}
14771477

1478-
match u.arbitrary::<ValTypeClass>()? {
1478+
let mut val_classes: Vec<_> = self
1479+
.valtypes
1480+
.iter()
1481+
.map(|vt| match vt {
1482+
ValType::I32 => ValTypeClass::I32,
1483+
ValType::I64 => ValTypeClass::I64,
1484+
ValType::F32 => ValTypeClass::F32,
1485+
ValType::F64 => ValTypeClass::F64,
1486+
ValType::V128 => ValTypeClass::V128,
1487+
ValType::Ref(_) => ValTypeClass::Ref,
1488+
})
1489+
.collect();
1490+
val_classes.sort_unstable();
1491+
val_classes.dedup();
1492+
1493+
match u.choose(&val_classes)? {
14791494
ValTypeClass::I32 => Ok(ValType::I32),
14801495
ValTypeClass::I64 => Ok(ValType::I64),
14811496
ValTypeClass::F32 => Ok(ValType::F32),
14821497
ValTypeClass::F64 => Ok(ValType::F64),
1483-
ValTypeClass::V128 => {
1484-
if self.config.simd_enabled {
1485-
Ok(ValType::V128)
1486-
} else {
1487-
Ok(ValType::I32)
1488-
}
1489-
}
1490-
ValTypeClass::Ref => {
1491-
if self.config.reference_types_enabled {
1492-
Ok(ValType::Ref(self.arbitrary_ref_type(u)?))
1493-
} else {
1494-
Ok(ValType::I32)
1495-
}
1496-
}
1498+
ValTypeClass::V128 => Ok(ValType::V128),
1499+
ValTypeClass::Ref => Ok(ValType::Ref(self.arbitrary_ref_type(u)?)),
14971500
}
14981501
}
14991502

@@ -2482,12 +2485,14 @@ pub(crate) fn configured_valtypes(config: &Config) -> Vec<ValType> {
24822485
let mut valtypes = Vec::with_capacity(25);
24832486
valtypes.push(ValType::I32);
24842487
valtypes.push(ValType::I64);
2485-
valtypes.push(ValType::F32);
2486-
valtypes.push(ValType::F64);
2488+
if config.allow_floats {
2489+
valtypes.push(ValType::F32);
2490+
valtypes.push(ValType::F64);
2491+
}
24872492
if config.simd_enabled {
24882493
valtypes.push(ValType::V128);
24892494
}
2490-
if config.gc_enabled {
2495+
if config.gc_enabled && config.reference_types_enabled {
24912496
for nullable in [
24922497
// TODO: For now, only create allow nullable reference
24932498
// types. Eventually we should support non-nullable reference types,
@@ -2808,6 +2813,24 @@ impl InstructionKinds {
28082813
pub fn contains(&self, kind: InstructionKind) -> bool {
28092814
self.0.contains(kind)
28102815
}
2816+
2817+
/// Restrict each [InstructionKind] to its subset not involving floats
2818+
pub fn without_floats(&self) -> Self {
2819+
let mut floatless = self.0;
2820+
if floatless.contains(InstructionKind::Numeric) {
2821+
floatless -= InstructionKind::Numeric;
2822+
floatless |= InstructionKind::NumericInt;
2823+
}
2824+
if floatless.contains(InstructionKind::Vector) {
2825+
floatless -= InstructionKind::Vector;
2826+
floatless |= InstructionKind::VectorInt;
2827+
}
2828+
if floatless.contains(InstructionKind::Memory) {
2829+
floatless -= InstructionKind::Memory;
2830+
floatless |= InstructionKind::MemoryInt;
2831+
}
2832+
Self(floatless)
2833+
}
28112834
}
28122835

28132836
flags! {
@@ -2816,15 +2839,18 @@ flags! {
28162839
#[allow(missing_docs)]
28172840
#[cfg_attr(feature = "_internal_cli", derive(serde_derive::Deserialize))]
28182841
pub enum InstructionKind: u16 {
2819-
Numeric,
2820-
Vector,
2821-
Reference,
2822-
Parametric,
2823-
Variable,
2824-
Table,
2825-
Memory,
2826-
Control,
2827-
Aggregate,
2842+
NumericInt = 1 << 0,
2843+
Numeric = (1 << 1) | (1 << 0),
2844+
VectorInt = 1 << 2,
2845+
Vector = (1 << 3) | (1 << 2),
2846+
Reference = 1 << 4,
2847+
Parametric = 1 << 5,
2848+
Variable = 1 << 6,
2849+
Table = 1 << 7,
2850+
MemoryInt = 1 << 8,
2851+
Memory = (1 << 9) | (1 << 8),
2852+
Control = 1 << 10,
2853+
Aggregate = 1 << 11,
28282854
}
28292855
}
28302856

@@ -2844,12 +2870,15 @@ impl FromStr for InstructionKind {
28442870
type Err = String;
28452871
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
28462872
match s.to_lowercase().as_str() {
2873+
"numeric_non_float" => Ok(InstructionKind::NumericInt),
28472874
"numeric" => Ok(InstructionKind::Numeric),
2875+
"vector_non_float" => Ok(InstructionKind::VectorInt),
28482876
"vector" => Ok(InstructionKind::Vector),
28492877
"reference" => Ok(InstructionKind::Reference),
28502878
"parametric" => Ok(InstructionKind::Parametric),
28512879
"variable" => Ok(InstructionKind::Variable),
28522880
"table" => Ok(InstructionKind::Table),
2881+
"memory_non_float" => Ok(InstructionKind::MemoryInt),
28532882
"memory" => Ok(InstructionKind::Memory),
28542883
"control" => Ok(InstructionKind::Control),
28552884
_ => Err(format!("unknown instruction kind: {}", s)),

0 commit comments

Comments
 (0)