wasmer_interface_types/decoders/
binary.rs

1//! Parse the WIT binary representation into an [AST](crate::ast).
2
3use crate::{ast::*, interpreter::Instruction, types::*, vec1::Vec1};
4use nom::{
5    error::{make_error, ErrorKind, ParseError},
6    Err, IResult,
7};
8use std::{convert::TryFrom, str};
9
10/// Parse a type kind.
11impl TryFrom<u8> for TypeKind {
12    type Error = &'static str;
13
14    fn try_from(code: u8) -> Result<Self, Self::Error> {
15        Ok(match code {
16            0x00 => Self::Function,
17            0x01 => Self::Record,
18            _ => return Err("Unknown type kind code."),
19        })
20    }
21}
22
23/// Parse an interface kind.
24impl TryFrom<u8> for InterfaceKind {
25    type Error = &'static str;
26
27    fn try_from(code: u8) -> Result<Self, Self::Error> {
28        Ok(match code {
29            0x00 => Self::Type,
30            0x01 => Self::Import,
31            0x02 => Self::Adapter,
32            0x03 => Self::Export,
33            0x04 => Self::Implementation,
34            _ => return Err("Unknown interface kind code."),
35        })
36    }
37}
38
39/// Parse a byte.
40fn byte<'input, E: ParseError<&'input [u8]>>(input: &'input [u8]) -> IResult<&'input [u8], u8, E> {
41    if input.is_empty() {
42        return Err(Err::Error(make_error(input, ErrorKind::Eof)));
43    }
44
45    Ok((&input[1..], input[0]))
46}
47
48/// Parse an unsigned Little Endian Based (LEB) with value no larger
49/// than a 64-bits number. Read
50/// [LEB128](https://en.wikipedia.org/wiki/LEB128) to learn more, or
51/// the Variable Length Data Section from the [DWARF 4
52/// standard](http://dwarfstd.org/doc/DWARF4.pdf).
53fn uleb<'input, E: ParseError<&'input [u8]>>(input: &'input [u8]) -> IResult<&'input [u8], u64, E> {
54    if input.is_empty() {
55        return Err(Err::Error(make_error(input, ErrorKind::Eof)));
56    }
57
58    let (output, bytes) = match input.iter().position(|&byte| byte & 0x80 == 0) {
59        Some(length) if length <= 8 => (&input[length + 1..], &input[..=length]),
60        Some(_) => return Err(Err::Error(make_error(input, ErrorKind::TooLarge))),
61        None => return Err(Err::Error(make_error(input, ErrorKind::Eof))),
62    };
63
64    Ok((
65        output,
66        bytes
67            .iter()
68            .rev()
69            .fold(0, |acc, byte| (acc << 7) | u64::from(byte & 0x7f)),
70    ))
71}
72
73/// Parse an interface type.
74fn ty<'input, E: ParseError<&'input [u8]>>(
75    mut input: &'input [u8],
76) -> IResult<&'input [u8], InterfaceType, E> {
77    if input.is_empty() {
78        return Err(Err::Error(make_error(input, ErrorKind::Eof)));
79    }
80
81    consume!((input, opcode) = byte(input)?);
82
83    let ty = match opcode {
84        0x00 => InterfaceType::S8,
85        0x01 => InterfaceType::S16,
86        0x02 => InterfaceType::S32,
87        0x03 => InterfaceType::S64,
88        0x04 => InterfaceType::U8,
89        0x05 => InterfaceType::U16,
90        0x06 => InterfaceType::U32,
91        0x07 => InterfaceType::U64,
92        0x08 => InterfaceType::F32,
93        0x09 => InterfaceType::F64,
94        0x0a => InterfaceType::String,
95        0x0b => InterfaceType::Anyref,
96        0x0c => InterfaceType::I32,
97        0x0d => InterfaceType::I64,
98        0x0e => {
99            consume!((input, record_type) = record_type(input)?);
100
101            InterfaceType::Record(record_type)
102        }
103        _ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))),
104    };
105
106    Ok((input, ty))
107}
108
109/// Parse a record type.
110fn record_type<'input, E: ParseError<&'input [u8]>>(
111    input: &'input [u8],
112) -> IResult<&'input [u8], RecordType, E> {
113    let (output, fields) = list(input, ty)?;
114
115    Ok((
116        output,
117        RecordType {
118            fields: Vec1::new(fields).expect("Record must have at least one field, zero given."),
119        },
120    ))
121}
122
123/// Parse a UTF-8 string.
124fn string<'input, E: ParseError<&'input [u8]>>(
125    input: &'input [u8],
126) -> IResult<&'input [u8], &'input str, E> {
127    if input.is_empty() {
128        return Err(Err::Error(make_error(input, ErrorKind::Eof)));
129    }
130
131    let length = input[0] as usize;
132    let input = &input[1..];
133
134    if input.len() < length {
135        return Err(Err::Error(make_error(input, ErrorKind::Eof)));
136    }
137
138    Ok((
139        &input[length..],
140        str::from_utf8(&input[..length])
141            .map_err(|_| Err::Error(make_error(input, ErrorKind::ParseTo)))?,
142    ))
143}
144
145/// Parse a list, with an item parser.
146#[allow(clippy::type_complexity)]
147fn list<'input, I, E: ParseError<&'input [u8]>>(
148    input: &'input [u8],
149    item_parser: fn(&'input [u8]) -> IResult<&'input [u8], I, E>,
150) -> IResult<&'input [u8], Vec<I>, E> {
151    if input.is_empty() {
152        return Err(Err::Error(make_error(input, ErrorKind::Eof)));
153    }
154
155    let length = input[0] as usize;
156    let mut input = &input[1..];
157
158    if input.len() < length {
159        return Err(Err::Error(make_error(input, ErrorKind::Eof)));
160    }
161
162    let mut items = Vec::with_capacity(length as usize);
163
164    for _ in 0..length {
165        consume!((input, item) = item_parser(input)?);
166        items.push(item);
167    }
168
169    Ok((input, items))
170}
171
172/// Parse an instruction with its arguments.
173fn instruction<'input, E: ParseError<&'input [u8]>>(
174    input: &'input [u8],
175) -> IResult<&'input [u8], Instruction, E> {
176    let (mut input, opcode) = byte(input)?;
177
178    Ok(match opcode {
179        0x00 => {
180            consume!((input, argument_0) = uleb(input)?);
181
182            (
183                input,
184                Instruction::ArgumentGet {
185                    index: argument_0 as u32,
186                },
187            )
188        }
189
190        0x01 => {
191            consume!((input, argument_0) = uleb(input)?);
192
193            (
194                input,
195                Instruction::CallCore {
196                    function_index: argument_0 as u32,
197                },
198            )
199        }
200
201        0x02 => (input, Instruction::S8FromI32),
202        0x03 => (input, Instruction::S8FromI64),
203        0x04 => (input, Instruction::S16FromI32),
204        0x05 => (input, Instruction::S16FromI64),
205        0x06 => (input, Instruction::S32FromI32),
206        0x07 => (input, Instruction::S32FromI64),
207        0x08 => (input, Instruction::S64FromI32),
208        0x09 => (input, Instruction::S64FromI64),
209        0x0a => (input, Instruction::I32FromS8),
210        0x0b => (input, Instruction::I32FromS16),
211        0x0c => (input, Instruction::I32FromS32),
212        0x0d => (input, Instruction::I32FromS64),
213        0x0e => (input, Instruction::I64FromS8),
214        0x0f => (input, Instruction::I64FromS16),
215        0x10 => (input, Instruction::I64FromS32),
216        0x11 => (input, Instruction::I64FromS64),
217        0x12 => (input, Instruction::U8FromI32),
218        0x13 => (input, Instruction::U8FromI64),
219        0x14 => (input, Instruction::U16FromI32),
220        0x15 => (input, Instruction::U16FromI64),
221        0x16 => (input, Instruction::U32FromI32),
222        0x17 => (input, Instruction::U32FromI64),
223        0x18 => (input, Instruction::U64FromI32),
224        0x19 => (input, Instruction::U64FromI64),
225        0x1a => (input, Instruction::I32FromU8),
226        0x1b => (input, Instruction::I32FromU16),
227        0x1c => (input, Instruction::I32FromU32),
228        0x1d => (input, Instruction::I32FromU64),
229        0x1e => (input, Instruction::I64FromU8),
230        0x1f => (input, Instruction::I64FromU16),
231        0x20 => (input, Instruction::I64FromU32),
232        0x21 => (input, Instruction::I64FromU64),
233
234        0x22 => (input, Instruction::StringLiftMemory),
235        0x23 => (input, Instruction::StringLowerMemory),
236        0x24 => (input, Instruction::StringSize),
237
238        0x25 => {
239            consume!((input, argument_0) = uleb(input)?);
240
241            (
242                input,
243                Instruction::RecordLift {
244                    type_index: argument_0 as u32,
245                },
246            )
247        }
248        0x26 => {
249            consume!((input, argument_0) = uleb(input)?);
250
251            (
252                input,
253                Instruction::RecordLower {
254                    type_index: argument_0 as u32,
255                },
256            )
257        }
258
259        _ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))),
260    })
261}
262
263/// Parse a list of types.
264fn types<'input, E: ParseError<&'input [u8]>>(
265    mut input: &'input [u8],
266) -> IResult<&'input [u8], Vec<Type>, E> {
267    consume!((input, number_of_types) = uleb(input)?);
268
269    let mut types = Vec::with_capacity(number_of_types as usize);
270
271    for _ in 0..number_of_types {
272        consume!((input, type_kind) = byte(input)?);
273
274        let type_kind = TypeKind::try_from(type_kind)
275            .map_err(|_| Err::Error(make_error(input, ErrorKind::ParseTo)))?;
276
277        match type_kind {
278            TypeKind::Function => {
279                consume!((input, inputs) = list(input, ty)?);
280                consume!((input, outputs) = list(input, ty)?);
281
282                types.push(Type::Function { inputs, outputs });
283            }
284
285            TypeKind::Record => {
286                consume!((input, record_type) = record_type(input)?);
287
288                types.push(Type::Record(record_type));
289            }
290        }
291    }
292
293    Ok((input, types))
294}
295
296/// Parse a list of imports.
297fn imports<'input, E: ParseError<&'input [u8]>>(
298    mut input: &'input [u8],
299) -> IResult<&'input [u8], Vec<Import>, E> {
300    consume!((input, number_of_imports) = uleb(input)?);
301
302    let mut imports = Vec::with_capacity(number_of_imports as usize);
303
304    for _ in 0..number_of_imports {
305        consume!((input, namespace) = string(input)?);
306        consume!((input, name) = string(input)?);
307        consume!((input, signature_type) = uleb(input)?);
308
309        imports.push(Import {
310            namespace,
311            name,
312            signature_type: signature_type as u32,
313        });
314    }
315
316    Ok((input, imports))
317}
318
319/// Parse a list of adapters.
320fn adapters<'input, E: ParseError<&'input [u8]>>(
321    mut input: &'input [u8],
322) -> IResult<&'input [u8], Vec<Adapter>, E> {
323    consume!((input, number_of_adapters) = uleb(input)?);
324
325    let mut adapters = Vec::with_capacity(number_of_adapters as usize);
326
327    for _ in 0..number_of_adapters {
328        consume!((input, function_type) = uleb(input)?);
329        consume!((input, instructions) = list(input, instruction)?);
330
331        adapters.push(Adapter {
332            function_type: function_type as u32,
333            instructions,
334        });
335    }
336
337    Ok((input, adapters))
338}
339
340/// Parse a list of exports.
341fn exports<'input, E: ParseError<&'input [u8]>>(
342    mut input: &'input [u8],
343) -> IResult<&'input [u8], Vec<Export>, E> {
344    consume!((input, number_of_exports) = uleb(input)?);
345
346    let mut exports = Vec::with_capacity(number_of_exports as usize);
347
348    for _ in 0..number_of_exports {
349        consume!((input, name) = string(input)?);
350        consume!((input, function_type) = uleb(input)?);
351
352        exports.push(Export {
353            name,
354            function_type: function_type as u32,
355        });
356    }
357
358    Ok((input, exports))
359}
360
361/// Parse a list of implementations.
362fn implementations<'input, E: ParseError<&'input [u8]>>(
363    mut input: &'input [u8],
364) -> IResult<&'input [u8], Vec<Implementation>, E> {
365    consume!((input, number_of_implementations) = uleb(input)?);
366
367    let mut implementations = Vec::with_capacity(number_of_implementations as usize);
368
369    for _ in 0..number_of_implementations {
370        consume!((input, core_function_type) = uleb(input)?);
371        consume!((input, adapter_function_type) = uleb(input)?);
372
373        implementations.push(Implementation {
374            core_function_type: core_function_type as u32,
375            adapter_function_type: adapter_function_type as u32,
376        });
377    }
378
379    Ok((input, implementations))
380}
381
382/// Parse complete interfaces.
383fn interfaces<'input, E: ParseError<&'input [u8]>>(
384    bytes: &'input [u8],
385) -> IResult<&'input [u8], Interfaces, E> {
386    let mut input = bytes;
387
388    let mut all_types = vec![];
389    let mut all_imports = vec![];
390    let mut all_adapters = vec![];
391    let mut all_exports = vec![];
392    let mut all_implementations = vec![];
393
394    while !input.is_empty() {
395        consume!((input, interface_kind) = byte(input)?);
396
397        let interface_kind = InterfaceKind::try_from(interface_kind)
398            .map_err(|_| Err::Error(make_error(input, ErrorKind::ParseTo)))?;
399
400        match interface_kind {
401            InterfaceKind::Type => {
402                consume!((input, mut new_types) = types(input)?);
403                all_types.append(&mut new_types);
404            }
405
406            InterfaceKind::Import => {
407                consume!((input, mut new_imports) = imports(input)?);
408                all_imports.append(&mut new_imports);
409            }
410
411            InterfaceKind::Adapter => {
412                consume!((input, mut new_adapters) = adapters(input)?);
413                all_adapters.append(&mut new_adapters);
414            }
415
416            InterfaceKind::Export => {
417                consume!((input, mut new_exports) = exports(input)?);
418                all_exports.append(&mut new_exports);
419            }
420
421            InterfaceKind::Implementation => {
422                consume!((input, mut new_implementations) = implementations(input)?);
423                all_implementations.append(&mut new_implementations)
424            }
425        }
426    }
427
428    Ok((
429        input,
430        Interfaces {
431            types: all_types,
432            imports: all_imports,
433            adapters: all_adapters,
434            exports: all_exports,
435            implementations: all_implementations,
436        },
437    ))
438}
439
440/// Parse a sequence of bytes, expecting it to be a valid WIT binary
441/// representation, into an [`Interfaces`](crate::ast::Interfaces)
442/// structure.
443///
444/// # Example
445///
446/// ```rust
447/// use wasmer_interface_types::{
448///     ast::{Adapter, Export, Implementation, Import, Interfaces, Type},
449///     decoders::binary::parse,
450///     interpreter::Instruction,
451///     types::InterfaceType,
452/// };
453///
454/// let input = &[
455///     0x00, // type section
456///     0x01, // 1 type
457///     0x00, // function type
458///     0x01, // list of 1 item
459///     0x00, // S8
460///     0x01, // list of 1 item
461///     0x01, // S16
462///     //
463///     0x01, // import section
464///     0x01, // 1 import
465///     0x02, // string of 2 bytes
466///     0x61, 0x62, // "a", "b"
467///     0x01, // string of 1 byte
468///     0x63, // "c"
469///     0x00, // signature type
470///     //
471///     0x02, // adapter section
472///     0x01, // 1 adapter
473///     0x00, // function type
474///     0x01, // list of 1 item
475///     0x00, 0x01, // ArgumentGet { index: 1 }
476///     //
477///     0x03, // export section
478///     0x01, // 1 export
479///     0x02, // string of 2 bytes
480///     0x61, 0x62, // "a", "b"
481///     0x01, // function type
482///     //
483///     0x04, // implementation section
484///     0x01, // 1 implementation
485///     0x02, // core function type
486///     0x03, // adapter function type
487/// ];
488/// let output = Ok((
489///     &[] as &[u8],
490///     Interfaces {
491///         types: vec![Type::Function {
492///             inputs: vec![InterfaceType::S8],
493///             outputs: vec![InterfaceType::S16],
494///         }],
495///         imports: vec![Import {
496///             namespace: "ab",
497///             name: "c",
498///             signature_type: 0,
499///         }],
500///         adapters: vec![Adapter {
501///             function_type: 0,
502///             instructions: vec![Instruction::ArgumentGet { index: 1 }],
503///         }],
504///         exports: vec![Export {
505///             name: "ab",
506///             function_type: 1,
507///         }],
508///         implementations: vec![Implementation {
509///             core_function_type: 2,
510///             adapter_function_type: 3,
511///         }],
512///     },
513/// ));
514///
515/// assert_eq!(parse::<()>(input), output);
516/// ```
517pub fn parse<'input, E: ParseError<&'input [u8]>>(
518    bytes: &'input [u8],
519) -> IResult<&'input [u8], Interfaces, E> {
520    interfaces(bytes)
521}
522
523#[cfg(test)]
524mod tests {
525    use super::*;
526    use nom::{error, Err};
527
528    #[test]
529    fn test_byte() {
530        let input = &[0x01, 0x02, 0x03];
531        let output = Ok((&[0x02, 0x03][..], 0x01u8));
532
533        assert_eq!(byte::<()>(input), output);
534    }
535
536    #[test]
537    fn test_uleb_1_byte() {
538        let input = &[0x01, 0x02, 0x03];
539        let output = Ok((&[0x02, 0x03][..], 0x01u64));
540
541        assert_eq!(uleb::<()>(input), output);
542    }
543
544    #[test]
545    fn test_uleb_3_bytes() {
546        let input = &[0xfc, 0xff, 0x01, 0x02];
547        let output = Ok((&[0x02][..], 0x7ffcu64));
548
549        assert_eq!(uleb::<()>(input), output);
550    }
551
552    // Examples from Figure 22 of [DWARF 4
553    // standard](http://dwarfstd.org/doc/DWARF4.pdf).
554    #[test]
555    fn test_uleb_from_dwarf_standard() {
556        macro_rules! assert_uleb {
557            ($to_parse:expr => $expected_result:expr) => {
558                assert_eq!(uleb::<()>($to_parse), Ok((&[][..], $expected_result)));
559            };
560        }
561
562        assert_uleb!(&[2u8] => 2u64);
563        assert_uleb!(&[127u8] => 127u64);
564        assert_uleb!(&[0x80, 1u8] => 128u64);
565        assert_uleb!(&[1u8 | 0x80, 1] => 129u64);
566        assert_uleb!(&[2u8 | 0x80, 1] => 130u64);
567        assert_uleb!(&[57u8 | 0x80, 100] => 12857u64);
568    }
569
570    #[test]
571    fn test_uleb_eof() {
572        let input = &[0x80];
573
574        assert_eq!(
575            uleb::<(&[u8], error::ErrorKind)>(input),
576            Err(Err::Error((&input[..], error::ErrorKind::Eof))),
577        );
578    }
579
580    #[test]
581    fn test_uleb_overflow() {
582        let input = &[
583            0x01 | 0x80,
584            0x02 | 0x80,
585            0x03 | 0x80,
586            0x04 | 0x80,
587            0x05 | 0x80,
588            0x06 | 0x80,
589            0x07 | 0x80,
590            0x08 | 0x80,
591            0x09 | 0x80,
592            0x0a,
593        ];
594
595        assert_eq!(
596            uleb::<(&[u8], error::ErrorKind)>(input),
597            Err(Err::Error((&input[..], error::ErrorKind::TooLarge))),
598        );
599    }
600
601    #[test]
602    fn test_ty() {
603        let input = &[
604            0x0f, // list of 15 items
605            0x00, // S8
606            0x01, // S16
607            0x02, // S32
608            0x03, // S64
609            0x04, // U8
610            0x05, // U16
611            0x06, // U32
612            0x07, // U64
613            0x08, // F32
614            0x09, // F64
615            0x0a, // String
616            0x0b, // Anyref
617            0x0c, // I32
618            0x0d, // I64
619            0x0e, 0x01, 0x02, // Record
620            0x01,
621        ];
622        let output = Ok((
623            &[0x01][..],
624            vec![
625                InterfaceType::S8,
626                InterfaceType::S16,
627                InterfaceType::S32,
628                InterfaceType::S64,
629                InterfaceType::U8,
630                InterfaceType::U16,
631                InterfaceType::U32,
632                InterfaceType::U64,
633                InterfaceType::F32,
634                InterfaceType::F64,
635                InterfaceType::String,
636                InterfaceType::Anyref,
637                InterfaceType::I32,
638                InterfaceType::I64,
639                InterfaceType::Record(RecordType {
640                    fields: vec1![InterfaceType::S32],
641                }),
642            ],
643        ));
644
645        assert_eq!(list::<_, ()>(input, ty), output);
646    }
647
648    #[test]
649    fn test_record_type() {
650        let input = &[
651            0x03, // list of 3 items
652            0x01, // 1 field
653            0x0a, // String
654            0x02, // 2 fields
655            0x0a, // String
656            0x0c, // I32
657            0x03, // 3 fields
658            0x0a, // String
659            0x0e, // Record
660            0x02, // 2 fields
661            0x0c, // I32
662            0x0c, // I32
663            0x09, // F64
664            0x01,
665        ];
666        let output = Ok((
667            &[0x01][..],
668            vec![
669                RecordType {
670                    fields: vec1![InterfaceType::String],
671                },
672                RecordType {
673                    fields: vec1![InterfaceType::String, InterfaceType::I32],
674                },
675                RecordType {
676                    fields: vec1![
677                        InterfaceType::String,
678                        InterfaceType::Record(RecordType {
679                            fields: vec1![InterfaceType::I32, InterfaceType::I32],
680                        }),
681                        InterfaceType::F64,
682                    ],
683                },
684            ],
685        ));
686
687        assert_eq!(list::<_, ()>(input, record_type), output);
688    }
689
690    #[test]
691    fn test_string() {
692        let input = &[
693            0x03, // string of 3 bytes
694            0x61, // "a"
695            0x62, // "b"
696            0x63, // "c"
697            0x64, 0x65,
698        ];
699        let output = Ok((&[0x64, 0x65][..], "abc"));
700
701        assert_eq!(string::<()>(input), output);
702    }
703
704    #[test]
705    fn test_list() {
706        let input = &[
707            0x02, // list of 2 items
708            0x01, // string of 1 byte
709            0x61, // "a"
710            0x02, // string of 2 bytes
711            0x62, // "b"
712            0x63, // "c"
713            0x07,
714        ];
715        let output = Ok((&[0x07][..], vec!["a", "bc"]));
716
717        assert_eq!(list::<_, ()>(input, string), output);
718    }
719
720    #[test]
721    fn test_instructions() {
722        let input = &[
723            0x27, // list of 39 items
724            0x00, 0x01, // ArgumentGet { index: 1 }
725            0x01, 0x01, // CallCore { function_index: 1 }
726            0x02, // S8FromI32
727            0x03, // S8FromI64
728            0x04, // S16FromI32
729            0x05, // S16FromI64
730            0x06, // S32FromI32
731            0x07, // S32FromI64
732            0x08, // S64FromI32
733            0x09, // S64FromI64
734            0x0a, // I32FromS8
735            0x0b, // I32FromS16
736            0x0c, // I32FromS32
737            0x0d, // I32FromS64
738            0x0e, // I64FromS8
739            0x0f, // I64FromS16
740            0x10, // I64FromS32
741            0x11, // I64FromS64
742            0x12, // U8FromI32
743            0x13, // U8FromI64
744            0x14, // U16FromI32
745            0x15, // U16FromI64
746            0x16, // U32FromI32
747            0x17, // U32FromI64
748            0x18, // U64FromI32
749            0x19, // U64FromI64
750            0x1a, // I32FromU8
751            0x1b, // I32FromU16
752            0x1c, // I32FromU32
753            0x1d, // I32FromU64
754            0x1e, // I64FromU8
755            0x1f, // I64FromU16
756            0x20, // I64FromU32
757            0x21, // I64FromU64
758            0x22, // StringLiftMemory
759            0x23, // StringLowerMemory
760            0x24, // StringSize
761            0x25, 0x01, // RecordLift { type_index: 1 },
762            0x26, 0x01, // RecordLower { type_index: 1 },
763            0x0a,
764        ];
765        let output = Ok((
766            &[0x0a][..],
767            vec![
768                Instruction::ArgumentGet { index: 1 },
769                Instruction::CallCore { function_index: 1 },
770                Instruction::S8FromI32,
771                Instruction::S8FromI64,
772                Instruction::S16FromI32,
773                Instruction::S16FromI64,
774                Instruction::S32FromI32,
775                Instruction::S32FromI64,
776                Instruction::S64FromI32,
777                Instruction::S64FromI64,
778                Instruction::I32FromS8,
779                Instruction::I32FromS16,
780                Instruction::I32FromS32,
781                Instruction::I32FromS64,
782                Instruction::I64FromS8,
783                Instruction::I64FromS16,
784                Instruction::I64FromS32,
785                Instruction::I64FromS64,
786                Instruction::U8FromI32,
787                Instruction::U8FromI64,
788                Instruction::U16FromI32,
789                Instruction::U16FromI64,
790                Instruction::U32FromI32,
791                Instruction::U32FromI64,
792                Instruction::U64FromI32,
793                Instruction::U64FromI64,
794                Instruction::I32FromU8,
795                Instruction::I32FromU16,
796                Instruction::I32FromU32,
797                Instruction::I32FromU64,
798                Instruction::I64FromU8,
799                Instruction::I64FromU16,
800                Instruction::I64FromU32,
801                Instruction::I64FromU64,
802                Instruction::StringLiftMemory,
803                Instruction::StringLowerMemory,
804                Instruction::StringSize,
805                Instruction::RecordLift { type_index: 1 },
806                Instruction::RecordLower { type_index: 1 },
807            ],
808        ));
809
810        assert_eq!(list::<_, ()>(input, instruction), output);
811    }
812
813    #[test]
814    fn test_exports() {
815        let input = &[
816            0x02, // 2 exports
817            0x02, // string of 2 bytes
818            0x61, 0x62, // "a", "b"
819            0x01, // function type
820            0x02, // string of 2 bytes
821            0x63, 0x64, // "c", "d"
822            0x02, // function type
823        ];
824        let output = Ok((
825            &[] as &[u8],
826            vec![
827                Export {
828                    name: "ab",
829                    function_type: 1,
830                },
831                Export {
832                    name: "cd",
833                    function_type: 2,
834                },
835            ],
836        ));
837
838        assert_eq!(exports::<()>(input), output);
839    }
840
841    #[test]
842    fn test_types() {
843        let input = &[
844            0x02, // 2 type
845            0x00, // function type
846            0x02, // list of 2 items
847            0x02, // S32
848            0x02, // S32
849            0x01, // list of 2 items
850            0x02, // S32
851            0x01, // record type
852            0x02, // list of 2 items
853            0x02, // S32
854            0x02, // S32
855        ];
856        let output = Ok((
857            &[] as &[u8],
858            vec![
859                Type::Function {
860                    inputs: vec![InterfaceType::S32, InterfaceType::S32],
861                    outputs: vec![InterfaceType::S32],
862                },
863                Type::Record(RecordType {
864                    fields: vec1![InterfaceType::S32, InterfaceType::S32],
865                }),
866            ],
867        ));
868
869        assert_eq!(types::<()>(input), output);
870    }
871
872    #[test]
873    fn test_imports() {
874        let input = &[
875            0x02, // 2 imports
876            0x01, // string of 1 byte
877            0x61, // "a"
878            0x01, // string of 1 byte
879            0x62, // "b"
880            0x01, // signature type
881            0x01, // string of 1 byte
882            0x63, // "c"
883            0x01, // string of 1 byte
884            0x64, // "d"
885            0x02, // signature type
886        ];
887        let output = Ok((
888            &[] as &[u8],
889            vec![
890                Import {
891                    namespace: "a",
892                    name: "b",
893                    signature_type: 1,
894                },
895                Import {
896                    namespace: "c",
897                    name: "d",
898                    signature_type: 2,
899                },
900            ],
901        ));
902
903        assert_eq!(imports::<()>(input), output);
904    }
905
906    #[test]
907    fn test_adapters() {
908        let input = &[
909            0x01, // 1 adapters
910            0x00, // function type
911            0x01, // list of 1 item
912            0x00, 0x01, // ArgumentGet { index: 1 }
913        ];
914        let output = Ok((
915            &[] as &[u8],
916            vec![Adapter {
917                function_type: 0,
918                instructions: vec![Instruction::ArgumentGet { index: 1 }],
919            }],
920        ));
921
922        assert_eq!(adapters::<()>(input), output);
923    }
924
925    #[test]
926    fn test_parse() {
927        let input = &[
928            0x00, // type section
929            0x01, // 1 type
930            0x00, // function type
931            0x01, // list of 1 item
932            0x00, // S8
933            0x01, // list of 1 item
934            0x01, // S16
935            //
936            0x01, // import section
937            0x01, // 1 import
938            0x02, // string of 2 bytes
939            0x61, 0x62, // "a", "b"
940            0x01, // string of 1 byte
941            0x63, // "c"
942            0x00, // signature type
943            //
944            0x02, // adapter section
945            0x01, // 1 adapter
946            0x00, // function type
947            0x01, // list of 1 item
948            0x00, 0x01, // ArgumentGet { index: 1 }
949            //
950            0x03, // export section
951            0x01, // 1 export
952            0x02, // string of 2 bytes
953            0x61, 0x62, // "a", "b"
954            0x01, // function type
955            //
956            0x04, // implementation section
957            0x01, // 1 implementation
958            0x02, // core function type
959            0x03, // adapter function type
960        ];
961        let output = Ok((
962            &[] as &[u8],
963            Interfaces {
964                types: vec![Type::Function {
965                    inputs: vec![InterfaceType::S8],
966                    outputs: vec![InterfaceType::S16],
967                }],
968                imports: vec![Import {
969                    namespace: "ab",
970                    name: "c",
971                    signature_type: 0,
972                }],
973                adapters: vec![Adapter {
974                    function_type: 0,
975                    instructions: vec![Instruction::ArgumentGet { index: 1 }],
976                }],
977                exports: vec![Export {
978                    name: "ab",
979                    function_type: 1,
980                }],
981                implementations: vec![Implementation {
982                    core_function_type: 2,
983                    adapter_function_type: 3,
984                }],
985            },
986        ));
987
988        assert_eq!(interfaces::<()>(input), output);
989    }
990}