1use 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
10impl 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
23impl 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
39fn 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
48fn 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
73fn 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
109fn 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
123fn 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#[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
172fn 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
263fn 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
296fn 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
319fn 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
340fn 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
361fn 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
382fn 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
440pub 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 #[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, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x01, 0x02, 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, 0x01, 0x0a, 0x02, 0x0a, 0x0c, 0x03, 0x0a, 0x0e, 0x02, 0x0c, 0x0c, 0x09, 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, 0x61, 0x62, 0x63, 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, 0x01, 0x61, 0x02, 0x62, 0x63, 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, 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,
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, 0x02, 0x61, 0x62, 0x01, 0x02, 0x63, 0x64, 0x02, ];
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, 0x00, 0x02, 0x02, 0x02, 0x01, 0x02, 0x01, 0x02, 0x02, 0x02, ];
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, 0x01, 0x61, 0x01, 0x62, 0x01, 0x01, 0x63, 0x01, 0x64, 0x02, ];
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, 0x00, 0x01, 0x00, 0x01, ];
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, 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, ];
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}