1#[macro_export]
6macro_rules! vec1 {
7 ($item:expr; 0) => {
8 compile_error!("Cannot create an empty `Vec1`, it violates its invariant.")
9 };
10
11 () => {
12 compile_error!("Cannot create an empty `Vec1`, it violates its invariant.")
13 };
14
15 ($item:expr; $length:expr) => {
16 {
17 crate::vec1::Vec1::new(vec![$item; $length]).unwrap()
18 }
19 };
20
21 ($($item:expr),+ $(,)?) => {
22 {
23 crate::vec1::Vec1::new(vec![$($item),*]).unwrap()
24 }
25 };
26}
27
28macro_rules! consume {
31 (($input:ident, $parser_output:ident) = $parser_expression:expr) => {
32 let (next_input, $parser_output) = $parser_expression;
33 $input = next_input;
34 };
35
36 (($input:ident, mut $parser_output:ident) = $parser_expression:expr) => {
37 let (next_input, mut $parser_output) = $parser_expression;
38 $input = next_input;
39 };
40}
41
42macro_rules! executable_instruction {
69 ($name:ident ( $($argument_name:ident: $argument_type:ty),* ) -> _ $implementation:block ) => {
70 pub(crate) fn $name<Instance, Export, LocalImport, Memory, MemoryView>(
71 $($argument_name: $argument_type),*
72 ) -> crate::interpreter::ExecutableInstruction<Instance, Export, LocalImport, Memory, MemoryView>
73 where
74 Export: crate::interpreter::wasm::structures::Export,
75 LocalImport: crate::interpreter::wasm::structures::LocalImport,
76 Memory: crate::interpreter::wasm::structures::Memory<MemoryView>,
77 MemoryView: crate::interpreter::wasm::structures::MemoryView,
78 Instance: crate::interpreter::wasm::structures::Instance<Export, LocalImport, Memory, MemoryView>,
79 {
80 #[allow(unused_imports)]
81 use crate::interpreter::{stack::Stackable};
82
83 Box::new($implementation)
84 }
85 };
86}
87
88#[cfg(test)]
89macro_rules! test_executable_instruction {
90 (
91 $test_name:ident =
92 instructions: [ $($instructions:expr),* $(,)* ],
93 invocation_inputs: [ $($invocation_inputs:expr),* $(,)* ],
94 instance: $instance:expr,
95 stack: [ $($stack:expr),* $(,)* ]
96 $(,)*
97 ) => {
98 #[test]
99 #[allow(non_snake_case, unused)]
100 fn $test_name() {
101 use crate::{
102 interpreter::{
103 instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
104 stack::Stackable,
105 Instruction, Interpreter,
106 },
107 types::InterfaceType,
108 values::InterfaceValue,
109 };
110 use std::{cell::Cell, collections::HashMap, convert::TryInto};
111
112 let interpreter: Interpreter<Instance, Export, LocalImport, Memory, MemoryView> =
113 (&vec![$($instructions),*]).try_into().unwrap();
114
115 let invocation_inputs = vec![$($invocation_inputs),*];
116 let mut instance = $instance;
117 let run = interpreter.run(&invocation_inputs, &mut instance);
118
119 let err = match &run {
120 Ok(_) => "".to_string(),
121 Err(e) => e.to_string(),
122 };
123
124 assert!(run.is_ok(), err);
125
126 let stack = run.unwrap();
127
128 assert_eq!(stack.as_slice(), &[$($stack),*]);
129 }
130 };
131
132 (
133 $test_name:ident =
134 instructions: [ $($instructions:expr),* $(,)* ],
135 invocation_inputs: [ $($invocation_inputs:expr),* $(,)* ],
136 instance: $instance:expr,
137 error: $error:expr
138 $(,)*
139 ) => {
140 #[test]
141 #[allow(non_snake_case, unused)]
142 fn $test_name() {
143 use crate::{
144 interpreter::{
145 instructions::tests::{Export, Instance, LocalImport, Memory, MemoryView},
146 stack::Stackable,
147 Instruction, Interpreter,
148 },
149 types::InterfaceType,
150 values::InterfaceValue,
151 };
152 use std::{cell::Cell, collections::HashMap, convert::TryInto};
153
154 let interpreter: Interpreter<Instance, Export, LocalImport, Memory, MemoryView> =
155 (&vec![$($instructions),*]).try_into().unwrap();
156
157 let invocation_inputs = vec![$($invocation_inputs),*];
158 let mut instance = $instance;
159 let run = interpreter.run(&invocation_inputs, &mut instance);
160
161 assert!(run.is_err());
162
163 let error = run.unwrap_err().to_string();
164
165 assert_eq!(error, String::from($error));
166 }
167 };
168}