wasmer_interface_types_fl/decoders/
binary.rs

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