Skip to content

Commit 7ea6523

Browse files
chore: simplify visitor macros
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent 17c5dc6 commit 7ea6523

2 files changed

Lines changed: 97 additions & 55 deletions

File tree

‎crates/parser/src/macros.rs‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ pub(crate) mod visit {
4545
// and fallback opcode. Instructions without a family use plain emission.
4646
macro_rules! lowering_ops {
4747
() => {};
48+
(atomic $op:ident $inputs:tt => $outputs:tt {
49+
$($visit:ident => $width:literal),* $(,)?
50+
} $($rest:tt)*) => {
51+
$(lowering_ops!(@atomic $op $inputs => $outputs $visit $width);)*
52+
lowering_ops!($($rest)*);
53+
};
4854
($kind:ident $inputs:tt => $outputs:tt {
4955
$($visit:ident $(($($arg:ident: $ty:ty),+))? => $instr:ident $([$family:ident($($rule_arg:expr),*)])?),* $(,)?
5056
} $($rest:tt)*) => {
@@ -104,6 +110,30 @@ pub(crate) mod visit {
104110
(@memory_arg $memory_arg_idx:ident, $lane:ident) => {
105111
tinywasm_types::MemoryLaneArg { memory_arg_idx: $memory_arg_idx, lane: $lane }
106112
};
113+
(@atomic $op:ident [$($input:ident),*] => [$($output:ident),*] $visit:ident $width:literal) => {
114+
fn $visit(&mut self, memarg: wasmparser::MemArg) -> Self::Output {
115+
if memarg.align != ($width as u32).trailing_zeros() as u8 {
116+
return Err(crate::ParseError::Other("invalid atomic alignment".into()));
117+
}
118+
let address = self.metadata.memory_size(memarg.memory)?;
119+
self.mark_memory(memarg.memory);
120+
let memory = self.push128(tinywasm_types::Operand128::<tinywasm_types::MemoryOperand>::new(
121+
memarg.offset, memarg.memory,
122+
))?;
123+
let is_64 = lowering_ops!(@atomic_is64 [$($input),*] [$($output),*]);
124+
let arg = tinywasm_types::AtomicArg::new(
125+
memory, tinywasm_types::AtomicWidth::from_bytes($width), is_64, tinywasm_types::AtomicOp::$op,
126+
);
127+
self.emit(
128+
&[$(lowering_ops!(@size $input, address)),*],
129+
&[$(lowering_ops!(@size $output, address)),*],
130+
tinywasm_types::Instruction::Atomic(arg),
131+
)
132+
}
133+
};
134+
(@atomic_is64 [Addr, S64 $(, S64)*] $outputs:tt) => { true };
135+
(@atomic_is64 [Addr] [S64]) => { true };
136+
(@atomic_is64 $inputs:tt $outputs:tt) => { false };
107137
(@global $inputs:tt => $outputs:tt $($operator:tt)*) => {
108138
lowering_ops!(@resolved global_size $inputs => $outputs $($operator)*);
109139
};

‎crates/parser/src/visit.rs‎

Lines changed: 67 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use alloc::{
1111
vec::Vec,
1212
};
1313
use tinywasm_types::{
14-
AtomicArg, AtomicOp, AtomicWaitOp, AtomicWidth, BinOp, BinOp128, CmpOp, ExceptionHandler, Global, Import,
15-
ImportKind, Instruction, MemoryType, Operand64, Operand64Idx, Operand128, Operand128Idx, StorageType,
16-
TableDefinition, TagType, TypeSection, ValueCounts, ValueLane, WasmFunctionData,
14+
AtomicWaitOp, BinOp, BinOp128, CmpOp, ExceptionHandler, Global, Import, ImportKind, Instruction, MemoryType,
15+
Operand64, Operand64Idx, Operand128, Operand128Idx, StorageType, TableDefinition, TagType, TypeSection,
16+
ValueCounts, ValueLane, WasmFunctionData,
1717
};
1818
use wasmparser::{FunctionBody, OperatorsReader, OperatorsReaderAllocations, VisitSimdOperator};
1919

@@ -512,37 +512,6 @@ pub(crate) fn process_operators_and_validate(
512512
Ok((instructions, builder.data, builder.uses_local_memory, validator.into_allocations(), reader.into_allocations()))
513513
}
514514

515-
macro_rules! atomic_visitors {
516-
($($op:ident, $inputs:tt => $outputs:tt: $(($visit:ident, $width:literal)),+;)*) => {
517-
$(atomic_visitors!(@group $op, $inputs => $outputs: $(($visit, $width)),+);)*
518-
};
519-
(@group $op:ident, $inputs:tt => $outputs:tt: $(($visit:ident, $width:literal)),+) => {
520-
$(atomic_visitors!(@one $op, $inputs => $outputs: $visit, $width);)+
521-
};
522-
(@one $op:ident, [$($input:ident),*] => [$($output:ident),*]: $visit:ident, $width:literal) => {
523-
fn $visit(&mut self, memarg: wasmparser::MemArg) -> Self::Output {
524-
if memarg.align != ($width as u32).trailing_zeros() as u8 {
525-
return Err(crate::ParseError::Other("invalid atomic alignment".into()));
526-
}
527-
let address = self.metadata.memory_size(memarg.memory)?;
528-
self.mark_memory(memarg.memory);
529-
let memory = self.push128(Operand128::<tinywasm_types::MemoryOperand>::new(memarg.offset, memarg.memory))?;
530-
let is_64 = atomic_visitors!(@is64 [$($input),*] [$($output),*]);
531-
let arg = AtomicArg::new(memory, AtomicWidth::from_bytes($width), is_64, AtomicOp::$op);
532-
self.emit(
533-
&[$(atomic_visitors!(@size $input, address)),*],
534-
&[$(atomic_visitors!(@size $output, address)),*],
535-
Instruction::Atomic(arg),
536-
)
537-
}
538-
};
539-
(@size Addr, $address:ident) => { $address };
540-
(@size $lane:ident, $address:ident) => { ValueLane::$lane };
541-
(@is64 [Addr, S64 $(, S64)*] $outputs:tt) => { true };
542-
(@is64 [Addr] [S64]) => { true };
543-
(@is64 $inputs:tt $outputs:tt) => { false };
544-
}
545-
546515
impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder<'_> {
547516
type Output = Result<()>;
548517

@@ -566,28 +535,71 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder<'_> {
566535
self.atomic_wait(memarg, 8, AtomicWaitOp::Wait64)
567536
}
568537

569-
atomic_visitors! {
570-
Load, [Addr] => [S32]: (visit_i32_atomic_load, 4), (visit_i32_atomic_load8_u, 1), (visit_i32_atomic_load16_u, 2);
571-
Load, [Addr] => [S64]: (visit_i64_atomic_load, 8), (visit_i64_atomic_load8_u, 1), (visit_i64_atomic_load16_u, 2), (visit_i64_atomic_load32_u, 4);
572-
Store, [Addr, S32] => []: (visit_i32_atomic_store, 4), (visit_i32_atomic_store8, 1), (visit_i32_atomic_store16, 2);
573-
Store, [Addr, S64] => []: (visit_i64_atomic_store, 8), (visit_i64_atomic_store8, 1), (visit_i64_atomic_store16, 2), (visit_i64_atomic_store32, 4);
574-
Add, [Addr, S32] => [S32]: (visit_i32_atomic_rmw_add, 4), (visit_i32_atomic_rmw8_add_u, 1), (visit_i32_atomic_rmw16_add_u, 2);
575-
Add, [Addr, S64] => [S64]: (visit_i64_atomic_rmw_add, 8), (visit_i64_atomic_rmw8_add_u, 1), (visit_i64_atomic_rmw16_add_u, 2), (visit_i64_atomic_rmw32_add_u, 4);
576-
Sub, [Addr, S32] => [S32]: (visit_i32_atomic_rmw_sub, 4), (visit_i32_atomic_rmw8_sub_u, 1), (visit_i32_atomic_rmw16_sub_u, 2);
577-
Sub, [Addr, S64] => [S64]: (visit_i64_atomic_rmw_sub, 8), (visit_i64_atomic_rmw8_sub_u, 1), (visit_i64_atomic_rmw16_sub_u, 2), (visit_i64_atomic_rmw32_sub_u, 4);
578-
And, [Addr, S32] => [S32]: (visit_i32_atomic_rmw_and, 4), (visit_i32_atomic_rmw8_and_u, 1), (visit_i32_atomic_rmw16_and_u, 2);
579-
And, [Addr, S64] => [S64]: (visit_i64_atomic_rmw_and, 8), (visit_i64_atomic_rmw8_and_u, 1), (visit_i64_atomic_rmw16_and_u, 2), (visit_i64_atomic_rmw32_and_u, 4);
580-
Or, [Addr, S32] => [S32]: (visit_i32_atomic_rmw_or, 4), (visit_i32_atomic_rmw8_or_u, 1), (visit_i32_atomic_rmw16_or_u, 2);
581-
Or, [Addr, S64] => [S64]: (visit_i64_atomic_rmw_or, 8), (visit_i64_atomic_rmw8_or_u, 1), (visit_i64_atomic_rmw16_or_u, 2), (visit_i64_atomic_rmw32_or_u, 4);
582-
Xor, [Addr, S32] => [S32]: (visit_i32_atomic_rmw_xor, 4), (visit_i32_atomic_rmw8_xor_u, 1), (visit_i32_atomic_rmw16_xor_u, 2);
583-
Xor, [Addr, S64] => [S64]: (visit_i64_atomic_rmw_xor, 8), (visit_i64_atomic_rmw8_xor_u, 1), (visit_i64_atomic_rmw16_xor_u, 2), (visit_i64_atomic_rmw32_xor_u, 4);
584-
Xchg, [Addr, S32] => [S32]: (visit_i32_atomic_rmw_xchg, 4), (visit_i32_atomic_rmw8_xchg_u, 1), (visit_i32_atomic_rmw16_xchg_u, 2);
585-
Xchg, [Addr, S64] => [S64]: (visit_i64_atomic_rmw_xchg, 8), (visit_i64_atomic_rmw8_xchg_u, 1), (visit_i64_atomic_rmw16_xchg_u, 2), (visit_i64_atomic_rmw32_xchg_u, 4);
586-
Cmpxchg, [Addr, S32, S32] => [S32]: (visit_i32_atomic_rmw_cmpxchg, 4), (visit_i32_atomic_rmw8_cmpxchg_u, 1), (visit_i32_atomic_rmw16_cmpxchg_u, 2);
587-
Cmpxchg, [Addr, S64, S64] => [S64]: (visit_i64_atomic_rmw_cmpxchg, 8), (visit_i64_atomic_rmw8_cmpxchg_u, 1), (visit_i64_atomic_rmw16_cmpxchg_u, 2), (visit_i64_atomic_rmw32_cmpxchg_u, 4);
588-
}
589-
590538
lowering_ops! {
539+
atomic Load [Addr] => [S32] {
540+
visit_i32_atomic_load => 4, visit_i32_atomic_load8_u => 1, visit_i32_atomic_load16_u => 2,
541+
}
542+
atomic Load [Addr] => [S64] {
543+
visit_i64_atomic_load => 8, visit_i64_atomic_load8_u => 1,
544+
visit_i64_atomic_load16_u => 2, visit_i64_atomic_load32_u => 4,
545+
}
546+
atomic Store [Addr, S32] => [] {
547+
visit_i32_atomic_store => 4, visit_i32_atomic_store8 => 1, visit_i32_atomic_store16 => 2,
548+
}
549+
atomic Store [Addr, S64] => [] {
550+
visit_i64_atomic_store => 8, visit_i64_atomic_store8 => 1,
551+
visit_i64_atomic_store16 => 2, visit_i64_atomic_store32 => 4,
552+
}
553+
atomic Add [Addr, S32] => [S32] {
554+
visit_i32_atomic_rmw_add => 4, visit_i32_atomic_rmw8_add_u => 1, visit_i32_atomic_rmw16_add_u => 2,
555+
}
556+
atomic Add [Addr, S64] => [S64] {
557+
visit_i64_atomic_rmw_add => 8, visit_i64_atomic_rmw8_add_u => 1,
558+
visit_i64_atomic_rmw16_add_u => 2, visit_i64_atomic_rmw32_add_u => 4,
559+
}
560+
atomic Sub [Addr, S32] => [S32] {
561+
visit_i32_atomic_rmw_sub => 4, visit_i32_atomic_rmw8_sub_u => 1, visit_i32_atomic_rmw16_sub_u => 2,
562+
}
563+
atomic Sub [Addr, S64] => [S64] {
564+
visit_i64_atomic_rmw_sub => 8, visit_i64_atomic_rmw8_sub_u => 1,
565+
visit_i64_atomic_rmw16_sub_u => 2, visit_i64_atomic_rmw32_sub_u => 4,
566+
}
567+
atomic And [Addr, S32] => [S32] {
568+
visit_i32_atomic_rmw_and => 4, visit_i32_atomic_rmw8_and_u => 1, visit_i32_atomic_rmw16_and_u => 2,
569+
}
570+
atomic And [Addr, S64] => [S64] {
571+
visit_i64_atomic_rmw_and => 8, visit_i64_atomic_rmw8_and_u => 1,
572+
visit_i64_atomic_rmw16_and_u => 2, visit_i64_atomic_rmw32_and_u => 4,
573+
}
574+
atomic Or [Addr, S32] => [S32] {
575+
visit_i32_atomic_rmw_or => 4, visit_i32_atomic_rmw8_or_u => 1, visit_i32_atomic_rmw16_or_u => 2,
576+
}
577+
atomic Or [Addr, S64] => [S64] {
578+
visit_i64_atomic_rmw_or => 8, visit_i64_atomic_rmw8_or_u => 1,
579+
visit_i64_atomic_rmw16_or_u => 2, visit_i64_atomic_rmw32_or_u => 4,
580+
}
581+
atomic Xor [Addr, S32] => [S32] {
582+
visit_i32_atomic_rmw_xor => 4, visit_i32_atomic_rmw8_xor_u => 1, visit_i32_atomic_rmw16_xor_u => 2,
583+
}
584+
atomic Xor [Addr, S64] => [S64] {
585+
visit_i64_atomic_rmw_xor => 8, visit_i64_atomic_rmw8_xor_u => 1,
586+
visit_i64_atomic_rmw16_xor_u => 2, visit_i64_atomic_rmw32_xor_u => 4,
587+
}
588+
atomic Xchg [Addr, S32] => [S32] {
589+
visit_i32_atomic_rmw_xchg => 4, visit_i32_atomic_rmw8_xchg_u => 1, visit_i32_atomic_rmw16_xchg_u => 2,
590+
}
591+
atomic Xchg [Addr, S64] => [S64] {
592+
visit_i64_atomic_rmw_xchg => 8, visit_i64_atomic_rmw8_xchg_u => 1,
593+
visit_i64_atomic_rmw16_xchg_u => 2, visit_i64_atomic_rmw32_xchg_u => 4,
594+
}
595+
atomic Cmpxchg [Addr, S32, S32] => [S32] {
596+
visit_i32_atomic_rmw_cmpxchg => 4, visit_i32_atomic_rmw8_cmpxchg_u => 1,
597+
visit_i32_atomic_rmw16_cmpxchg_u => 2,
598+
}
599+
atomic Cmpxchg [Addr, S64, S64] => [S64] {
600+
visit_i64_atomic_rmw_cmpxchg => 8, visit_i64_atomic_rmw8_cmpxchg_u => 1,
601+
visit_i64_atomic_rmw16_cmpxchg_u => 2, visit_i64_atomic_rmw32_cmpxchg_u => 4,
602+
}
591603
memory [Addr] => [S32] {
592604
visit_i32_load => I32Load [load(Instruction::LoadLocal32)],
593605
visit_f32_load => F32Load [load(Instruction::LoadLocal32)],

0 commit comments

Comments
 (0)