Skip to content

Commit 40bf650

Browse files
Generate atomic instructions defined in the threads proposal
This commit adds suppport for emitting atomic instructions when wasm_smith::Config::threads_enabled and wasm_smith::Config::shared_everything_threads_enabled are true. A link to the atomic instructions in the threads proposal: https://webassembly.github.io/threads/core/syntax/instructions.html#syntax-instr-atomic-memory
1 parent 44b5ea4 commit 40bf650

File tree

3 files changed

+345
-1
lines changed

3 files changed

+345
-1
lines changed

crates/wasm-smith/src/core/code_builder.rs

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,74 @@ instructions! {
594594
(Some(wide_arithmetic_binop128_on_stack), i64_sub128, NumericInt),
595595
(Some(wide_arithmetic_mul_wide_on_stack), i64_mul_wide_s, NumericInt),
596596
(Some(wide_arithmetic_mul_wide_on_stack), i64_mul_wide_u, NumericInt),
597+
// Atomic instructions
598+
(Some(atomic_load_valid), i32_atomic_load, MemoryInt),
599+
(Some(atomic_load_valid), i64_atomic_load, MemoryInt),
600+
(Some(atomic_load_valid), i32_atomic_load8_u,MemoryInt),
601+
(Some(atomic_load_valid), i64_atomic_load8_u, MemoryInt),
602+
(Some(atomic_load_valid), i32_atomic_load16_u, MemoryInt),
603+
(Some(atomic_load_valid), i64_atomic_load16_u, MemoryInt),
604+
(Some(atomic_load_valid), i64_atomic_load32_u, MemoryInt),
605+
(Some(i32_atomic_store_valid), i32_atomic_store, MemoryInt),
606+
(Some(i64_atomic_store_valid), i64_atomic_store, MemoryInt),
607+
(Some(i32_atomic_store_valid), i32_atomic_store8, MemoryInt),
608+
(Some(i64_atomic_store_valid), i64_atomic_store8, MemoryInt),
609+
(Some(i32_atomic_store_valid), i32_atomic_store16, MemoryInt),
610+
(Some(i64_atomic_store_valid), i64_atomic_store16, MemoryInt),
611+
(Some(i64_atomic_store_valid), i64_atomic_store32, MemoryInt),
612+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw_add, MemoryInt),
613+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw_sub, MemoryInt),
614+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw_and, MemoryInt),
615+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw_or, MemoryInt),
616+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw_xor, MemoryInt),
617+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw_xchg, MemoryInt),
618+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw_add, MemoryInt),
619+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw_sub, MemoryInt),
620+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw_and, MemoryInt),
621+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw_or, MemoryInt),
622+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw_xor, MemoryInt),
623+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw_xchg, MemoryInt),
624+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw8_add_u, MemoryInt),
625+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw8_sub_u, MemoryInt),
626+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw8_and_u, MemoryInt),
627+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw8_or_u, MemoryInt),
628+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw8_xor_u, MemoryInt),
629+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw8_xchg_u, MemoryInt),
630+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw8_add_u, MemoryInt),
631+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw8_sub_u, MemoryInt),
632+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw8_and_u, MemoryInt),
633+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw8_or_u, MemoryInt),
634+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw8_xor_u, MemoryInt),
635+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw8_xchg_u, MemoryInt),
636+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw16_add_u, MemoryInt),
637+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw16_sub_u, MemoryInt),
638+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw16_and_u, MemoryInt),
639+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw16_or_u, MemoryInt),
640+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw16_xor_u, MemoryInt),
641+
(Some(i32_atomic_rmw_atop_valid), i32_atomic_rmw16_xchg_u, MemoryInt),
642+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw16_add_u, MemoryInt),
643+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw16_sub_u, MemoryInt),
644+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw16_and_u, MemoryInt),
645+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw16_or_u, MemoryInt),
646+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw16_xor_u, MemoryInt),
647+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw16_xchg_u, MemoryInt),
648+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw32_add_u, MemoryInt),
649+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw32_sub_u, MemoryInt),
650+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw32_and_u, MemoryInt),
651+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw32_or_u, MemoryInt),
652+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw32_xor_u, MemoryInt),
653+
(Some(i64_atomic_rmw_atop_valid), i64_atomic_rmw32_xchg_u, MemoryInt),
654+
(Some(i32_atomic_rmw_cmpxchg_valid), i32_atomic_rmw_cmpxchg, MemoryInt),
655+
(Some(i64_atomic_rmw_cmpxchg_valid), i64_atomic_rmw_cmpxchg, MemoryInt),
656+
(Some(i32_atomic_rmw_cmpxchg_valid), i32_atomic_rmw8_cmpxchg_u, MemoryInt),
657+
(Some(i64_atomic_rmw_cmpxchg_valid), i64_atomic_rmw8_cmpxchg_u, MemoryInt),
658+
(Some(i32_atomic_rmw_cmpxchg_valid), i32_atomic_rmw16_cmpxchg_u, MemoryInt),
659+
(Some(i64_atomic_rmw_cmpxchg_valid), i64_atomic_rmw16_cmpxchg_u, MemoryInt),
660+
(Some(i64_atomic_rmw_cmpxchg_valid), i64_atomic_rmw32_cmpxchg_u, MemoryInt),
661+
(Some(atomic_notify_valid), atomic_notify, MemoryInt),
662+
(Some(atomic_wait32_valid), atomic_wait32, MemoryInt),
663+
(Some(atomic_wait64_valid), atomic_wait64, MemoryInt),
664+
(Some(atomic_instruction_valid), atomic_fence, MemoryInt),
597665
}
598666

