1use 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
13impl 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
26impl 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
43fn 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
52fn 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
103fn 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
145fn 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
163fn 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
185fn 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#[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
234fn 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
368fn 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
404fn 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
427fn 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
448fn 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
469fn 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
490fn 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
572pub 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 #[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, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x01, 0x02, 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, 0x01, 0x0a, 0x02, 0x0a, 0x0c, 0x03, 0x0a, 0x0e, 0x02, 0x0c, 0x0c, 0x09, 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, 0x61, 0x62, 0x63, 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, 0x01, 0x61, 0x02, 0x62, 0x63, 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, 0x00, 0x01, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x01, 0x26, 0x01, 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 ],
943 ));
944
945 assert_eq!(list::<_, ()>(input, instruction), output);
946 }
947
948 #[test]
949 fn test_exports() {
950 let input = &[
951 0x02, 0x02, 0x61, 0x62, 0x01, 0x02, 0x63, 0x64, 0x02, ];
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, 0x00, 0x02, 0x02, 0x02, 0x01, 0x02, 0x01, 0x02, 0x02, 0x02, ];
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, 0x01, 0x61, 0x01, 0x62, 0x01, 0x01, 0x63, 0x01, 0x64, 0x02, ];
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, 0x00, 0x01, 0x00, 0x01, ];
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, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x61, 0x62, 0x01, 0x63, 0x00, 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, 0x03, 0x01, 0x02, 0x61, 0x62, 0x01, 0x04, 0x01, 0x02, 0x03, ];
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}