1 /* Copyright 2018 Mozilla Foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 use std::convert::TryInto;
17 use std::fmt;
18 use std::str;
19 
20 use crate::limits::*;
21 
22 use crate::primitives::{
23     BinaryReaderError, BrTable, CustomSectionKind, ExternalKind, FuncType, GlobalType, Ieee32,
24     Ieee64, LinkingType, MemoryImmediate, MemoryType, NameType, Operator, RelocType,
25     ResizableLimits, ResizableLimits64, Result, SIMDLaneIndex, SectionCode, TableType, Type,
26     TypeOrFuncType, V128,
27 };
28 use crate::{EventType, ExportType, Import, ImportSectionEntryType, InstanceType, ModuleType};
29 
30 const MAX_WASM_BR_TABLE_SIZE: usize = MAX_WASM_FUNCTION_SIZE;
31 
is_name(name: &str, expected: &'static str) -> bool32 fn is_name(name: &str, expected: &'static str) -> bool {
33     name == expected
34 }
35 
is_name_prefix(name: &str, prefix: &'static str) -> bool36 fn is_name_prefix(name: &str, prefix: &'static str) -> bool {
37     name.starts_with(prefix)
38 }
39 
40 const WASM_MAGIC_NUMBER: &[u8; 4] = b"\0asm";
41 const WASM_EXPERIMENTAL_VERSION: u32 = 0xd;
42 const WASM_SUPPORTED_VERSION: u32 = 0x1;
43 
44 #[derive(Clone)]
45 pub(crate) struct SectionHeader<'a> {
46     pub code: SectionCode<'a>,
47     pub payload_start: usize,
48     pub payload_len: usize,
49 }
50 
51 /// Bytecode range in the WebAssembly module.
52 #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
53 pub struct Range {
54     /// The start bound of the range.
55     pub start: usize,
56     /// The end bound of the range.
57     pub end: usize,
58 }
59 
60 impl Range {
61     /// Constructs a new instance of `Range`.
62     ///
63     /// # Panics
64     /// If `start` is greater than `end`.
new(start: usize, end: usize) -> Range65     pub fn new(start: usize, end: usize) -> Range {
66         assert!(start <= end);
67         Range { start, end }
68     }
69 
70     /// Returns a new slice between `start` and `end - 1` from `data`.
slice<'a>(&self, data: &'a [u8]) -> &'a [u8]71     pub fn slice<'a>(&self, data: &'a [u8]) -> &'a [u8] {
72         &data[self.start..self.end]
73     }
74 }
75 
76 /// A binary reader of the WebAssembly structures and types.
77 #[derive(Clone, Debug, Hash)]
78 pub struct BinaryReader<'a> {
79     pub(crate) buffer: &'a [u8],
80     pub(crate) position: usize,
81     pub(crate) original_offset: usize,
82 }
83 
84 impl<'a> BinaryReader<'a> {
85     /// Constructs `BinaryReader` type.
86     ///
87     /// # Examples
88     /// ```
89     /// let fn_body = &vec![0x41, 0x00, 0x10, 0x00, 0x0B];
90     /// let mut reader = wasmparser::BinaryReader::new(fn_body);
91     /// while !reader.eof() {
92     ///     let op = reader.read_operator();
93     ///     println!("{:?}", op)
94     /// }
95     /// ```
new(data: &[u8]) -> BinaryReader96     pub fn new(data: &[u8]) -> BinaryReader {
97         BinaryReader {
98             buffer: data,
99             position: 0,
100             original_offset: 0,
101         }
102     }
103 
104     /// Constructs a `BinaryReader` with an explicit starting offset.
new_with_offset(data: &[u8], original_offset: usize) -> BinaryReader105     pub fn new_with_offset(data: &[u8], original_offset: usize) -> BinaryReader {
106         BinaryReader {
107             buffer: data,
108             position: 0,
109             original_offset,
110         }
111     }
112 
original_position(&self) -> usize113     pub fn original_position(&self) -> usize {
114         self.original_offset + self.position
115     }
116 
117     /// Returns a range from the starting offset to the end of the buffer.
range(&self) -> Range118     pub fn range(&self) -> Range {
119         Range {
120             start: self.original_offset,
121             end: self.original_offset + self.buffer.len(),
122         }
123     }
124 
remaining_buffer(&self) -> &'a [u8]125     pub(crate) fn remaining_buffer(&self) -> &'a [u8] {
126         &self.buffer[self.position..]
127     }
128 
ensure_has_byte(&self) -> Result<()>129     fn ensure_has_byte(&self) -> Result<()> {
130         if self.position < self.buffer.len() {
131             Ok(())
132         } else {
133             Err(BinaryReaderError::eof(self.original_position(), 1))
134         }
135     }
136 
ensure_has_bytes(&self, len: usize) -> Result<()>137     pub(crate) fn ensure_has_bytes(&self, len: usize) -> Result<()> {
138         if self.position + len <= self.buffer.len() {
139             Ok(())
140         } else {
141             let hint = self.position + len - self.buffer.len();
142             Err(BinaryReaderError::eof(self.original_position(), hint))
143         }
144     }
145 
read_var_u1(&mut self) -> Result<u32>146     fn read_var_u1(&mut self) -> Result<u32> {
147         let b = self.read_u8()?;
148         if (b & 0xFE) != 0 {
149             return Err(BinaryReaderError::new(
150                 "Invalid var_u1",
151                 self.original_position() - 1,
152             ));
153         }
154         Ok(b)
155     }
156 
read_var_i7(&mut self) -> Result<i32>157     fn read_var_i7(&mut self) -> Result<i32> {
158         let b = self.read_u8()?;
159         if (b & 0x80) != 0 {
160             return Err(BinaryReaderError::new(
161                 "Invalid var_i7",
162                 self.original_position() - 1,
163             ));
164         }
165         Ok((b << 25) as i32 >> 25)
166     }
167 
read_var_u7(&mut self) -> Result<u32>168     pub(crate) fn read_var_u7(&mut self) -> Result<u32> {
169         let b = self.read_u8()?;
170         if (b & 0x80) != 0 {
171             return Err(BinaryReaderError::new(
172                 "Invalid var_u7",
173                 self.original_position() - 1,
174             ));
175         }
176         Ok(b)
177     }
178 
read_type(&mut self) -> Result<Type>179     pub fn read_type(&mut self) -> Result<Type> {
180         let code = self.read_var_i7()?;
181         match code {
182             -0x01 => Ok(Type::I32),
183             -0x02 => Ok(Type::I64),
184             -0x03 => Ok(Type::F32),
185             -0x04 => Ok(Type::F64),
186             -0x05 => Ok(Type::V128),
187             -0x10 => Ok(Type::FuncRef),
188             -0x11 => Ok(Type::ExternRef),
189             -0x18 => Ok(Type::ExnRef),
190             -0x20 => Ok(Type::Func),
191             -0x40 => Ok(Type::EmptyBlockType),
192             _ => Err(BinaryReaderError::new(
193                 "Invalid type",
194                 self.original_position() - 1,
195             )),
196         }
197     }
198 
read_external_kind(&mut self) -> Result<ExternalKind>199     pub(crate) fn read_external_kind(&mut self) -> Result<ExternalKind> {
200         let code = self.read_u8()?;
201         match code {
202             0 => Ok(ExternalKind::Function),
203             1 => Ok(ExternalKind::Table),
204             2 => Ok(ExternalKind::Memory),
205             3 => Ok(ExternalKind::Global),
206             4 => Ok(ExternalKind::Event),
207             5 => Ok(ExternalKind::Module),
208             6 => Ok(ExternalKind::Instance),
209             7 => Ok(ExternalKind::Type),
210             _ => Err(BinaryReaderError::new(
211                 "Invalid external kind",
212                 self.original_position() - 1,
213             )),
214         }
215     }
216 
read_func_type(&mut self) -> Result<FuncType>217     pub(crate) fn read_func_type(&mut self) -> Result<FuncType> {
218         let params_len = self.read_var_u32()? as usize;
219         if params_len > MAX_WASM_FUNCTION_PARAMS {
220             return Err(BinaryReaderError::new(
221                 "function params size is out of bound",
222                 self.original_position() - 1,
223             ));
224         }
225         let mut params: Vec<Type> = Vec::with_capacity(params_len);
226         for _ in 0..params_len {
227             params.push(self.read_type()?);
228         }
229         let returns_len = self.read_var_u32()? as usize;
230         if returns_len > MAX_WASM_FUNCTION_RETURNS {
231             return Err(BinaryReaderError::new(
232                 "function returns size is out of bound",
233                 self.original_position() - 1,
234             ));
235         }
236         let mut returns: Vec<Type> = Vec::with_capacity(returns_len);
237         for _ in 0..returns_len {
238             returns.push(self.read_type()?);
239         }
240         Ok(FuncType {
241             params: params.into_boxed_slice(),
242             returns: returns.into_boxed_slice(),
243         })
244     }
245 
read_module_type(&mut self) -> Result<ModuleType<'a>>246     pub(crate) fn read_module_type(&mut self) -> Result<ModuleType<'a>> {
247         let pos = self.original_position();
248         let imports_len = self.read_var_u32()? as usize;
249         if imports_len > MAX_WASM_IMPORTS {
250             return Err(BinaryReaderError::new("imports size is out of bounds", pos));
251         }
252         Ok(ModuleType {
253             imports: (0..imports_len)
254                 .map(|_| self.read_import())
255                 .collect::<Result<_>>()?,
256             exports: self.read_export_types()?,
257         })
258     }
259 
read_instance_type(&mut self) -> Result<InstanceType<'a>>260     pub(crate) fn read_instance_type(&mut self) -> Result<InstanceType<'a>> {
261         Ok(InstanceType {
262             exports: self.read_export_types()?,
263         })
264     }
265 
read_export_types(&mut self) -> Result<Box<[ExportType<'a>]>>266     fn read_export_types(&mut self) -> Result<Box<[ExportType<'a>]>> {
267         let pos = self.original_position();
268         let exports_len = self.read_var_u32()? as usize;
269         if exports_len > MAX_WASM_EXPORTS {
270             return Err(BinaryReaderError::new("exports size is out of bound", pos));
271         }
272         (0..exports_len).map(|_| self.read_export_type()).collect()
273     }
274 
read_import(&mut self) -> Result<Import<'a>>275     pub(crate) fn read_import(&mut self) -> Result<Import<'a>> {
276         let module = self.read_string()?;
277         let field = self.read_string()?;
278 
279         // For the `field`, figure out if we're the experimental encoding of
280         // single-level imports for the module linking proposal (a single-byte
281         // string which is 0xc0, which is invalid utf-8) or if we have a second
282         // level of import.
283         let field = if field.is_empty() && self.buffer.get(self.position) == Some(&0xff) {
284             self.position += 1;
285             None
286         } else {
287             Some(field)
288         };
289 
290         let ty = self.read_import_desc()?;
291         Ok(Import { module, field, ty })
292     }
293 
read_export_type(&mut self) -> Result<ExportType<'a>>294     pub(crate) fn read_export_type(&mut self) -> Result<ExportType<'a>> {
295         let name = self.read_string()?;
296         let ty = self.read_import_desc()?;
297         Ok(ExportType { name, ty })
298     }
299 
read_import_desc(&mut self) -> Result<ImportSectionEntryType>300     pub(crate) fn read_import_desc(&mut self) -> Result<ImportSectionEntryType> {
301         Ok(match self.read_external_kind()? {
302             ExternalKind::Function => ImportSectionEntryType::Function(self.read_var_u32()?),
303             ExternalKind::Table => ImportSectionEntryType::Table(self.read_table_type()?),
304             ExternalKind::Memory => ImportSectionEntryType::Memory(self.read_memory_type()?),
305             ExternalKind::Event => ImportSectionEntryType::Event(self.read_event_type()?),
306             ExternalKind::Global => ImportSectionEntryType::Global(self.read_global_type()?),
307             ExternalKind::Module => ImportSectionEntryType::Module(self.read_var_u32()?),
308             ExternalKind::Instance => ImportSectionEntryType::Instance(self.read_var_u32()?),
309             ExternalKind::Type => {
310                 return Err(BinaryReaderError::new(
311                     "cannot import types",
312                     self.original_position() - 1,
313                 ))
314             }
315         })
316     }
317 
read_resizable_limits(&mut self, max_present: bool) -> Result<ResizableLimits>318     fn read_resizable_limits(&mut self, max_present: bool) -> Result<ResizableLimits> {
319         let initial = self.read_var_u32()?;
320         let maximum = if max_present {
321             Some(self.read_var_u32()?)
322         } else {
323             None
324         };
325         Ok(ResizableLimits { initial, maximum })
326     }
327 
read_resizable_limits64(&mut self, max_present: bool) -> Result<ResizableLimits64>328     fn read_resizable_limits64(&mut self, max_present: bool) -> Result<ResizableLimits64> {
329         let initial = self.read_var_u64()?;
330         let maximum = if max_present {
331             Some(self.read_var_u64()?)
332         } else {
333             None
334         };
335         Ok(ResizableLimits64 { initial, maximum })
336     }
337 
read_table_type(&mut self) -> Result<TableType>338     pub(crate) fn read_table_type(&mut self) -> Result<TableType> {
339         let element_type = self.read_type()?;
340         let flags = self.read_var_u32()?;
341         if (flags & !0x1) != 0 {
342             return Err(BinaryReaderError::new(
343                 "invalid table resizable limits flags",
344                 self.original_position() - 1,
345             ));
346         }
347         let limits = self.read_resizable_limits((flags & 0x1) != 0)?;
348         Ok(TableType {
349             element_type,
350             limits,
351         })
352     }
353 
read_memory_type(&mut self) -> Result<MemoryType>354     pub(crate) fn read_memory_type(&mut self) -> Result<MemoryType> {
355         let pos = self.original_position();
356         let flags = self.read_u8()?;
357         if (flags & !0x7) != 0 {
358             return Err(BinaryReaderError::new(
359                 "invalid table resizable limits flags",
360                 pos,
361             ));
362         }
363         if flags & 0x4 == 0 {
364             let limits = self.read_resizable_limits((flags & 0x1) != 0)?;
365             let shared = (flags & 0x2) != 0;
366             Ok(MemoryType::M32 { limits, shared })
367         } else {
368             let limits = self.read_resizable_limits64((flags & 0x1) != 0)?;
369             let shared = (flags & 0x2) != 0;
370             Ok(MemoryType::M64 { limits, shared })
371         }
372     }
373 
read_event_type(&mut self) -> Result<EventType>374     pub(crate) fn read_event_type(&mut self) -> Result<EventType> {
375         let attribute = self.read_var_u32()?;
376         if attribute != 0 {
377             return Err(BinaryReaderError::new(
378                 "invalid event attributes",
379                 self.original_position() - 1,
380             ));
381         }
382         let type_index = self.read_var_u32()?;
383         Ok(EventType { type_index })
384     }
385 
read_global_type(&mut self) -> Result<GlobalType>386     pub(crate) fn read_global_type(&mut self) -> Result<GlobalType> {
387         Ok(GlobalType {
388             content_type: self.read_type()?,
389             mutable: self.read_var_u1()? != 0,
390         })
391     }
392 
read_first_byte_and_var_u32(&mut self) -> Result<(u8, u32)>393     fn read_first_byte_and_var_u32(&mut self) -> Result<(u8, u32)> {
394         let pos = self.position;
395         let val = self.read_var_u32()?;
396         Ok((self.buffer[pos], val))
397     }
398 
read_memarg(&mut self) -> Result<MemoryImmediate>399     fn read_memarg(&mut self) -> Result<MemoryImmediate> {
400         let flags_pos = self.original_position();
401         let mut flags = self.read_var_u32()?;
402         let offset = self.read_var_u32()?;
403         let memory = if flags & (1 << 6) != 0 {
404             flags ^= 1 << 6;
405             self.read_var_u32()?
406         } else {
407             0
408         };
409         let align = if flags >= (1 << 6) {
410             return Err(BinaryReaderError::new("alignment too large", flags_pos));
411         } else {
412             flags as u8
413         };
414         Ok(MemoryImmediate {
415             align,
416             offset,
417             memory,
418         })
419     }
420 
read_section_code(&mut self, id: u32, offset: usize) -> Result<SectionCode<'a>>421     pub(crate) fn read_section_code(&mut self, id: u32, offset: usize) -> Result<SectionCode<'a>> {
422         match id {
423             0 => {
424                 let name = self.read_string()?;
425                 let kind = if is_name(name, "name") {
426                     CustomSectionKind::Name
427                 } else if is_name(name, "producers") {
428                     CustomSectionKind::Producers
429                 } else if is_name(name, "sourceMappingURL") {
430                     CustomSectionKind::SourceMappingURL
431                 } else if is_name_prefix(name, "reloc.") {
432                     CustomSectionKind::Reloc
433                 } else if is_name(name, "linking") {
434                     CustomSectionKind::Linking
435                 } else {
436                     CustomSectionKind::Unknown
437                 };
438                 Ok(SectionCode::Custom { name, kind })
439             }
440             1 => Ok(SectionCode::Type),
441             2 => Ok(SectionCode::Import),
442             3 => Ok(SectionCode::Function),
443             4 => Ok(SectionCode::Table),
444             5 => Ok(SectionCode::Memory),
445             6 => Ok(SectionCode::Global),
446             7 => Ok(SectionCode::Export),
447             8 => Ok(SectionCode::Start),
448             9 => Ok(SectionCode::Element),
449             10 => Ok(SectionCode::Code),
450             11 => Ok(SectionCode::Data),
451             12 => Ok(SectionCode::DataCount),
452             13 => Ok(SectionCode::Event),
453             14 => Ok(SectionCode::Module),
454             15 => Ok(SectionCode::Instance),
455             16 => Ok(SectionCode::Alias),
456             17 => Ok(SectionCode::ModuleCode),
457             _ => Err(BinaryReaderError::new("Invalid section code", offset)),
458         }
459     }
460 
read_br_table(&mut self) -> Result<BrTable<'a>>461     fn read_br_table(&mut self) -> Result<BrTable<'a>> {
462         let targets_len = self.read_var_u32()? as usize;
463         if targets_len > MAX_WASM_BR_TABLE_SIZE {
464             return Err(BinaryReaderError::new(
465                 "br_table size is out of bound",
466                 self.original_position() - 1,
467             ));
468         }
469         let start = self.position;
470         for _ in 0..targets_len {
471             self.skip_var_32()?;
472         }
473         self.skip_var_32()?;
474         let end = self.position;
475         Ok(BrTable {
476             reader: BinaryReader::new_with_offset(&self.buffer[start..end], start),
477             cnt: targets_len as usize,
478         })
479     }
480 
481     /// Returns whether the `BinaryReader` has reached the end of the file.
eof(&self) -> bool482     pub fn eof(&self) -> bool {
483         self.position >= self.buffer.len()
484     }
485 
486     /// Returns the `BinaryReader`'s current position.
current_position(&self) -> usize487     pub fn current_position(&self) -> usize {
488         self.position
489     }
490 
491     /// Returns the number of bytes remaining in the `BinaryReader`.
bytes_remaining(&self) -> usize492     pub fn bytes_remaining(&self) -> usize {
493         self.buffer.len() - self.position
494     }
495 
496     /// Advances the `BinaryReader` `size` bytes, and returns a slice from the
497     /// current position of `size` length.
498     ///
499     /// # Errors
500     /// If `size` exceeds the remaining length in `BinaryReader`.
read_bytes(&mut self, size: usize) -> Result<&'a [u8]>501     pub fn read_bytes(&mut self, size: usize) -> Result<&'a [u8]> {
502         self.ensure_has_bytes(size)?;
503         let start = self.position;
504         self.position += size;
505         Ok(&self.buffer[start..self.position])
506     }
507 
508     /// Advances the `BinaryReader` four bytes and returns a `u32`.
509     /// # Errors
510     /// If `BinaryReader` has less than four bytes remaining.
read_u32(&mut self) -> Result<u32>511     pub fn read_u32(&mut self) -> Result<u32> {
512         self.ensure_has_bytes(4)?;
513         let word = u32::from_le_bytes(
514             self.buffer[self.position..self.position + 4]
515                 .try_into()
516                 .unwrap(),
517         );
518         self.position += 4;
519         Ok(word)
520     }
521 
522     /// Advances the `BinaryReader` eight bytes and returns a `u64`.
523     /// # Errors
524     /// If `BinaryReader` has less than eight bytes remaining.
read_u64(&mut self) -> Result<u64>525     pub fn read_u64(&mut self) -> Result<u64> {
526         self.ensure_has_bytes(8)?;
527         let word = u64::from_le_bytes(
528             self.buffer[self.position..self.position + 8]
529                 .try_into()
530                 .unwrap(),
531         );
532         self.position += 8;
533         Ok(word)
534     }
535 
536     /// Advances the `BinaryReader` a single byte, and returns the data as
537     /// a `u32`.
538     ///
539     /// # Errors
540     ///
541     /// If `BinaryReader` has no bytes remaining.
read_u8(&mut self) -> Result<u32>542     pub fn read_u8(&mut self) -> Result<u32> {
543         self.ensure_has_byte()?;
544         let b = u32::from(self.buffer[self.position]);
545         self.position += 1;
546         Ok(b)
547     }
548 
549     /// Advances the `BinaryReader` up to two bytes to parse a variable
550     /// length integer as a `u8`.
551     ///
552     /// # Errors
553     ///
554     /// If `BinaryReader` has less than one or two bytes remaining, or the
555     /// integer is larger than eight bits.
read_var_u8(&mut self) -> Result<u32>556     pub fn read_var_u8(&mut self) -> Result<u32> {
557         // Optimization for single byte i32.
558         let byte = self.read_u8()?;
559         if (byte & 0x80) == 0 {
560             return Ok(byte);
561         }
562 
563         let result = (self.read_u8()? << 7) | (byte & 0x7F);
564         if result >= 0x100 {
565             return Err(BinaryReaderError::new(
566                 "Invalid var_u8",
567                 self.original_position() - 1,
568             ));
569         }
570         Ok(result)
571     }
572 
573     /// Advances the `BinaryReader` up to four bytes to parse a variable
574     /// length integer as a `u32`.
575     ///
576     /// # Errors
577     ///
578     /// If `BinaryReader` has less than one or up to four bytes remaining, or
579     /// the integer is larger than 32 bits.
read_var_u32(&mut self) -> Result<u32>580     pub fn read_var_u32(&mut self) -> Result<u32> {
581         // Optimization for single byte i32.
582         let byte = self.read_u8()?;
583         if (byte & 0x80) == 0 {
584             return Ok(byte);
585         }
586 
587         let mut result = byte & 0x7F;
588         let mut shift = 7;
589         loop {
590             let byte = self.read_u8()?;
591             result |= ((byte & 0x7F) as u32) << shift;
592             if shift >= 25 && (byte >> (32 - shift)) != 0 {
593                 // The continuation bit or unused bits are set.
594                 return Err(BinaryReaderError::new(
595                     "Invalid var_u32",
596                     self.original_position() - 1,
597                 ));
598             }
599             shift += 7;
600             if (byte & 0x80) == 0 {
601                 break;
602             }
603         }
604         Ok(result)
605     }
606 
607     /// Advances the `BinaryReader` up to four bytes to parse a variable
608     /// length integer as a `u64`.
609     ///
610     /// # Errors
611     ///
612     /// If `BinaryReader` has less than one or up to eight bytes remaining, or
613     /// the integer is larger than 64 bits.
read_var_u64(&mut self) -> Result<u64>614     pub fn read_var_u64(&mut self) -> Result<u64> {
615         // Optimization for single byte u64.
616         let byte = u64::from(self.read_u8()?);
617         if (byte & 0x80) == 0 {
618             return Ok(byte);
619         }
620 
621         let mut result = byte & 0x7F;
622         let mut shift = 7;
623         loop {
624             let byte = u64::from(self.read_u8()?);
625             result |= (byte & 0x7F) << shift;
626             if shift >= 57 && (byte >> (64 - shift)) != 0 {
627                 // The continuation bit or unused bits are set.
628                 return Err(BinaryReaderError::new(
629                     "Invalid var_u64",
630                     self.original_position() - 1,
631                 ));
632             }
633             shift += 7;
634             if (byte & 0x80) == 0 {
635                 break;
636             }
637         }
638         Ok(result)
639     }
640 
641     /// Advances the `BinaryReader` up to four bytes over a variable length 32
642     /// bit integer, discarding the result.
643     /// # Errors
644     /// If `BinaryReader` has less than one or up to four bytes remaining, or
645     /// the integer is larger than 32 bits.
skip_var_32(&mut self) -> Result<()>646     pub fn skip_var_32(&mut self) -> Result<()> {
647         for _ in 0..5 {
648             let byte = self.read_u8()?;
649             if (byte & 0x80) == 0 {
650                 return Ok(());
651             }
652         }
653         Err(BinaryReaderError::new(
654             "Invalid var_32",
655             self.original_position() - 1,
656         ))
657     }
658 
659     /// Alias method for `BinaryReader::skip_var_u32`.
skip_type(&mut self) -> Result<()>660     pub fn skip_type(&mut self) -> Result<()> {
661         self.skip_var_32()
662     }
663 
664     /// Advances the `BinaryReader` `len` bytes, skipping the result.
665     /// # Errors
666     /// If `BinaryReader` has less than `len` bytes remaining.
skip_bytes(&mut self, len: usize) -> Result<()>667     pub fn skip_bytes(&mut self, len: usize) -> Result<()> {
668         self.ensure_has_bytes(len)?;
669         self.position += len;
670         Ok(())
671     }
672 
673     /// Advances the `BinaryReader` past a WebAssembly string. This method does
674     /// not perform any utf-8 validation.
675     /// # Errors
676     /// If `BinaryReader` has less than four bytes, the string's length exceeds
677     /// the remaining bytes, or the string length
678     /// exceeds `limits::MAX_WASM_STRING_SIZE`.
skip_string(&mut self) -> Result<()>679     pub fn skip_string(&mut self) -> Result<()> {
680         let len = self.read_var_u32()? as usize;
681         if len > MAX_WASM_STRING_SIZE {
682             return Err(BinaryReaderError::new(
683                 "string size out of bounds",
684                 self.original_position() - 1,
685             ));
686         }
687         self.skip_bytes(len)
688     }
689 
skip_to(&mut self, position: usize)690     pub(crate) fn skip_to(&mut self, position: usize) {
691         assert!(
692             self.position <= position && position <= self.buffer.len(),
693             "skip_to allowed only into region past current position"
694         );
695         self.position = position;
696     }
697 
698     /// Advances the `BinaryReader` up to four bytes to parse a variable
699     /// length integer as a `i32`.
700     /// # Errors
701     /// If `BinaryReader` has less than one or up to four bytes remaining, or
702     /// the integer is larger than 32 bits.
read_var_i32(&mut self) -> Result<i32>703     pub fn read_var_i32(&mut self) -> Result<i32> {
704         // Optimization for single byte i32.
705         let byte = self.read_u8()?;
706         if (byte & 0x80) == 0 {
707             return Ok(((byte as i32) << 25) >> 25);
708         }
709 
710         let mut result = (byte & 0x7F) as i32;
711         let mut shift = 7;
712         loop {
713             let byte = self.read_u8()?;
714             result |= ((byte & 0x7F) as i32) << shift;
715             if shift >= 25 {
716                 let continuation_bit = (byte & 0x80) != 0;
717                 let sign_and_unused_bit = (byte << 1) as i8 >> (32 - shift);
718                 if continuation_bit || (sign_and_unused_bit != 0 && sign_and_unused_bit != -1) {
719                     return Err(BinaryReaderError::new(
720                         "Invalid var_i32",
721                         self.original_position() - 1,
722                     ));
723                 }
724                 return Ok(result);
725             }
726             shift += 7;
727             if (byte & 0x80) == 0 {
728                 break;
729             }
730         }
731         let ashift = 32 - shift;
732         Ok((result << ashift) >> ashift)
733     }
734 
735     /// Advances the `BinaryReader` up to four bytes to parse a variable
736     /// length integer as a signed 33 bit integer, returned as a `i64`.
737     /// # Errors
738     /// If `BinaryReader` has less than one or up to five bytes remaining, or
739     /// the integer is larger than 33 bits.
read_var_s33(&mut self) -> Result<i64>740     pub fn read_var_s33(&mut self) -> Result<i64> {
741         // Optimization for single byte.
742         let byte = self.read_u8()?;
743         if (byte & 0x80) == 0 {
744             return Ok(((byte as i8) << 1) as i64 >> 1);
745         }
746 
747         let mut result = (byte & 0x7F) as i64;
748         let mut shift = 7;
749         loop {
750             let byte = self.read_u8()?;
751             result |= ((byte & 0x7F) as i64) << shift;
752             if shift >= 25 {
753                 let continuation_bit = (byte & 0x80) != 0;
754                 let sign_and_unused_bit = (byte << 1) as i8 >> (33 - shift);
755                 if continuation_bit || (sign_and_unused_bit != 0 && sign_and_unused_bit != -1) {
756                     return Err(BinaryReaderError::new(
757                         "Invalid var_s33",
758                         self.original_position() - 1,
759                     ));
760                 }
761                 return Ok(result);
762             }
763             shift += 7;
764             if (byte & 0x80) == 0 {
765                 break;
766             }
767         }
768         let ashift = 64 - shift;
769         Ok((result << ashift) >> ashift)
770     }
771 
772     /// Advances the `BinaryReader` up to eight bytes to parse a variable
773     /// length integer as a 64 bit integer, returned as a `i64`.
774     /// # Errors
775     /// If `BinaryReader` has less than one or up to eight bytes remaining, or
776     /// the integer is larger than 64 bits.
read_var_i64(&mut self) -> Result<i64>777     pub fn read_var_i64(&mut self) -> Result<i64> {
778         let mut result: i64 = 0;
779         let mut shift = 0;
780         loop {
781             let byte = self.read_u8()?;
782             result |= i64::from(byte & 0x7F) << shift;
783             if shift >= 57 {
784                 let continuation_bit = (byte & 0x80) != 0;
785                 let sign_and_unused_bit = ((byte << 1) as i8) >> (64 - shift);
786                 if continuation_bit || (sign_and_unused_bit != 0 && sign_and_unused_bit != -1) {
787                     return Err(BinaryReaderError::new(
788                         "Invalid var_i64",
789                         self.original_position() - 1,
790                     ));
791                 }
792                 return Ok(result);
793             }
794             shift += 7;
795             if (byte & 0x80) == 0 {
796                 break;
797             }
798         }
799         let ashift = 64 - shift;
800         Ok((result << ashift) >> ashift)
801     }
802 
803     /// Advances the `BinaryReader` up to four bytes to parse a variable
804     /// length integer as a 32 bit floating point integer, returned as `Ieee32`.
805     /// # Errors
806     /// If `BinaryReader` has less than one or up to four bytes remaining, or
807     /// the integer is larger than 32 bits.
read_f32(&mut self) -> Result<Ieee32>808     pub fn read_f32(&mut self) -> Result<Ieee32> {
809         let value = self.read_u32()?;
810         Ok(Ieee32(value))
811     }
812 
813     /// Advances the `BinaryReader` up to four bytes to parse a variable
814     /// length integer as a 32 bit floating point integer, returned as `Ieee32`.
815     /// # Errors
816     /// If `BinaryReader` has less than one or up to four bytes remaining, or
817     /// the integer is larger than 32 bits.
read_f64(&mut self) -> Result<Ieee64>818     pub fn read_f64(&mut self) -> Result<Ieee64> {
819         let value = self.read_u64()?;
820         Ok(Ieee64(value))
821     }
822 
823     /// Reads a WebAssembly string from the module.
824     /// # Errors
825     /// If `BinaryReader` has less than up to four bytes remaining, the string's
826     /// length exceeds the remaining bytes, the string's length exceeds
827     /// `limits::MAX_WASM_STRING_SIZE`, or the string contains invalid utf-8.
read_string(&mut self) -> Result<&'a str>828     pub fn read_string(&mut self) -> Result<&'a str> {
829         let len = self.read_var_u32()? as usize;
830         if len > MAX_WASM_STRING_SIZE {
831             return Err(BinaryReaderError::new(
832                 "string size out of bounds",
833                 self.original_position() - 1,
834             ));
835         }
836         let bytes = self.read_bytes(len)?;
837         str::from_utf8(bytes).map_err(|_| {
838             BinaryReaderError::new("invalid UTF-8 encoding", self.original_position() - 1)
839         })
840     }
841 
read_memarg_of_align(&mut self, max_align: u8) -> Result<MemoryImmediate>842     fn read_memarg_of_align(&mut self, max_align: u8) -> Result<MemoryImmediate> {
843         let align_pos = self.original_position();
844         let imm = self.read_memarg()?;
845         if imm.align > max_align {
846             return Err(BinaryReaderError::new(
847                 "alignment must not be larger than natural",
848                 align_pos,
849             ));
850         }
851         Ok(imm)
852     }
853 
read_0xfe_operator(&mut self) -> Result<Operator<'a>>854     fn read_0xfe_operator(&mut self) -> Result<Operator<'a>> {
855         let code = self.read_var_u32()?;
856         Ok(match code {
857             0x00 => Operator::MemoryAtomicNotify {
858                 memarg: self.read_memarg_of_align(2)?,
859             },
860             0x01 => Operator::MemoryAtomicWait32 {
861                 memarg: self.read_memarg_of_align(2)?,
862             },
863             0x02 => Operator::MemoryAtomicWait64 {
864                 memarg: self.read_memarg_of_align(3)?,
865             },
866             0x03 => Operator::AtomicFence {
867                 flags: self.read_u8()? as u8,
868             },
869             0x10 => Operator::I32AtomicLoad {
870                 memarg: self.read_memarg_of_align(2)?,
871             },
872             0x11 => Operator::I64AtomicLoad {
873                 memarg: self.read_memarg_of_align(3)?,
874             },
875             0x12 => Operator::I32AtomicLoad8U {
876                 memarg: self.read_memarg_of_align(0)?,
877             },
878             0x13 => Operator::I32AtomicLoad16U {
879                 memarg: self.read_memarg_of_align(1)?,
880             },
881             0x14 => Operator::I64AtomicLoad8U {
882                 memarg: self.read_memarg_of_align(0)?,
883             },
884             0x15 => Operator::I64AtomicLoad16U {
885                 memarg: self.read_memarg_of_align(1)?,
886             },
887             0x16 => Operator::I64AtomicLoad32U {
888                 memarg: self.read_memarg_of_align(2)?,
889             },
890             0x17 => Operator::I32AtomicStore {
891                 memarg: self.read_memarg_of_align(2)?,
892             },
893             0x18 => Operator::I64AtomicStore {
894                 memarg: self.read_memarg_of_align(3)?,
895             },
896             0x19 => Operator::I32AtomicStore8 {
897                 memarg: self.read_memarg_of_align(0)?,
898             },
899             0x1a => Operator::I32AtomicStore16 {
900                 memarg: self.read_memarg_of_align(1)?,
901             },
902             0x1b => Operator::I64AtomicStore8 {
903                 memarg: self.read_memarg_of_align(0)?,
904             },
905             0x1c => Operator::I64AtomicStore16 {
906                 memarg: self.read_memarg_of_align(1)?,
907             },
908             0x1d => Operator::I64AtomicStore32 {
909                 memarg: self.read_memarg_of_align(2)?,
910             },
911             0x1e => Operator::I32AtomicRmwAdd {
912                 memarg: self.read_memarg_of_align(2)?,
913             },
914             0x1f => Operator::I64AtomicRmwAdd {
915                 memarg: self.read_memarg_of_align(3)?,
916             },
917             0x20 => Operator::I32AtomicRmw8AddU {
918                 memarg: self.read_memarg_of_align(0)?,
919             },
920             0x21 => Operator::I32AtomicRmw16AddU {
921                 memarg: self.read_memarg_of_align(1)?,
922             },
923             0x22 => Operator::I64AtomicRmw8AddU {
924                 memarg: self.read_memarg_of_align(0)?,
925             },
926             0x23 => Operator::I64AtomicRmw16AddU {
927                 memarg: self.read_memarg_of_align(1)?,
928             },
929             0x24 => Operator::I64AtomicRmw32AddU {
930                 memarg: self.read_memarg_of_align(2)?,
931             },
932             0x25 => Operator::I32AtomicRmwSub {
933                 memarg: self.read_memarg_of_align(2)?,
934             },
935             0x26 => Operator::I64AtomicRmwSub {
936                 memarg: self.read_memarg_of_align(3)?,
937             },
938             0x27 => Operator::I32AtomicRmw8SubU {
939                 memarg: self.read_memarg_of_align(0)?,
940             },
941             0x28 => Operator::I32AtomicRmw16SubU {
942                 memarg: self.read_memarg_of_align(1)?,
943             },
944             0x29 => Operator::I64AtomicRmw8SubU {
945                 memarg: self.read_memarg_of_align(0)?,
946             },
947             0x2a => Operator::I64AtomicRmw16SubU {
948                 memarg: self.read_memarg_of_align(1)?,
949             },
950             0x2b => Operator::I64AtomicRmw32SubU {
951                 memarg: self.read_memarg_of_align(2)?,
952             },
953             0x2c => Operator::I32AtomicRmwAnd {
954                 memarg: self.read_memarg_of_align(2)?,
955             },
956             0x2d => Operator::I64AtomicRmwAnd {
957                 memarg: self.read_memarg_of_align(3)?,
958             },
959             0x2e => Operator::I32AtomicRmw8AndU {
960                 memarg: self.read_memarg_of_align(0)?,
961             },
962             0x2f => Operator::I32AtomicRmw16AndU {
963                 memarg: self.read_memarg_of_align(1)?,
964             },
965             0x30 => Operator::I64AtomicRmw8AndU {
966                 memarg: self.read_memarg_of_align(0)?,
967             },
968             0x31 => Operator::I64AtomicRmw16AndU {
969                 memarg: self.read_memarg_of_align(1)?,
970             },
971             0x32 => Operator::I64AtomicRmw32AndU {
972                 memarg: self.read_memarg_of_align(2)?,
973             },
974             0x33 => Operator::I32AtomicRmwOr {
975                 memarg: self.read_memarg_of_align(2)?,
976             },
977             0x34 => Operator::I64AtomicRmwOr {
978                 memarg: self.read_memarg_of_align(3)?,
979             },
980             0x35 => Operator::I32AtomicRmw8OrU {
981                 memarg: self.read_memarg_of_align(0)?,
982             },
983             0x36 => Operator::I32AtomicRmw16OrU {
984                 memarg: self.read_memarg_of_align(1)?,
985             },
986             0x37 => Operator::I64AtomicRmw8OrU {
987                 memarg: self.read_memarg_of_align(0)?,
988             },
989             0x38 => Operator::I64AtomicRmw16OrU {
990                 memarg: self.read_memarg_of_align(1)?,
991             },
992             0x39 => Operator::I64AtomicRmw32OrU {
993                 memarg: self.read_memarg_of_align(2)?,
994             },
995             0x3a => Operator::I32AtomicRmwXor {
996                 memarg: self.read_memarg_of_align(2)?,
997             },
998             0x3b => Operator::I64AtomicRmwXor {
999                 memarg: self.read_memarg_of_align(3)?,
1000             },
1001             0x3c => Operator::I32AtomicRmw8XorU {
1002                 memarg: self.read_memarg_of_align(0)?,
1003             },
1004             0x3d => Operator::I32AtomicRmw16XorU {
1005                 memarg: self.read_memarg_of_align(1)?,
1006             },
1007             0x3e => Operator::I64AtomicRmw8XorU {
1008                 memarg: self.read_memarg_of_align(0)?,
1009             },
1010             0x3f => Operator::I64AtomicRmw16XorU {
1011                 memarg: self.read_memarg_of_align(1)?,
1012             },
1013             0x40 => Operator::I64AtomicRmw32XorU {
1014                 memarg: self.read_memarg_of_align(2)?,
1015             },
1016             0x41 => Operator::I32AtomicRmwXchg {
1017                 memarg: self.read_memarg_of_align(2)?,
1018             },
1019             0x42 => Operator::I64AtomicRmwXchg {
1020                 memarg: self.read_memarg_of_align(3)?,
1021             },
1022             0x43 => Operator::I32AtomicRmw8XchgU {
1023                 memarg: self.read_memarg_of_align(0)?,
1024             },
1025             0x44 => Operator::I32AtomicRmw16XchgU {
1026                 memarg: self.read_memarg_of_align(1)?,
1027             },
1028             0x45 => Operator::I64AtomicRmw8XchgU {
1029                 memarg: self.read_memarg_of_align(0)?,
1030             },
1031             0x46 => Operator::I64AtomicRmw16XchgU {
1032                 memarg: self.read_memarg_of_align(1)?,
1033             },
1034             0x47 => Operator::I64AtomicRmw32XchgU {
1035                 memarg: self.read_memarg_of_align(2)?,
1036             },
1037             0x48 => Operator::I32AtomicRmwCmpxchg {
1038                 memarg: self.read_memarg_of_align(2)?,
1039             },
1040             0x49 => Operator::I64AtomicRmwCmpxchg {
1041                 memarg: self.read_memarg_of_align(3)?,
1042             },
1043             0x4a => Operator::I32AtomicRmw8CmpxchgU {
1044                 memarg: self.read_memarg_of_align(0)?,
1045             },
1046             0x4b => Operator::I32AtomicRmw16CmpxchgU {
1047                 memarg: self.read_memarg_of_align(1)?,
1048             },
1049             0x4c => Operator::I64AtomicRmw8CmpxchgU {
1050                 memarg: self.read_memarg_of_align(0)?,
1051             },
1052             0x4d => Operator::I64AtomicRmw16CmpxchgU {
1053                 memarg: self.read_memarg_of_align(1)?,
1054             },
1055             0x4e => Operator::I64AtomicRmw32CmpxchgU {
1056                 memarg: self.read_memarg_of_align(2)?,
1057             },
1058 
1059             _ => {
1060                 return Err(BinaryReaderError::new(
1061                     format!("Unknown 0xfe subopcode: 0x{:x}", code),
1062                     self.original_position() - 1,
1063                 ));
1064             }
1065         })
1066     }
1067 
read_blocktype(&mut self) -> Result<TypeOrFuncType>1068     fn read_blocktype(&mut self) -> Result<TypeOrFuncType> {
1069         let position = self.position;
1070         if let Ok(ty) = self.read_type() {
1071             Ok(TypeOrFuncType::Type(ty))
1072         } else {
1073             self.position = position;
1074             let idx = self.read_var_s33()?;
1075             if idx < 0 || idx > (std::u32::MAX as i64) {
1076                 return Err(BinaryReaderError::new("invalid function type", position));
1077             }
1078             Ok(TypeOrFuncType::FuncType(idx as u32))
1079         }
1080     }
1081 
1082     /// Reads the next available `Operator`.
1083     /// # Errors
1084     /// If `BinaryReader` has less bytes remaining than required to parse
1085     /// the `Operator`.
read_operator(&mut self) -> Result<Operator<'a>>1086     pub fn read_operator(&mut self) -> Result<Operator<'a>> {
1087         let code = self.read_u8()? as u8;
1088         Ok(match code {
1089             0x00 => Operator::Unreachable,
1090             0x01 => Operator::Nop,
1091             0x02 => Operator::Block {
1092                 ty: self.read_blocktype()?,
1093             },
1094             0x03 => Operator::Loop {
1095                 ty: self.read_blocktype()?,
1096             },
1097             0x04 => Operator::If {
1098                 ty: self.read_blocktype()?,
1099             },
1100             0x05 => Operator::Else,
1101             0x06 => Operator::Try {
1102                 ty: self.read_blocktype()?,
1103             },
1104             0x07 => Operator::Catch {
1105                 index: self.read_var_u32()?,
1106             },
1107             0x08 => Operator::Throw {
1108                 index: self.read_var_u32()?,
1109             },
1110             0x09 => Operator::Rethrow {
1111                 relative_depth: self.read_var_u32()?,
1112             },
1113             0x0a => Operator::Unwind,
1114             0x0b => Operator::End,
1115             0x0c => Operator::Br {
1116                 relative_depth: self.read_var_u32()?,
1117             },
1118             0x0d => Operator::BrIf {
1119                 relative_depth: self.read_var_u32()?,
1120             },
1121             0x0e => Operator::BrTable {
1122                 table: self.read_br_table()?,
1123             },
1124             0x0f => Operator::Return,
1125             0x10 => Operator::Call {
1126                 function_index: self.read_var_u32()?,
1127             },
1128             0x11 => Operator::CallIndirect {
1129                 index: self.read_var_u32()?,
1130                 table_index: self.read_var_u32()?,
1131             },
1132             0x12 => Operator::ReturnCall {
1133                 function_index: self.read_var_u32()?,
1134             },
1135             0x13 => Operator::ReturnCallIndirect {
1136                 index: self.read_var_u32()?,
1137                 table_index: self.read_var_u32()?,
1138             },
1139             0x18 => Operator::Delegate {
1140                 relative_depth: self.read_var_u32()?,
1141             },
1142             0x19 => Operator::CatchAll,
1143             0x1a => Operator::Drop,
1144             0x1b => Operator::Select,
1145             0x1c => {
1146                 let results = self.read_var_u32()?;
1147                 if results != 1 {
1148                     return Err(BinaryReaderError::new(
1149                         "invalid result arity",
1150                         self.position,
1151                     ));
1152                 }
1153                 Operator::TypedSelect {
1154                     ty: self.read_type()?,
1155                 }
1156             }
1157             0x20 => Operator::LocalGet {
1158                 local_index: self.read_var_u32()?,
1159             },
1160             0x21 => Operator::LocalSet {
1161                 local_index: self.read_var_u32()?,
1162             },
1163             0x22 => Operator::LocalTee {
1164                 local_index: self.read_var_u32()?,
1165             },
1166             0x23 => Operator::GlobalGet {
1167                 global_index: self.read_var_u32()?,
1168             },
1169             0x24 => Operator::GlobalSet {
1170                 global_index: self.read_var_u32()?,
1171             },
1172             0x25 => Operator::TableGet {
1173                 table: self.read_var_u32()?,
1174             },
1175             0x26 => Operator::TableSet {
1176                 table: self.read_var_u32()?,
1177             },
1178             0x28 => Operator::I32Load {
1179                 memarg: self.read_memarg()?,
1180             },
1181             0x29 => Operator::I64Load {
1182                 memarg: self.read_memarg()?,
1183             },
1184             0x2a => Operator::F32Load {
1185                 memarg: self.read_memarg()?,
1186             },
1187             0x2b => Operator::F64Load {
1188                 memarg: self.read_memarg()?,
1189             },
1190             0x2c => Operator::I32Load8S {
1191                 memarg: self.read_memarg()?,
1192             },
1193             0x2d => Operator::I32Load8U {
1194                 memarg: self.read_memarg()?,
1195             },
1196             0x2e => Operator::I32Load16S {
1197                 memarg: self.read_memarg()?,
1198             },
1199             0x2f => Operator::I32Load16U {
1200                 memarg: self.read_memarg()?,
1201             },
1202             0x30 => Operator::I64Load8S {
1203                 memarg: self.read_memarg()?,
1204             },
1205             0x31 => Operator::I64Load8U {
1206                 memarg: self.read_memarg()?,
1207             },
1208             0x32 => Operator::I64Load16S {
1209                 memarg: self.read_memarg()?,
1210             },
1211             0x33 => Operator::I64Load16U {
1212                 memarg: self.read_memarg()?,
1213             },
1214             0x34 => Operator::I64Load32S {
1215                 memarg: self.read_memarg()?,
1216             },
1217             0x35 => Operator::I64Load32U {
1218                 memarg: self.read_memarg()?,
1219             },
1220             0x36 => Operator::I32Store {
1221                 memarg: self.read_memarg()?,
1222             },
1223             0x37 => Operator::I64Store {
1224                 memarg: self.read_memarg()?,
1225             },
1226             0x38 => Operator::F32Store {
1227                 memarg: self.read_memarg()?,
1228             },
1229             0x39 => Operator::F64Store {
1230                 memarg: self.read_memarg()?,
1231             },
1232             0x3a => Operator::I32Store8 {
1233                 memarg: self.read_memarg()?,
1234             },
1235             0x3b => Operator::I32Store16 {
1236                 memarg: self.read_memarg()?,
1237             },
1238             0x3c => Operator::I64Store8 {
1239                 memarg: self.read_memarg()?,
1240             },
1241             0x3d => Operator::I64Store16 {
1242                 memarg: self.read_memarg()?,
1243             },
1244             0x3e => Operator::I64Store32 {
1245                 memarg: self.read_memarg()?,
1246             },
1247             0x3f => {
1248                 let (mem_byte, mem) = self.read_first_byte_and_var_u32()?;
1249                 Operator::MemorySize { mem_byte, mem }
1250             }
1251             0x40 => {
1252                 let (mem_byte, mem) = self.read_first_byte_and_var_u32()?;
1253                 Operator::MemoryGrow { mem_byte, mem }
1254             }
1255             0x41 => Operator::I32Const {
1256                 value: self.read_var_i32()?,
1257             },
1258             0x42 => Operator::I64Const {
1259                 value: self.read_var_i64()?,
1260             },
1261             0x43 => Operator::F32Const {
1262                 value: self.read_f32()?,
1263             },
1264             0x44 => Operator::F64Const {
1265                 value: self.read_f64()?,
1266             },
1267             0x45 => Operator::I32Eqz,
1268             0x46 => Operator::I32Eq,
1269             0x47 => Operator::I32Ne,
1270             0x48 => Operator::I32LtS,
1271             0x49 => Operator::I32LtU,
1272             0x4a => Operator::I32GtS,
1273             0x4b => Operator::I32GtU,
1274             0x4c => Operator::I32LeS,
1275             0x4d => Operator::I32LeU,
1276             0x4e => Operator::I32GeS,
1277             0x4f => Operator::I32GeU,
1278             0x50 => Operator::I64Eqz,
1279             0x51 => Operator::I64Eq,
1280             0x52 => Operator::I64Ne,
1281             0x53 => Operator::I64LtS,
1282             0x54 => Operator::I64LtU,
1283             0x55 => Operator::I64GtS,
1284             0x56 => Operator::I64GtU,
1285             0x57 => Operator::I64LeS,
1286             0x58 => Operator::I64LeU,
1287             0x59 => Operator::I64GeS,
1288             0x5a => Operator::I64GeU,
1289             0x5b => Operator::F32Eq,
1290             0x5c => Operator::F32Ne,
1291             0x5d => Operator::F32Lt,
1292             0x5e => Operator::F32Gt,
1293             0x5f => Operator::F32Le,
1294             0x60 => Operator::F32Ge,
1295             0x61 => Operator::F64Eq,
1296             0x62 => Operator::F64Ne,
1297             0x63 => Operator::F64Lt,
1298             0x64 => Operator::F64Gt,
1299             0x65 => Operator::F64Le,
1300             0x66 => Operator::F64Ge,
1301             0x67 => Operator::I32Clz,
1302             0x68 => Operator::I32Ctz,
1303             0x69 => Operator::I32Popcnt,
1304             0x6a => Operator::I32Add,
1305             0x6b => Operator::I32Sub,
1306             0x6c => Operator::I32Mul,
1307             0x6d => Operator::I32DivS,
1308             0x6e => Operator::I32DivU,
1309             0x6f => Operator::I32RemS,
1310             0x70 => Operator::I32RemU,
1311             0x71 => Operator::I32And,
1312             0x72 => Operator::I32Or,
1313             0x73 => Operator::I32Xor,
1314             0x74 => Operator::I32Shl,
1315             0x75 => Operator::I32ShrS,
1316             0x76 => Operator::I32ShrU,
1317             0x77 => Operator::I32Rotl,
1318             0x78 => Operator::I32Rotr,
1319             0x79 => Operator::I64Clz,
1320             0x7a => Operator::I64Ctz,
1321             0x7b => Operator::I64Popcnt,
1322             0x7c => Operator::I64Add,
1323             0x7d => Operator::I64Sub,
1324             0x7e => Operator::I64Mul,
1325             0x7f => Operator::I64DivS,
1326             0x80 => Operator::I64DivU,
1327             0x81 => Operator::I64RemS,
1328             0x82 => Operator::I64RemU,
1329             0x83 => Operator::I64And,
1330             0x84 => Operator::I64Or,
1331             0x85 => Operator::I64Xor,
1332             0x86 => Operator::I64Shl,
1333             0x87 => Operator::I64ShrS,
1334             0x88 => Operator::I64ShrU,
1335             0x89 => Operator::I64Rotl,
1336             0x8a => Operator::I64Rotr,
1337             0x8b => Operator::F32Abs,
1338             0x8c => Operator::F32Neg,
1339             0x8d => Operator::F32Ceil,
1340             0x8e => Operator::F32Floor,
1341             0x8f => Operator::F32Trunc,
1342             0x90 => Operator::F32Nearest,
1343             0x91 => Operator::F32Sqrt,
1344             0x92 => Operator::F32Add,
1345             0x93 => Operator::F32Sub,
1346             0x94 => Operator::F32Mul,
1347             0x95 => Operator::F32Div,
1348             0x96 => Operator::F32Min,
1349             0x97 => Operator::F32Max,
1350             0x98 => Operator::F32Copysign,
1351             0x99 => Operator::F64Abs,
1352             0x9a => Operator::F64Neg,
1353             0x9b => Operator::F64Ceil,
1354             0x9c => Operator::F64Floor,
1355             0x9d => Operator::F64Trunc,
1356             0x9e => Operator::F64Nearest,
1357             0x9f => Operator::F64Sqrt,
1358             0xa0 => Operator::F64Add,
1359             0xa1 => Operator::F64Sub,
1360             0xa2 => Operator::F64Mul,
1361             0xa3 => Operator::F64Div,
1362             0xa4 => Operator::F64Min,
1363             0xa5 => Operator::F64Max,
1364             0xa6 => Operator::F64Copysign,
1365             0xa7 => Operator::I32WrapI64,
1366             0xa8 => Operator::I32TruncF32S,
1367             0xa9 => Operator::I32TruncF32U,
1368             0xaa => Operator::I32TruncF64S,
1369             0xab => Operator::I32TruncF64U,
1370             0xac => Operator::I64ExtendI32S,
1371             0xad => Operator::I64ExtendI32U,
1372             0xae => Operator::I64TruncF32S,
1373             0xaf => Operator::I64TruncF32U,
1374             0xb0 => Operator::I64TruncF64S,
1375             0xb1 => Operator::I64TruncF64U,
1376             0xb2 => Operator::F32ConvertI32S,
1377             0xb3 => Operator::F32ConvertI32U,
1378             0xb4 => Operator::F32ConvertI64S,
1379             0xb5 => Operator::F32ConvertI64U,
1380             0xb6 => Operator::F32DemoteF64,
1381             0xb7 => Operator::F64ConvertI32S,
1382             0xb8 => Operator::F64ConvertI32U,
1383             0xb9 => Operator::F64ConvertI64S,
1384             0xba => Operator::F64ConvertI64U,
1385             0xbb => Operator::F64PromoteF32,
1386             0xbc => Operator::I32ReinterpretF32,
1387             0xbd => Operator::I64ReinterpretF64,
1388             0xbe => Operator::F32ReinterpretI32,
1389             0xbf => Operator::F64ReinterpretI64,
1390 
1391             0xc0 => Operator::I32Extend8S,
1392             0xc1 => Operator::I32Extend16S,
1393             0xc2 => Operator::I64Extend8S,
1394             0xc3 => Operator::I64Extend16S,
1395             0xc4 => Operator::I64Extend32S,
1396 
1397             0xd0 => Operator::RefNull {
1398                 ty: self.read_type()?,
1399             },
1400             0xd1 => Operator::RefIsNull,
1401             0xd2 => Operator::RefFunc {
1402                 function_index: self.read_var_u32()?,
1403             },
1404 
1405             0xfc => self.read_0xfc_operator()?,
1406             0xfd => self.read_0xfd_operator()?,
1407             0xfe => self.read_0xfe_operator()?,
1408 
1409             _ => {
1410                 return Err(BinaryReaderError::new(
1411                     format!("Unknown opcode: 0x{:x}", code),
1412                     self.original_position() - 1,
1413                 ));
1414             }
1415         })
1416     }
1417 
read_0xfc_operator(&mut self) -> Result<Operator<'a>>1418     fn read_0xfc_operator(&mut self) -> Result<Operator<'a>> {
1419         let code = self.read_var_u32()?;
1420         Ok(match code {
1421             0x00 => Operator::I32TruncSatF32S,
1422             0x01 => Operator::I32TruncSatF32U,
1423             0x02 => Operator::I32TruncSatF64S,
1424             0x03 => Operator::I32TruncSatF64U,
1425             0x04 => Operator::I64TruncSatF32S,
1426             0x05 => Operator::I64TruncSatF32U,
1427             0x06 => Operator::I64TruncSatF64S,
1428             0x07 => Operator::I64TruncSatF64U,
1429 
1430             0x08 => {
1431                 let segment = self.read_var_u32()?;
1432                 let mem = self.read_var_u32()?;
1433                 Operator::MemoryInit { segment, mem }
1434             }
1435             0x09 => {
1436                 let segment = self.read_var_u32()?;
1437                 Operator::DataDrop { segment }
1438             }
1439             0x0a => {
1440                 let dst = self.read_var_u32()?;
1441                 let src = self.read_var_u32()?;
1442                 Operator::MemoryCopy { src, dst }
1443             }
1444             0x0b => {
1445                 let mem = self.read_var_u32()?;
1446                 Operator::MemoryFill { mem }
1447             }
1448             0x0c => {
1449                 let segment = self.read_var_u32()?;
1450                 let table = self.read_var_u32()?;
1451                 Operator::TableInit { segment, table }
1452             }
1453             0x0d => {
1454                 let segment = self.read_var_u32()?;
1455                 Operator::ElemDrop { segment }
1456             }
1457             0x0e => {
1458                 let dst_table = self.read_var_u32()?;
1459                 let src_table = self.read_var_u32()?;
1460                 Operator::TableCopy {
1461                     src_table,
1462                     dst_table,
1463                 }
1464             }
1465 
1466             0x0f => {
1467                 let table = self.read_var_u32()?;
1468                 Operator::TableGrow { table }
1469             }
1470             0x10 => {
1471                 let table = self.read_var_u32()?;
1472                 Operator::TableSize { table }
1473             }
1474 
1475             0x11 => {
1476                 let table = self.read_var_u32()?;
1477                 Operator::TableFill { table }
1478             }
1479 
1480             _ => {
1481                 return Err(BinaryReaderError::new(
1482                     format!("Unknown 0xfc subopcode: 0x{:x}", code),
1483                     self.original_position() - 1,
1484                 ));
1485             }
1486         })
1487     }
1488 
read_lane_index(&mut self, max: u32) -> Result<SIMDLaneIndex>1489     fn read_lane_index(&mut self, max: u32) -> Result<SIMDLaneIndex> {
1490         let index = self.read_u8()?;
1491         if index >= max {
1492             return Err(BinaryReaderError::new(
1493                 "invalid lane index",
1494                 self.original_position() - 1,
1495             ));
1496         }
1497         Ok(index as SIMDLaneIndex)
1498     }
1499 
read_v128(&mut self) -> Result<V128>1500     fn read_v128(&mut self) -> Result<V128> {
1501         let mut bytes = [0; 16];
1502         bytes.clone_from_slice(self.read_bytes(16)?);
1503         Ok(V128(bytes))
1504     }
1505 
read_0xfd_operator(&mut self) -> Result<Operator<'a>>1506     fn read_0xfd_operator(&mut self) -> Result<Operator<'a>> {
1507         let code = self.read_var_u32()?;
1508         Ok(match code {
1509             0x00 => Operator::V128Load {
1510                 memarg: self.read_memarg()?,
1511             },
1512             0x01 => Operator::V128Load8x8S {
1513                 memarg: self.read_memarg_of_align(3)?,
1514             },
1515             0x02 => Operator::V128Load8x8U {
1516                 memarg: self.read_memarg_of_align(3)?,
1517             },
1518             0x03 => Operator::V128Load16x4S {
1519                 memarg: self.read_memarg_of_align(3)?,
1520             },
1521             0x04 => Operator::V128Load16x4U {
1522                 memarg: self.read_memarg_of_align(3)?,
1523             },
1524             0x05 => Operator::V128Load32x2S {
1525                 memarg: self.read_memarg_of_align(3)?,
1526             },
1527             0x06 => Operator::V128Load32x2U {
1528                 memarg: self.read_memarg_of_align(3)?,
1529             },
1530             0x07 => Operator::V128Load8Splat {
1531                 memarg: self.read_memarg_of_align(0)?,
1532             },
1533             0x08 => Operator::V128Load16Splat {
1534                 memarg: self.read_memarg_of_align(1)?,
1535             },
1536             0x09 => Operator::V128Load32Splat {
1537                 memarg: self.read_memarg_of_align(2)?,
1538             },
1539             0x0a => Operator::V128Load64Splat {
1540                 memarg: self.read_memarg_of_align(3)?,
1541             },
1542             0x0b => Operator::V128Store {
1543                 memarg: self.read_memarg()?,
1544             },
1545             0x0c => Operator::V128Const {
1546                 value: self.read_v128()?,
1547             },
1548             0x0d => {
1549                 let mut lanes = [0 as SIMDLaneIndex; 16];
1550                 for lane in &mut lanes {
1551                     *lane = self.read_lane_index(32)?
1552                 }
1553                 Operator::I8x16Shuffle { lanes }
1554             }
1555             0x0e => Operator::I8x16Swizzle,
1556             0x0f => Operator::I8x16Splat,
1557             0x10 => Operator::I16x8Splat,
1558             0x11 => Operator::I32x4Splat,
1559             0x12 => Operator::I64x2Splat,
1560             0x13 => Operator::F32x4Splat,
1561             0x14 => Operator::F64x2Splat,
1562             0x15 => Operator::I8x16ExtractLaneS {
1563                 lane: self.read_lane_index(16)?,
1564             },
1565             0x16 => Operator::I8x16ExtractLaneU {
1566                 lane: self.read_lane_index(16)?,
1567             },
1568             0x17 => Operator::I8x16ReplaceLane {
1569                 lane: self.read_lane_index(16)?,
1570             },
1571             0x18 => Operator::I16x8ExtractLaneS {
1572                 lane: self.read_lane_index(8)?,
1573             },
1574             0x19 => Operator::I16x8ExtractLaneU {
1575                 lane: self.read_lane_index(8)?,
1576             },
1577             0x1a => Operator::I16x8ReplaceLane {
1578                 lane: self.read_lane_index(8)?,
1579             },
1580             0x1b => Operator::I32x4ExtractLane {
1581                 lane: self.read_lane_index(4)?,
1582             },
1583             0x1c => Operator::I32x4ReplaceLane {
1584                 lane: self.read_lane_index(4)?,
1585             },
1586             0x1d => Operator::I64x2ExtractLane {
1587                 lane: self.read_lane_index(2)?,
1588             },
1589             0x1e => Operator::I64x2ReplaceLane {
1590                 lane: self.read_lane_index(2)?,
1591             },
1592             0x1f => Operator::F32x4ExtractLane {
1593                 lane: self.read_lane_index(4)?,
1594             },
1595             0x20 => Operator::F32x4ReplaceLane {
1596                 lane: self.read_lane_index(4)?,
1597             },
1598             0x21 => Operator::F64x2ExtractLane {
1599                 lane: self.read_lane_index(2)?,
1600             },
1601             0x22 => Operator::F64x2ReplaceLane {
1602                 lane: self.read_lane_index(2)?,
1603             },
1604             0x23 => Operator::I8x16Eq,
1605             0x24 => Operator::I8x16Ne,
1606             0x25 => Operator::I8x16LtS,
1607             0x26 => Operator::I8x16LtU,
1608             0x27 => Operator::I8x16GtS,
1609             0x28 => Operator::I8x16GtU,
1610             0x29 => Operator::I8x16LeS,
1611             0x2a => Operator::I8x16LeU,
1612             0x2b => Operator::I8x16GeS,
1613             0x2c => Operator::I8x16GeU,
1614             0x2d => Operator::I16x8Eq,
1615             0x2e => Operator::I16x8Ne,
1616             0x2f => Operator::I16x8LtS,
1617             0x30 => Operator::I16x8LtU,
1618             0x31 => Operator::I16x8GtS,
1619             0x32 => Operator::I16x8GtU,
1620             0x33 => Operator::I16x8LeS,
1621             0x34 => Operator::I16x8LeU,
1622             0x35 => Operator::I16x8GeS,
1623             0x36 => Operator::I16x8GeU,
1624             0x37 => Operator::I32x4Eq,
1625             0x38 => Operator::I32x4Ne,
1626             0x39 => Operator::I32x4LtS,
1627             0x3a => Operator::I32x4LtU,
1628             0x3b => Operator::I32x4GtS,
1629             0x3c => Operator::I32x4GtU,
1630             0x3d => Operator::I32x4LeS,
1631             0x3e => Operator::I32x4LeU,
1632             0x3f => Operator::I32x4GeS,
1633             0x40 => Operator::I32x4GeU,
1634             0x41 => Operator::F32x4Eq,
1635             0x42 => Operator::F32x4Ne,
1636             0x43 => Operator::F32x4Lt,
1637             0x44 => Operator::F32x4Gt,
1638             0x45 => Operator::F32x4Le,
1639             0x46 => Operator::F32x4Ge,
1640             0x47 => Operator::F64x2Eq,
1641             0x48 => Operator::F64x2Ne,
1642             0x49 => Operator::F64x2Lt,
1643             0x4a => Operator::F64x2Gt,
1644             0x4b => Operator::F64x2Le,
1645             0x4c => Operator::F64x2Ge,
1646             0x4d => Operator::V128Not,
1647             0x4e => Operator::V128And,
1648             0x4f => Operator::V128AndNot,
1649             0x50 => Operator::V128Or,
1650             0x51 => Operator::V128Xor,
1651             0x52 => Operator::V128Bitselect,
1652             0x53 => Operator::V128AnyTrue,
1653             0x54 => Operator::V128Load8Lane {
1654                 memarg: self.read_memarg()?,
1655                 lane: self.read_lane_index(16)?,
1656             },
1657             0x55 => Operator::V128Load16Lane {
1658                 memarg: self.read_memarg()?,
1659                 lane: self.read_lane_index(8)?,
1660             },
1661             0x56 => Operator::V128Load32Lane {
1662                 memarg: self.read_memarg()?,
1663                 lane: self.read_lane_index(4)?,
1664             },
1665             0x57 => Operator::V128Load64Lane {
1666                 memarg: self.read_memarg()?,
1667                 lane: self.read_lane_index(2)?,
1668             },
1669             0x58 => Operator::V128Store8Lane {
1670                 memarg: self.read_memarg()?,
1671                 lane: self.read_lane_index(16)?,
1672             },
1673             0x59 => Operator::V128Store16Lane {
1674                 memarg: self.read_memarg()?,
1675                 lane: self.read_lane_index(8)?,
1676             },
1677             0x5a => Operator::V128Store32Lane {
1678                 memarg: self.read_memarg()?,
1679                 lane: self.read_lane_index(4)?,
1680             },
1681             0x5b => Operator::V128Store64Lane {
1682                 memarg: self.read_memarg()?,
1683                 lane: self.read_lane_index(2)?,
1684             },
1685             0x5c => Operator::V128Load32Zero {
1686                 memarg: self.read_memarg_of_align(2)?,
1687             },
1688             0x5d => Operator::V128Load64Zero {
1689                 memarg: self.read_memarg_of_align(3)?,
1690             },
1691             0x5e => Operator::F32x4DemoteF64x2Zero,
1692             0x5f => Operator::F64x2PromoteLowF32x4,
1693             0x60 => Operator::I8x16Abs,
1694             0x61 => Operator::I8x16Neg,
1695             0x62 => Operator::I8x16Popcnt,
1696             0x63 => Operator::I8x16AllTrue,
1697             0x64 => Operator::I8x16Bitmask,
1698             0x65 => Operator::I8x16NarrowI16x8S,
1699             0x66 => Operator::I8x16NarrowI16x8U,
1700             0x67 => Operator::F32x4Ceil,
1701             0x68 => Operator::F32x4Floor,
1702             0x69 => Operator::F32x4Trunc,
1703             0x6a => Operator::F32x4Nearest,
1704             0x6b => Operator::I8x16Shl,
1705             0x6c => Operator::I8x16ShrS,
1706             0x6d => Operator::I8x16ShrU,
1707             0x6e => Operator::I8x16Add,
1708             0x6f => Operator::I8x16AddSatS,
1709             0x70 => Operator::I8x16AddSatU,
1710             0x71 => Operator::I8x16Sub,
1711             0x72 => Operator::I8x16SubSatS,
1712             0x73 => Operator::I8x16SubSatU,
1713             0x74 => Operator::F64x2Ceil,
1714             0x75 => Operator::F64x2Floor,
1715             0x76 => Operator::I8x16MinS,
1716             0x77 => Operator::I8x16MinU,
1717             0x78 => Operator::I8x16MaxS,
1718             0x79 => Operator::I8x16MaxU,
1719             0x7a => Operator::F64x2Trunc,
1720             0x7b => Operator::I8x16RoundingAverageU,
1721             0x7c => Operator::I16x8ExtAddPairwiseI8x16S,
1722             0x7d => Operator::I16x8ExtAddPairwiseI8x16U,
1723             0x7e => Operator::I32x4ExtAddPairwiseI16x8S,
1724             0x7f => Operator::I32x4ExtAddPairwiseI16x8U,
1725             0x80 => Operator::I16x8Abs,
1726             0x81 => Operator::I16x8Neg,
1727             0x82 => Operator::I16x8Q15MulrSatS,
1728             0x83 => Operator::I16x8AllTrue,
1729             0x84 => Operator::I16x8Bitmask,
1730             0x85 => Operator::I16x8NarrowI32x4S,
1731             0x86 => Operator::I16x8NarrowI32x4U,
1732             0x87 => Operator::I16x8ExtendLowI8x16S,
1733             0x88 => Operator::I16x8ExtendHighI8x16S,
1734             0x89 => Operator::I16x8ExtendLowI8x16U,
1735             0x8a => Operator::I16x8ExtendHighI8x16U,
1736             0x8b => Operator::I16x8Shl,
1737             0x8c => Operator::I16x8ShrS,
1738             0x8d => Operator::I16x8ShrU,
1739             0x8e => Operator::I16x8Add,
1740             0x8f => Operator::I16x8AddSatS,
1741             0x90 => Operator::I16x8AddSatU,
1742             0x91 => Operator::I16x8Sub,
1743             0x92 => Operator::I16x8SubSatS,
1744             0x93 => Operator::I16x8SubSatU,
1745             0x94 => Operator::F64x2Nearest,
1746             0x95 => Operator::I16x8Mul,
1747             0x96 => Operator::I16x8MinS,
1748             0x97 => Operator::I16x8MinU,
1749             0x98 => Operator::I16x8MaxS,
1750             0x99 => Operator::I16x8MaxU,
1751             0x9b => Operator::I16x8RoundingAverageU,
1752             0x9c => Operator::I16x8ExtMulLowI8x16S,
1753             0x9d => Operator::I16x8ExtMulHighI8x16S,
1754             0x9e => Operator::I16x8ExtMulLowI8x16U,
1755             0x9f => Operator::I16x8ExtMulHighI8x16U,
1756             0xa0 => Operator::I32x4Abs,
1757             0xa1 => Operator::I32x4Neg,
1758             0xa3 => Operator::I32x4AllTrue,
1759             0xa4 => Operator::I32x4Bitmask,
1760             0xa7 => Operator::I32x4ExtendLowI16x8S,
1761             0xa8 => Operator::I32x4ExtendHighI16x8S,
1762             0xa9 => Operator::I32x4ExtendLowI16x8U,
1763             0xaa => Operator::I32x4ExtendHighI16x8U,
1764             0xab => Operator::I32x4Shl,
1765             0xac => Operator::I32x4ShrS,
1766             0xad => Operator::I32x4ShrU,
1767             0xae => Operator::I32x4Add,
1768             0xb1 => Operator::I32x4Sub,
1769             0xb5 => Operator::I32x4Mul,
1770             0xb6 => Operator::I32x4MinS,
1771             0xb7 => Operator::I32x4MinU,
1772             0xb8 => Operator::I32x4MaxS,
1773             0xb9 => Operator::I32x4MaxU,
1774             0xba => Operator::I32x4DotI16x8S,
1775             0xbc => Operator::I32x4ExtMulLowI16x8S,
1776             0xbd => Operator::I32x4ExtMulHighI16x8S,
1777             0xbe => Operator::I32x4ExtMulLowI16x8U,
1778             0xbf => Operator::I32x4ExtMulHighI16x8U,
1779             0xc0 => Operator::I64x2Abs,
1780             0xc1 => Operator::I64x2Neg,
1781             0xc3 => Operator::I64x2AllTrue,
1782             0xc4 => Operator::I64x2Bitmask,
1783             0xc7 => Operator::I64x2ExtendLowI32x4S,
1784             0xc8 => Operator::I64x2ExtendHighI32x4S,
1785             0xc9 => Operator::I64x2ExtendLowI32x4U,
1786             0xca => Operator::I64x2ExtendHighI32x4U,
1787             0xcb => Operator::I64x2Shl,
1788             0xcc => Operator::I64x2ShrS,
1789             0xcd => Operator::I64x2ShrU,
1790             0xce => Operator::I64x2Add,
1791             0xd1 => Operator::I64x2Sub,
1792             0xd5 => Operator::I64x2Mul,
1793             0xd6 => Operator::I64x2Eq,
1794             0xd7 => Operator::I64x2Ne,
1795             0xd8 => Operator::I64x2LtS,
1796             0xd9 => Operator::I64x2GtS,
1797             0xda => Operator::I64x2LeS,
1798             0xdb => Operator::I64x2GeS,
1799             0xdc => Operator::I64x2ExtMulLowI32x4S,
1800             0xdd => Operator::I64x2ExtMulHighI32x4S,
1801             0xde => Operator::I64x2ExtMulLowI32x4U,
1802             0xdf => Operator::I64x2ExtMulHighI32x4U,
1803             0xe0 => Operator::F32x4Abs,
1804             0xe1 => Operator::F32x4Neg,
1805             0xe3 => Operator::F32x4Sqrt,
1806             0xe4 => Operator::F32x4Add,
1807             0xe5 => Operator::F32x4Sub,
1808             0xe6 => Operator::F32x4Mul,
1809             0xe7 => Operator::F32x4Div,
1810             0xe8 => Operator::F32x4Min,
1811             0xe9 => Operator::F32x4Max,
1812             0xea => Operator::F32x4PMin,
1813             0xeb => Operator::F32x4PMax,
1814             0xec => Operator::F64x2Abs,
1815             0xed => Operator::F64x2Neg,
1816             0xef => Operator::F64x2Sqrt,
1817             0xf0 => Operator::F64x2Add,
1818             0xf1 => Operator::F64x2Sub,
1819             0xf2 => Operator::F64x2Mul,
1820             0xf3 => Operator::F64x2Div,
1821             0xf4 => Operator::F64x2Min,
1822             0xf5 => Operator::F64x2Max,
1823             0xf6 => Operator::F64x2PMin,
1824             0xf7 => Operator::F64x2PMax,
1825             0xf8 => Operator::I32x4TruncSatF32x4S,
1826             0xf9 => Operator::I32x4TruncSatF32x4U,
1827             0xfa => Operator::F32x4ConvertI32x4S,
1828             0xfb => Operator::F32x4ConvertI32x4U,
1829             0xfc => Operator::I32x4TruncSatF64x2SZero,
1830             0xfd => Operator::I32x4TruncSatF64x2UZero,
1831             0xfe => Operator::F64x2ConvertLowI32x4S,
1832             0xff => Operator::F64x2ConvertLowI32x4U,
1833 
1834             _ => {
1835                 return Err(BinaryReaderError::new(
1836                     format!("Unknown 0xfd subopcode: 0x{:x}", code),
1837                     self.original_position() - 1,
1838                 ));
1839             }
1840         })
1841     }
1842 
read_file_header(&mut self) -> Result<u32>1843     pub(crate) fn read_file_header(&mut self) -> Result<u32> {
1844         let magic_number = self.read_bytes(4)?;
1845         if magic_number != WASM_MAGIC_NUMBER {
1846             return Err(BinaryReaderError::new(
1847                 "Bad magic number",
1848                 self.original_position() - 4,
1849             ));
1850         }
1851         let version = self.read_u32()?;
1852         if version != WASM_SUPPORTED_VERSION && version != WASM_EXPERIMENTAL_VERSION {
1853             return Err(BinaryReaderError::new(
1854                 "Bad version number",
1855                 self.original_position() - 4,
1856             ));
1857         }
1858         Ok(version)
1859     }
1860 
read_name_type(&mut self) -> Result<NameType>1861     pub(crate) fn read_name_type(&mut self) -> Result<NameType> {
1862         let code = self.read_var_u7()?;
1863         match code {
1864             0 => Ok(NameType::Module),
1865             1 => Ok(NameType::Function),
1866             2 => Ok(NameType::Local),
1867             _ => Ok(NameType::Unknown(code)),
1868         }
1869     }
1870 
read_linking_type(&mut self) -> Result<LinkingType>1871     pub(crate) fn read_linking_type(&mut self) -> Result<LinkingType> {
1872         let ty = self.read_var_u32()?;
1873         Ok(match ty {
1874             1 => LinkingType::StackPointer(self.read_var_u32()?),
1875             _ => {
1876                 return Err(BinaryReaderError::new(
1877                     "Invalid linking type",
1878                     self.original_position() - 1,
1879                 ));
1880             }
1881         })
1882     }
1883 
read_reloc_type(&mut self) -> Result<RelocType>1884     pub(crate) fn read_reloc_type(&mut self) -> Result<RelocType> {
1885         let code = self.read_var_u7()?;
1886         match code {
1887             0 => Ok(RelocType::FunctionIndexLEB),
1888             1 => Ok(RelocType::TableIndexSLEB),
1889             2 => Ok(RelocType::TableIndexI32),
1890             3 => Ok(RelocType::GlobalAddrLEB),
1891             4 => Ok(RelocType::GlobalAddrSLEB),
1892             5 => Ok(RelocType::GlobalAddrI32),
1893             6 => Ok(RelocType::TypeIndexLEB),
1894             7 => Ok(RelocType::GlobalIndexLEB),
1895             _ => Err(BinaryReaderError::new(
1896                 "Invalid reloc type",
1897                 self.original_position() - 1,
1898             )),
1899         }
1900     }
1901 
skip_init_expr(&mut self) -> Result<()>1902     pub(crate) fn skip_init_expr(&mut self) -> Result<()> {
1903         // TODO add skip_operator() method and/or validate init_expr operators.
1904         loop {
1905             if let Operator::End = self.read_operator()? {
1906                 return Ok(());
1907             }
1908         }
1909     }
1910 }
1911 
1912 impl<'a> BrTable<'a> {
1913     /// Returns the number of `br_table` entries, not including the default
1914     /// label
len(&self) -> usize1915     pub fn len(&self) -> usize {
1916         self.cnt
1917     }
1918 
1919     /// Returns whether `BrTable` doesn't have any labels apart from the default one.
is_empty(&self) -> bool1920     pub fn is_empty(&self) -> bool {
1921         self.len() == 0
1922     }
1923 
1924     /// Returns the list of targets that this `br_table` instruction will be
1925     /// jumping to.
1926     ///
1927     /// This method will return an iterator which parses each target of this
1928     /// `br_table` as well as the default target. The returned iterator will
1929     /// yield `self.len() + 1` elements.
1930     ///
1931     /// Each iterator item is a tuple of `(u32, bool)`, where the first item is
1932     /// the relative depth of the jump and the second item is `true` if the item
1933     /// is the default label. You're guaranteed that `true` will only show up
1934     /// for the final element of the iterator.
1935     ///
1936     /// #Examples
1937     ///
1938     /// ```rust
1939     /// let buf = [0x0e, 0x02, 0x01, 0x02, 0x00];
1940     /// let mut reader = wasmparser::BinaryReader::new(&buf);
1941     /// let op = reader.read_operator().unwrap();
1942     /// if let wasmparser::Operator::BrTable { table } = op {
1943     ///     let targets = table.targets().collect::<Result<Vec<_>, _>>().unwrap();
1944     ///     assert_eq!(targets, [(1, false), (2, false), (0, true)]);
1945     /// }
1946     /// ```
targets<'b>(&'b self) -> impl Iterator<Item = Result<(u32, bool)>> + 'b1947     pub fn targets<'b>(&'b self) -> impl Iterator<Item = Result<(u32, bool)>> + 'b {
1948         let mut reader = self.reader.clone();
1949         (0..self.cnt + 1).map(move |i| {
1950             let label = reader.read_var_u32()?;
1951             let ret = (label, i == self.cnt);
1952             if ret.1 && !reader.eof() {
1953                 return Err(BinaryReaderError::new(
1954                     "trailing data in br_table",
1955                     reader.original_position(),
1956                 ));
1957             }
1958             Ok(ret)
1959         })
1960     }
1961 }
1962 
1963 impl fmt::Debug for BrTable<'_> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1964     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1965         let mut f = f.debug_struct("BrTable");
1966         f.field("count", &self.cnt);
1967         match self.targets().collect::<Result<Vec<_>>>() {
1968             Ok(targets) => {
1969                 f.field("targets", &targets);
1970             }
1971             Err(_) => {
1972                 f.field("reader", &self.reader);
1973             }
1974         }
1975         f.finish()
1976     }
1977 }
1978