599667
pub(crate) struct CodeBuilderAllocations {
@@ -7333,3 +7401,260 @@ fn i64_mul_wide_u(
73337401
instructions.push(Instruction::I64MulWideU);
73347402
Ok(())
73357403
}
7404+
7405+
#[inline]
7406+
fn atomic_instruction_valid(module: &Module, _builder: &mut CodeBuilder) -> bool {
7407+
module.config.threads_enabled
7408+
}
7409+
7410+
#[inline]
7411+
fn atomic_load_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
7412+
atomic_instruction_valid(module, builder) && have_memory_and_offset(module, builder)
7413+
}
7414+
7415+
#[inline]
7416+
fn i32_atomic_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
7417+
atomic_instruction_valid(module, builder) && i32_store_valid(module, builder)
7418+
}
7419+
7420+
#[inline]
7421+
fn i64_atomic_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
7422+
atomic_instruction_valid(module, builder) && i64_store_valid(module, builder)
7423+
}
7424+
7425+
#[inline]
7426+
fn atomic_stack_op_valid(
7427+
module: &Module,
7428+
builder: &mut CodeBuilder,
7429+
stack_types: &[ValType],
7430+
) -> bool {
7431+
atomic_instruction_valid(module, builder)
7432+
&& builder.types_on_stack(module, stack_types)
7433+
&& ((builder.allocs.memory32.len() > 0
7434+
&& builder.type_on_stack_at(module, stack_types.len(), ValType::I32))
7435+
|| (builder.allocs.memory64.len() > 0
7436+
&& builder.type_on_stack_at(module, stack_types.len(), ValType::I64)))
7437+
}
7438+
7439+
#[inline]
7440+
fn i32_atomic_rmw_atop_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
7441+
atomic_stack_op_valid(module, builder, &[ValType::I32])
7442+
}
7443+
7444+
#[inline]
7445+
fn i64_atomic_rmw_atop_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
7446+
atomic_stack_op_valid(module, builder, &[ValType::I64])
7447+
}
7448+
7449+
#[inline]
7450+
fn i32_atomic_rmw_cmpxchg_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
7451+
atomic_stack_op_valid(module, builder, &[ValType::I32, ValType::I32])
7452+
}
7453+
7454+
#[inline]
7455+
fn i64_atomic_rmw_cmpxchg_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
7456+
atomic_stack_op_valid(module, builder, &[ValType::I64, ValType::I64])
7457+
}
7458+
7459+
#[inline]
7460+
fn atomic_notify_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
7461+
atomic_stack_op_valid(module, builder, &[ValType::I32])
7462+
}
7463+
7464+
#[inline]
7465+
fn atomic_wait32_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
7466+
atomic_stack_op_valid(module, builder, &[ValType::I32, ValType::I64])
7467+
}
7468+
7469+
#[inline]
7470+
fn atomic_wait64_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
7471+
atomic_stack_op_valid(module, builder, &[ValType::I64, ValType::I64])
7472+
}
7473+
7474+
macro_rules! atomic_load {
7475+
($instr:ident, $valtype:ident, $fn_name:ident, [$($memarg_align:expr),*]) => {
7476+
fn $fn_name(
7477+
u: &mut Unstructured,
7478+
module: &Module,
7479+
builder: &mut CodeBuilder,
7480+
instructions: &mut Vec<Instruction>,
7481+
) -> Result<()> {
7482+
let memarg = mem_arg(u, module, builder, &[$($memarg_align),*])?;
7483+
builder.push_operands(&[ValType::$valtype]);
7484+
instructions.push(Instruction::$instr(memarg));
7485+
Ok(())
7486+
}
7487+
};
7488+
}
7489+
7490+
macro_rules! atomic_store {
7491+
($instr:ident, $valtype:ident, $fn_name:ident, [$($memarg_align:expr),*]) => {
7492+
fn $fn_name(
7493+
u: &mut Unstructured,
7494+
module: &Module,
7495+
builder: &mut CodeBuilder,
7496+
instructions: &mut Vec<Instruction>,
7497+
) -> Result<()> {
7498+
builder.pop_operands(module, &[ValType::$valtype]);
7499+
let memarg = mem_arg(u, module, builder, &[$($memarg_align),*])?;
7500+
instructions.push(Instruction::$instr(memarg));
7501+
Ok(())
7502+
}
7503+
};
7504+
}
7505+
7506+
macro_rules! atomic_rmw_atop {
7507+
($valtype:ident, $instr:ident, $fn_name:ident, [$($memarg_align:expr),*]) => {
7508+
fn $fn_name(
7509+
u: &mut Unstructured,
7510+
module: &Module,
7511+
builder: &mut CodeBuilder,
7512+
instructions: &mut Vec<Instruction>,
7513+
) -> Result<()> {
7514+
builder.pop_operands(module, &[ValType::$valtype]);
7515+
let memarg = mem_arg(u, module, builder, &[$($memarg_align),*])?;
7516+
builder.push_operands(&[ValType::$valtype]);
7517+
instructions.push(Instruction::$instr(memarg));
7518+
Ok(())
7519+
}
7520+
};
7521+
}
7522+
7523+
macro_rules! atomic_rmw_cmpxchg {
7524+
($valtype:ident, $instr:ident, $fn_name:ident, [$($memarg_align:expr),*]) => {
7525+
fn $fn_name(
7526+
u: &mut Unstructured,
7527+
module: &Module,
7528+
builder: &mut CodeBuilder,
7529+
instructions: &mut Vec<Instruction>,
7530+
) -> Result<()> {
7531+
builder.pop_operands(module, &[ValType::$valtype, ValType::$valtype]);
7532+
let memarg = mem_arg(u, module, builder, &[$($memarg_align),*])?;
7533+
builder.push_operands(&[ValType::$valtype]);
7534+
instructions.push(Instruction::$instr(memarg));
7535+
Ok(())
7536+
}
7537+
};
7538+
}
7539+
7540+
atomic_load!(I32AtomicLoad, I32, i32_atomic_load, [2]);
7541+
atomic_load!(I64AtomicLoad, I64, i64_atomic_load, [3]);
7542+
atomic_load!(I32AtomicLoad8U, I32, i32_atomic_load8_u, [0]);
7543+
atomic_load!(I64AtomicLoad8U, I64, i64_atomic_load8_u, [0]);
7544+
atomic_load!(I32AtomicLoad16U, I32, i32_atomic_load16_u, [1]);
7545+
atomic_load!(I64AtomicLoad16U, I64, i64_atomic_load16_u, [1]);
7546+
atomic_load!(I64AtomicLoad32U, I64, i64_atomic_load32_u, [2]);
7547+
7548+
atomic_store!(I32AtomicStore, I32, i32_atomic_store, [2]);
7549+
atomic_store!(I64AtomicStore, I64, i64_atomic_store, [3]);
7550+
atomic_store!(I32AtomicStore8, I32, i32_atomic_store8, [0]);
7551+
atomic_store!(I64AtomicStore8, I64, i64_atomic_store8, [0]);
7552+
atomic_store!(I32AtomicStore16, I32, i32_atomic_store16, [1]);
7553+
atomic_store!(I64AtomicStore16, I64, i64_atomic_store16, [1]);
7554+
atomic_store!(I64AtomicStore32, I64, i64_atomic_store32, [2]);
7555+
7556+
atomic_rmw_atop!(I32, I32AtomicRmwAdd, i32_atomic_rmw_add, [2]);
7557+
atomic_rmw_atop!(I32, I32AtomicRmwSub, i32_atomic_rmw_sub, [2]);
7558+
atomic_rmw_atop!(I32, I32AtomicRmwAnd, i32_atomic_rmw_and, [2]);
7559+
atomic_rmw_atop!(I32, I32AtomicRmwOr, i32_atomic_rmw_or, [2]);
7560+
atomic_rmw_atop!(I32, I32AtomicRmwXor, i32_atomic_rmw_xor, [2]);
7561+
atomic_rmw_atop!(I32, I32AtomicRmwXchg, i32_atomic_rmw_xchg, [2]);
7562+
7563+
atomic_rmw_atop!(I64, I64AtomicRmwAdd, i64_atomic_rmw_add, [3]);
7564+
atomic_rmw_atop!(I64, I64AtomicRmwSub, i64_atomic_rmw_sub, [3]);
7565+
atomic_rmw_atop!(I64, I64AtomicRmwAnd, i64_atomic_rmw_and, [3]);
7566+
atomic_rmw_atop!(I64, I64AtomicRmwOr, i64_atomic_rmw_or, [3]);
7567+
atomic_rmw_atop!(I64, I64AtomicRmwXor, i64_atomic_rmw_xor, [3]);
7568+
atomic_rmw_atop!(I64, I64AtomicRmwXchg, i64_atomic_rmw_xchg, [3]);
7569+
7570+
atomic_rmw_atop!(I32, I32AtomicRmw8AddU, i32_atomic_rmw8_add_u, [0]);
7571+
atomic_rmw_atop!(I32, I32AtomicRmw8SubU, i32_atomic_rmw8_sub_u, [0]);
7572+
atomic_rmw_atop!(I32, I32AtomicRmw8AndU, i32_atomic_rmw8_and_u, [0]);
7573+
atomic_rmw_atop!(I32, I32AtomicRmw8OrU, i32_atomic_rmw8_or_u, [0]);
7574+
atomic_rmw_atop!(I32, I32AtomicRmw8XorU, i32_atomic_rmw8_xor_u, [0]);
7575+
atomic_rmw_atop!(I32, I32AtomicRmw8XchgU, i32_atomic_rmw8_xchg_u, [0]);
7576+
7577+
atomic_rmw_atop!(I64, I64AtomicRmw8AddU, i64_atomic_rmw8_add_u, [0]);
7578+
atomic_rmw_atop!(I64, I64AtomicRmw8SubU, i64_atomic_rmw8_sub_u, [0]);
7579+
atomic_rmw_atop!(I64, I64AtomicRmw8AndU, i64_atomic_rmw8_and_u, [0]);
7580+
atomic_rmw_atop!(I64, I64AtomicRmw8OrU, i64_atomic_rmw8_or_u, [0]);
7581+
atomic_rmw_atop!(I64, I64AtomicRmw8XorU, i64_atomic_rmw8_xor_u, [0]);
7582+
atomic_rmw_atop!(I64, I64AtomicRmw8XchgU, i64_atomic_rmw8_xchg_u, [0]);
7583+
7584+
atomic_rmw_atop!(I32, I32AtomicRmw16AddU, i32_atomic_rmw16_add_u, [1]);
7585+
atomic_rmw_atop!(I32, I32AtomicRmw16SubU, i32_atomic_rmw16_sub_u, [1]);
7586+
atomic_rmw_atop!(I32, I32AtomicRmw16AndU, i32_atomic_rmw16_and_u, [1]);
7587+
atomic_rmw_atop!(I32, I32AtomicRmw16OrU, i32_atomic_rmw16_or_u, [1]);
7588+
atomic_rmw_atop!(I32, I32AtomicRmw16XorU, i32_atomic_rmw16_xor_u, [1]);
7589+
atomic_rmw_atop!(I32, I32AtomicRmw16XchgU, i32_atomic_rmw16_xchg_u, [1]);
7590+
7591+
atomic_rmw_atop!(I64, I64AtomicRmw16AddU, i64_atomic_rmw16_add_u, [1]);
7592+
atomic_rmw_atop!(I64, I64AtomicRmw16SubU, i64_atomic_rmw16_sub_u, [1]);
7593+
atomic_rmw_atop!(I64, I64AtomicRmw16AndU, i64_atomic_rmw16_and_u, [1]);
7594+
atomic_rmw_atop!(I64, I64AtomicRmw16OrU, i64_atomic_rmw16_or_u, [1]);
7595+
atomic_rmw_atop!(I64, I64AtomicRmw16XorU, i64_atomic_rmw16_xor_u, [1]);
7596+
atomic_rmw_atop!(I64, I64AtomicRmw16XchgU, i64_atomic_rmw16_xchg_u, [1]);
7597+
7598+
atomic_rmw_atop!(I64, I64AtomicRmw32AddU, i64_atomic_rmw32_add_u, [2]);
7599+
atomic_rmw_atop!(I64, I64AtomicRmw32SubU, i64_atomic_rmw32_sub_u, [2]);
7600+
atomic_rmw_atop!(I64, I64AtomicRmw32AndU, i64_atomic_rmw32_and_u, [2]);
7601+
atomic_rmw_atop!(I64, I64AtomicRmw32OrU, i64_atomic_rmw32_or_u, [2]);
7602+
atomic_rmw_atop!(I64, I64AtomicRmw32XorU, i64_atomic_rmw32_xor_u, [2]);
7603+
atomic_rmw_atop!(I64, I64AtomicRmw32XchgU, i64_atomic_rmw32_xchg_u, [2]);
7604+
7605+
atomic_rmw_cmpxchg!(I32, I32AtomicRmwCmpxchg, i32_atomic_rmw_cmpxchg, [2]);
7606+
atomic_rmw_cmpxchg!(I64, I64AtomicRmwCmpxchg, i64_atomic_rmw_cmpxchg, [3]);
7607+
atomic_rmw_cmpxchg!(I32, I32AtomicRmw8CmpxchgU, i32_atomic_rmw8_cmpxchg_u, [0]);
7608+
atomic_rmw_cmpxchg!(I64, I64AtomicRmw8CmpxchgU, i64_atomic_rmw8_cmpxchg_u, [0]);
7609+
atomic_rmw_cmpxchg!(I32, I32AtomicRmw16CmpxchgU, i32_atomic_rmw16_cmpxchg_u, [1]);
7610+
atomic_rmw_cmpxchg!(I64, I64AtomicRmw16CmpxchgU, i64_atomic_rmw16_cmpxchg_u, [1]);
7611+
atomic_rmw_cmpxchg!(I64, I64AtomicRmw32CmpxchgU, i64_atomic_rmw32_cmpxchg_u, [2]);
7612+
7613+
fn atomic_notify(
7614+
u: &mut Unstructured,
7615+
module: &Module,
7616+
builder: &mut CodeBuilder,
7617+
instructions: &mut Vec<Instruction>,
7618+
) -> Result<()> {
7619+
builder.pop_operands(module, &[ValType::I32]);
7620+
let memarg = mem_arg(u, module, builder, &[2])?;
7621+
builder.push_operands(&[ValType::I32]);
7622+
instructions.push(Instruction::MemoryAtomicNotify(memarg));
7623+
Ok(())
7624+
}
7625+
7626+
fn atomic_wait32(
7627+
u: &mut Unstructured,
7628+
module: &Module,
7629+
builder: &mut CodeBuilder,
7630+
instructions: &mut Vec<Instruction>,
7631+
) -> Result<()> {
7632+
builder.pop_operands(module, &[ValType::I32, ValType::I64]);
7633+
let memarg = mem_arg(u, module, builder, &[2])?;
7634+
builder.push_operands(&[ValType::I32]);
7635+
instructions.push(Instruction::MemoryAtomicWait32(memarg));
7636+
Ok(())
7637+
}
7638+
7639+
fn atomic_wait64(
7640+
u: &mut Unstructured,
7641+
module: &Module,
7642+
builder: &mut CodeBuilder,
7643+
instructions: &mut Vec<Instruction>,
7644+
) -> Result<()> {
7645+
builder.pop_operands(module, &[ValType::I64, ValType::I64]);
7646+
let memarg = mem_arg(u, module, builder, &[3])?;
7647+
builder.push_operands(&[ValType::I32]);
7648+
instructions.push(Instruction::MemoryAtomicWait64(memarg));
7649+
Ok(())
7650+
}
7651+
7652+
fn atomic_fence(
7653+
_u: &mut Unstructured,
7654+
_module: &Module,
7655+
_builder: &mut CodeBuilder,
7656+
instructions: &mut Vec<Instruction>,
7657+
) -> Result<()> {
7658+
instructions.push(Instruction::AtomicFence);
7659+
Ok(())
7660+
}

crates/wasm-smith/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
#![cfg_attr(docsrs, feature(doc_cfg))]
5656
#![deny(missing_docs, missing_debug_implementations)]
5757
// Needed for the `instructions!` macro in `src/code_builder.rs`.
58-
#![recursion_limit = "512"]
58+
#![recursion_limit = "1024"]
5959

6060
#[cfg(feature = "component-model")]
6161
mod component;

crates/wasm-smith/tests/core.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,25 @@ fn smoke_test_reference_types() {
166166
}
167167
}
168168

169+
#[test]
170+
fn smoke_test_threads() {
171+
let mut rng = SmallRng::seed_from_u64(0);
172+
let mut buf = vec![0; 2048];
173+
for _ in 0..1024 {
174+
rng.fill_bytes(&mut buf);
175+
let mut u = Unstructured::new(&buf);
176+
let config = Config {
177+
threads_enabled: true,
178+
..Config::default()
179+
};
180+
if let Ok(module) = Module::new(config, &mut u) {
181+
let wasm_bytes = module.to_bytes();
182+
let mut validator = Validator::new_with_features(WasmFeatures::all());
183+
validate(&mut validator, &wasm_bytes);
184+
}
185+
}
186+
}
187+
169188
#[test]
170189
fn smoke_test_wasm_gc() {
171190
let mut rng = SmallRng::seed_from_u64(0);

0 commit comments

Comments
 (0)