summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wasmparser/src/readers
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/wasmparser/src/readers')
-rw-r--r--third_party/rust/wasmparser/src/readers/alias_section.rs88
-rw-r--r--third_party/rust/wasmparser/src/readers/code_section.rs238
-rw-r--r--third_party/rust/wasmparser/src/readers/data_section.rs152
-rw-r--r--third_party/rust/wasmparser/src/readers/element_section.rs290
-rw-r--r--third_party/rust/wasmparser/src/readers/export_section.rs102
-rw-r--r--third_party/rust/wasmparser/src/readers/function_section.rs88
-rw-r--r--third_party/rust/wasmparser/src/readers/global_section.rs105
-rw-r--r--third_party/rust/wasmparser/src/readers/import_section.rs98
-rw-r--r--third_party/rust/wasmparser/src/readers/init_expr.rs42
-rw-r--r--third_party/rust/wasmparser/src/readers/instance_section.rs162
-rw-r--r--third_party/rust/wasmparser/src/readers/linking_section.rs78
-rw-r--r--third_party/rust/wasmparser/src/readers/memory_section.rs88
-rw-r--r--third_party/rust/wasmparser/src/readers/mod.rs63
-rw-r--r--third_party/rust/wasmparser/src/readers/module_code_section.rs96
-rw-r--r--third_party/rust/wasmparser/src/readers/module_section.rs61
-rw-r--r--third_party/rust/wasmparser/src/readers/name_section.rs253
-rw-r--r--third_party/rust/wasmparser/src/readers/operators.rs161
-rw-r--r--third_party/rust/wasmparser/src/readers/producers_section.rs197
-rw-r--r--third_party/rust/wasmparser/src/readers/reloc_section.rs118
-rw-r--r--third_party/rust/wasmparser/src/readers/section_reader.rs124
-rw-r--r--third_party/rust/wasmparser/src/readers/table_section.rs89
-rw-r--r--third_party/rust/wasmparser/src/readers/type_section.rs109
22 files changed, 2802 insertions, 0 deletions
diff --git a/third_party/rust/wasmparser/src/readers/alias_section.rs b/third_party/rust/wasmparser/src/readers/alias_section.rs
new file mode 100644
index 0000000000..bf64c18069
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/alias_section.rs
@@ -0,0 +1,88 @@
+use crate::{
+ BinaryReader, BinaryReaderError, ExternalKind, Range, Result, SectionIteratorLimited,
+ SectionReader, SectionWithLimitedItems,
+};
+
+#[derive(Clone)]
+pub struct AliasSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+#[derive(Debug)]
+pub struct Alias {
+ pub instance: AliasedInstance,
+ pub kind: ExternalKind,
+ pub index: u32,
+}
+
+#[derive(Debug)]
+pub enum AliasedInstance {
+ Parent,
+ Child(u32),
+}
+
+impl<'a> AliasSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<AliasSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(AliasSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn read(&mut self) -> Result<Alias> {
+ Ok(Alias {
+ instance: match self.reader.read_u8()? {
+ 0x00 => AliasedInstance::Child(self.reader.read_var_u32()?),
+ 0x01 => AliasedInstance::Parent,
+ _ => {
+ return Err(BinaryReaderError::new(
+ "invalid byte in alias",
+ self.original_position() - 1,
+ ))
+ }
+ },
+ kind: self.reader.read_external_kind()?,
+ index: self.reader.read_var_u32()?,
+ })
+ }
+}
+
+impl<'a> SectionReader for AliasSectionReader<'a> {
+ type Item = Alias;
+
+ fn read(&mut self) -> Result<Self::Item> {
+ AliasSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ AliasSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for AliasSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ AliasSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for AliasSectionReader<'a> {
+ type Item = Result<Alias>;
+ type IntoIter = SectionIteratorLimited<AliasSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/code_section.rs b/third_party/rust/wasmparser/src/readers/code_section.rs
new file mode 100644
index 0000000000..f17f66ac57
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/code_section.rs
@@ -0,0 +1,238 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, BinaryReaderError, OperatorsReader, Range, Result, SectionIteratorLimited,
+ SectionReader, SectionWithLimitedItems, Type,
+};
+
+#[derive(Debug, Clone)]
+pub struct FunctionBody<'a> {
+ offset: usize,
+ data: &'a [u8],
+}
+
+impl<'a> FunctionBody<'a> {
+ pub fn new(offset: usize, data: &'a [u8]) -> Self {
+ Self { offset, data }
+ }
+
+ pub fn get_binary_reader<'b>(&self) -> BinaryReader<'b>
+ where
+ 'a: 'b,
+ {
+ BinaryReader::new_with_offset(self.data, self.offset)
+ }
+
+ fn skip_locals(reader: &mut BinaryReader) -> Result<()> {
+ let count = reader.read_var_u32()?;
+ for _ in 0..count {
+ reader.skip_var_32()?;
+ reader.skip_type()?;
+ }
+ Ok(())
+ }
+
+ pub fn get_locals_reader<'b>(&self) -> Result<LocalsReader<'b>>
+ where
+ 'a: 'b,
+ {
+ let mut reader = BinaryReader::new_with_offset(self.data, self.offset);
+ let count = reader.read_var_u32()?;
+ Ok(LocalsReader { reader, count })
+ }
+
+ pub fn get_operators_reader<'b>(&self) -> Result<OperatorsReader<'b>>
+ where
+ 'a: 'b,
+ {
+ let mut reader = BinaryReader::new_with_offset(self.data, self.offset);
+ Self::skip_locals(&mut reader)?;
+ let pos = reader.position;
+ Ok(OperatorsReader::new(&self.data[pos..], self.offset + pos))
+ }
+
+ pub fn range(&self) -> Range {
+ Range {
+ start: self.offset,
+ end: self.offset + self.data.len(),
+ }
+ }
+}
+
+pub struct LocalsReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> LocalsReader<'a> {
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn read(&mut self) -> Result<(u32, Type)> {
+ let count = self.reader.read_var_u32()?;
+ let value_type = self.reader.read_type()?;
+ Ok((count, value_type))
+ }
+}
+
+pub struct CodeSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> IntoIterator for LocalsReader<'a> {
+ type Item = Result<(u32, Type)>;
+ type IntoIter = LocalsIterator<'a>;
+ fn into_iter(self) -> Self::IntoIter {
+ let count = self.count;
+ LocalsIterator {
+ reader: self,
+ left: count,
+ err: false,
+ }
+ }
+}
+
+pub struct LocalsIterator<'a> {
+ reader: LocalsReader<'a>,
+ left: u32,
+ err: bool,
+}
+
+impl<'a> Iterator for LocalsIterator<'a> {
+ type Item = Result<(u32, Type)>;
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.err || self.left == 0 {
+ return None;
+ }
+ let result = self.reader.read();
+ self.err = result.is_err();
+ self.left -= 1;
+ Some(result)
+ }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let count = self.reader.get_count() as usize;
+ (count, Some(count))
+ }
+}
+
+impl<'a> CodeSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<CodeSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(CodeSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ fn verify_body_end(&self, end: usize) -> Result<()> {
+ if self.reader.buffer.len() < end {
+ return Err(BinaryReaderError::new(
+ "Function body extends past end of the code section",
+ self.reader.original_offset + self.reader.buffer.len(),
+ ));
+ }
+ Ok(())
+ }
+
+ /// Reads content of the code section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::CodeSectionReader;
+ /// # let data: &[u8] = &[
+ /// # 0x01, 0x03, 0x00, 0x01, 0x0b];
+ /// let mut code_reader = CodeSectionReader::new(data, 0).unwrap();
+ /// for _ in 0..code_reader.get_count() {
+ /// let body = code_reader.read().expect("function body");
+ /// let mut binary_reader = body.get_binary_reader();
+ /// assert!(binary_reader.read_var_u32().expect("local count") == 0);
+ /// let op = binary_reader.read_operator().expect("first operator");
+ /// println!("First operator: {:?}", op);
+ /// }
+ /// ```
+ pub fn read<'b>(&mut self) -> Result<FunctionBody<'b>>
+ where
+ 'a: 'b,
+ {
+ let size = self.reader.read_var_u32()? as usize;
+ let body_start = self.reader.position;
+ let body_end = body_start + size;
+ self.verify_body_end(body_end)?;
+ self.reader.skip_to(body_end);
+ Ok(FunctionBody {
+ offset: self.reader.original_offset + body_start,
+ data: &self.reader.buffer[body_start..body_end],
+ })
+ }
+}
+
+impl<'a> SectionReader for CodeSectionReader<'a> {
+ type Item = FunctionBody<'a>;
+ fn read(&mut self) -> Result<Self::Item> {
+ CodeSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ CodeSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for CodeSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ CodeSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for CodeSectionReader<'a> {
+ type Item = Result<FunctionBody<'a>>;
+ type IntoIter = SectionIteratorLimited<CodeSectionReader<'a>>;
+
+ /// Implements iterator over the code section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::CodeSectionReader;
+ /// # let data: &[u8] = &[
+ /// # 0x01, 0x03, 0x00, 0x01, 0x0b];
+ /// let mut code_reader = CodeSectionReader::new(data, 0).unwrap();
+ /// for body in code_reader {
+ /// let mut binary_reader = body.expect("b").get_binary_reader();
+ /// assert!(binary_reader.read_var_u32().expect("local count") == 0);
+ /// let op = binary_reader.read_operator().expect("first operator");
+ /// println!("First operator: {:?}", op);
+ /// }
+ /// ```
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/data_section.rs b/third_party/rust/wasmparser/src/readers/data_section.rs
new file mode 100644
index 0000000000..b9675e2de8
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/data_section.rs
@@ -0,0 +1,152 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, BinaryReaderError, InitExpr, Range, Result, SectionIteratorLimited,
+ SectionReader, SectionWithLimitedItems,
+};
+
+#[derive(Debug, Copy, Clone)]
+pub struct Data<'a> {
+ pub kind: DataKind<'a>,
+ pub data: &'a [u8],
+}
+
+#[derive(Debug, Copy, Clone)]
+pub enum DataKind<'a> {
+ Passive,
+ Active {
+ memory_index: u32,
+ init_expr: InitExpr<'a>,
+ },
+}
+
+#[derive(Clone)]
+pub struct DataSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> DataSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<DataSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(DataSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ fn verify_data_end(&self, end: usize) -> Result<()> {
+ if self.reader.buffer.len() < end {
+ return Err(BinaryReaderError::new(
+ "Data segment extends past end of the data section",
+ self.reader.original_offset + self.reader.buffer.len(),
+ ));
+ }
+ Ok(())
+ }
+
+ /// Reads content of the data section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::{DataSectionReader, DataKind};
+ /// # let data: &[u8] = &[
+ /// # 0x01, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00];
+ /// let mut data_reader = DataSectionReader::new(data, 0).unwrap();
+ /// for _ in 0..data_reader.get_count() {
+ /// let data = data_reader.read().expect("data");
+ /// println!("Data: {:?}", data);
+ /// if let DataKind::Active { init_expr, .. } = data.kind {
+ /// let mut init_expr_reader = init_expr.get_binary_reader();
+ /// let op = init_expr_reader.read_operator().expect("op");
+ /// println!("Init const: {:?}", op);
+ /// }
+ /// }
+ /// ```
+ pub fn read<'b>(&mut self) -> Result<Data<'b>>
+ where
+ 'a: 'b,
+ {
+ let flags = self.reader.read_var_u32()?;
+ let kind = if flags == 1 {
+ DataKind::Passive
+ } else {
+ let memory_index = match flags {
+ 0 => 0,
+ 2 => self.reader.read_var_u32()?,
+ _ => {
+ return Err(BinaryReaderError::new(
+ "invalid flags byte in data segment",
+ self.reader.original_position() - 1,
+ ));
+ }
+ };
+ let init_expr = {
+ let expr_offset = self.reader.position;
+ self.reader.skip_init_expr()?;
+ let data = &self.reader.buffer[expr_offset..self.reader.position];
+ InitExpr::new(data, self.reader.original_offset + expr_offset)
+ };
+ DataKind::Active {
+ memory_index,
+ init_expr,
+ }
+ };
+ let data_len = self.reader.read_var_u32()? as usize;
+ let data_end = self.reader.position + data_len;
+ self.verify_data_end(data_end)?;
+ let data = &self.reader.buffer[self.reader.position..data_end];
+ self.reader.skip_to(data_end);
+ Ok(Data { kind, data })
+ }
+}
+
+impl<'a> SectionReader for DataSectionReader<'a> {
+ type Item = Data<'a>;
+ fn read(&mut self) -> Result<Self::Item> {
+ DataSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ DataSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for DataSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ DataSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for DataSectionReader<'a> {
+ type Item = Result<Data<'a>>;
+ type IntoIter = SectionIteratorLimited<DataSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/element_section.rs b/third_party/rust/wasmparser/src/readers/element_section.rs
new file mode 100644
index 0000000000..f01c2d1f62
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/element_section.rs
@@ -0,0 +1,290 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, BinaryReaderError, InitExpr, Range, Result, SectionIteratorLimited,
+ SectionReader, SectionWithLimitedItems, Type,
+};
+use crate::{ExternalKind, Operator};
+
+#[derive(Clone)]
+pub struct Element<'a> {
+ pub kind: ElementKind<'a>,
+ pub items: ElementItems<'a>,
+ pub ty: Type,
+}
+
+#[derive(Clone)]
+pub enum ElementKind<'a> {
+ Passive,
+ Active {
+ table_index: u32,
+ init_expr: InitExpr<'a>,
+ },
+ Declared,
+}
+
+#[derive(Debug, Copy, Clone)]
+pub struct ElementItems<'a> {
+ exprs: bool,
+ offset: usize,
+ data: &'a [u8],
+}
+
+#[derive(Debug)]
+pub enum ElementItem {
+ Null(Type),
+ Func(u32),
+}
+
+impl<'a> ElementItems<'a> {
+ pub fn get_items_reader<'b>(&self) -> Result<ElementItemsReader<'b>>
+ where
+ 'a: 'b,
+ {
+ ElementItemsReader::new(self.data, self.offset, self.exprs)
+ }
+}
+
+pub struct ElementItemsReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+ exprs: bool,
+}
+
+impl<'a> ElementItemsReader<'a> {
+ pub fn new(data: &[u8], offset: usize, exprs: bool) -> Result<ElementItemsReader> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(ElementItemsReader {
+ reader,
+ count,
+ exprs,
+ })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn uses_exprs(&self) -> bool {
+ self.exprs
+ }
+
+ pub fn read(&mut self) -> Result<ElementItem> {
+ if self.exprs {
+ let offset = self.reader.original_position();
+ let ret = match self.reader.read_operator()? {
+ Operator::RefNull { ty } => ElementItem::Null(ty),
+ Operator::RefFunc { function_index } => ElementItem::Func(function_index),
+ _ => return Err(BinaryReaderError::new("invalid passive segment", offset)),
+ };
+ match self.reader.read_operator()? {
+ Operator::End => {}
+ _ => return Err(BinaryReaderError::new("invalid passive segment", offset)),
+ }
+ Ok(ret)
+ } else {
+ self.reader.read_var_u32().map(ElementItem::Func)
+ }
+ }
+}
+
+impl<'a> IntoIterator for ElementItemsReader<'a> {
+ type Item = Result<ElementItem>;
+ type IntoIter = ElementItemsIterator<'a>;
+ fn into_iter(self) -> Self::IntoIter {
+ let count = self.count;
+ ElementItemsIterator {
+ reader: self,
+ left: count,
+ err: false,
+ }
+ }
+}
+
+pub struct ElementItemsIterator<'a> {
+ reader: ElementItemsReader<'a>,
+ left: u32,
+ err: bool,
+}
+
+impl<'a> Iterator for ElementItemsIterator<'a> {
+ type Item = Result<ElementItem>;
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.err || self.left == 0 {
+ return None;
+ }
+ let result = self.reader.read();
+ self.err = result.is_err();
+ self.left -= 1;
+ Some(result)
+ }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let count = self.reader.get_count() as usize;
+ (count, Some(count))
+ }
+}
+
+#[derive(Clone)]
+pub struct ElementSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> ElementSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<ElementSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(ElementSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ /// Reads content of the element section.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// # let data: &[u8] = &[];
+ /// use wasmparser::{ElementSectionReader, ElementKind};
+ /// let mut element_reader = ElementSectionReader::new(data, 0).unwrap();
+ /// for _ in 0..element_reader.get_count() {
+ /// let element = element_reader.read().expect("element");
+ /// if let ElementKind::Active { init_expr, .. } = element.kind {
+ /// let mut init_expr_reader = init_expr.get_binary_reader();
+ /// let op = init_expr_reader.read_operator().expect("op");
+ /// println!("Init const: {:?}", op);
+ /// }
+ /// let mut items_reader = element.items.get_items_reader().expect("items reader");
+ /// for _ in 0..items_reader.get_count() {
+ /// let item = items_reader.read().expect("item");
+ /// println!(" Item: {:?}", item);
+ /// }
+ /// }
+ /// ```
+ pub fn read<'b>(&mut self) -> Result<Element<'b>>
+ where
+ 'a: 'b,
+ {
+ let flags = self.reader.read_var_u32()?;
+ if (flags & !0b111) != 0 {
+ return Err(BinaryReaderError::new(
+ "invalid flags byte in element segment",
+ self.reader.original_position() - 1,
+ ));
+ }
+ let kind = if flags & 0b001 != 0 {
+ if flags & 0b010 != 0 {
+ ElementKind::Declared
+ } else {
+ ElementKind::Passive
+ }
+ } else {
+ let table_index = if flags & 0b010 == 0 {
+ 0
+ } else {
+ self.reader.read_var_u32()?
+ };
+ let init_expr = {
+ let expr_offset = self.reader.position;
+ self.reader.skip_init_expr()?;
+ let data = &self.reader.buffer[expr_offset..self.reader.position];
+ InitExpr::new(data, self.reader.original_offset + expr_offset)
+ };
+ ElementKind::Active {
+ table_index,
+ init_expr,
+ }
+ };
+ let exprs = flags & 0b100 != 0;
+ let ty = if flags & 0b011 != 0 {
+ if exprs {
+ self.reader.read_type()?
+ } else {
+ match self.reader.read_external_kind()? {
+ ExternalKind::Function => Type::FuncRef,
+ _ => {
+ return Err(BinaryReaderError::new(
+ "only the function external type is supported in elem segment",
+ self.reader.original_position() - 1,
+ ));
+ }
+ }
+ }
+ } else {
+ Type::FuncRef
+ };
+ let data_start = self.reader.position;
+ let items_count = self.reader.read_var_u32()?;
+ if exprs {
+ for _ in 0..items_count {
+ self.reader.skip_init_expr()?;
+ }
+ } else {
+ for _ in 0..items_count {
+ self.reader.skip_var_32()?;
+ }
+ }
+ let data_end = self.reader.position;
+ let items = ElementItems {
+ offset: self.reader.original_offset + data_start,
+ data: &self.reader.buffer[data_start..data_end],
+ exprs,
+ };
+ Ok(Element { kind, items, ty })
+ }
+}
+
+impl<'a> SectionReader for ElementSectionReader<'a> {
+ type Item = Element<'a>;
+ fn read(&mut self) -> Result<Self::Item> {
+ ElementSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ ElementSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for ElementSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ ElementSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for ElementSectionReader<'a> {
+ type Item = Result<Element<'a>>;
+ type IntoIter = SectionIteratorLimited<ElementSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/export_section.rs b/third_party/rust/wasmparser/src/readers/export_section.rs
new file mode 100644
index 0000000000..4e3ff3f892
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/export_section.rs
@@ -0,0 +1,102 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, ExternalKind, Range, Result, SectionIteratorLimited, SectionReader,
+ SectionWithLimitedItems,
+};
+
+#[derive(Debug, Copy, Clone)]
+pub struct Export<'a> {
+ pub field: &'a str,
+ pub kind: ExternalKind,
+ pub index: u32,
+}
+
+#[derive(Clone)]
+pub struct ExportSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> ExportSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<ExportSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(ExportSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ /// Reads content of the export section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::ExportSectionReader;
+ ///
+ /// # let data: &[u8] = &[0x01, 0x01, 0x65, 0x00, 0x00];
+ /// let mut export_reader = ExportSectionReader::new(data, 0).unwrap();
+ /// for _ in 0..export_reader.get_count() {
+ /// let export = export_reader.read().expect("export");
+ /// println!("Export: {:?}", export);
+ /// }
+ /// ```
+ pub fn read<'b>(&mut self) -> Result<Export<'b>>
+ where
+ 'a: 'b,
+ {
+ let field = self.reader.read_string()?;
+ let kind = self.reader.read_external_kind()?;
+ let index = self.reader.read_var_u32()?;
+ Ok(Export { field, kind, index })
+ }
+}
+
+impl<'a> SectionReader for ExportSectionReader<'a> {
+ type Item = Export<'a>;
+ fn read(&mut self) -> Result<Self::Item> {
+ ExportSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ ExportSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for ExportSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ ExportSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for ExportSectionReader<'a> {
+ type Item = Result<Export<'a>>;
+ type IntoIter = SectionIteratorLimited<ExportSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/function_section.rs b/third_party/rust/wasmparser/src/readers/function_section.rs
new file mode 100644
index 0000000000..0d96cf2f92
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/function_section.rs
@@ -0,0 +1,88 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, Range, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems,
+};
+
+#[derive(Clone)]
+pub struct FunctionSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> FunctionSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<FunctionSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(FunctionSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ /// Reads function type index from the function section.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use wasmparser::FunctionSectionReader;
+ /// # let data: &[u8] = &[0x01, 0x00];
+ /// let mut function_reader = FunctionSectionReader::new(data, 0).unwrap();
+ /// for _ in 0..function_reader.get_count() {
+ /// let ty = function_reader.read().expect("function type index");
+ /// println!("Function type index: {}", ty);
+ /// }
+ /// ```
+ pub fn read(&mut self) -> Result<u32> {
+ self.reader.read_var_u32()
+ }
+}
+
+impl<'a> SectionReader for FunctionSectionReader<'a> {
+ type Item = u32;
+ fn read(&mut self) -> Result<Self::Item> {
+ FunctionSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ FunctionSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for FunctionSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ FunctionSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for FunctionSectionReader<'a> {
+ type Item = Result<u32>;
+ type IntoIter = SectionIteratorLimited<FunctionSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/global_section.rs b/third_party/rust/wasmparser/src/readers/global_section.rs
new file mode 100644
index 0000000000..fdbf75797a
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/global_section.rs
@@ -0,0 +1,105 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, GlobalType, InitExpr, Range, Result, SectionIteratorLimited, SectionReader,
+ SectionWithLimitedItems,
+};
+
+#[derive(Debug, Copy, Clone)]
+pub struct Global<'a> {
+ pub ty: GlobalType,
+ pub init_expr: InitExpr<'a>,
+}
+
+#[derive(Clone)]
+pub struct GlobalSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> GlobalSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<GlobalSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(GlobalSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ /// Reads content of the global section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::GlobalSectionReader;
+ /// # let data: &[u8] = &[0x01, 0x7F, 0x01, 0x41, 0x90, 0x88, 0x04, 0x0B];
+ /// let mut global_reader = GlobalSectionReader::new(data, 0).unwrap();
+ /// for _ in 0..global_reader.get_count() {
+ /// let global = global_reader.read().expect("global");
+ /// println!("Global: {:?}", global);
+ /// let mut init_expr_reader = global.init_expr.get_binary_reader();
+ /// let op = init_expr_reader.read_operator().expect("op");
+ /// println!("Init const: {:?}", op);
+ /// }
+ /// ```
+ pub fn read<'b>(&mut self) -> Result<Global<'b>>
+ where
+ 'a: 'b,
+ {
+ let ty = self.reader.read_global_type()?;
+ let expr_offset = self.reader.position;
+ self.reader.skip_init_expr()?;
+ let data = &self.reader.buffer[expr_offset..self.reader.position];
+ let init_expr = InitExpr::new(data, self.reader.original_offset + expr_offset);
+ Ok(Global { ty, init_expr })
+ }
+}
+
+impl<'a> SectionReader for GlobalSectionReader<'a> {
+ type Item = Global<'a>;
+ fn read(&mut self) -> Result<Self::Item> {
+ GlobalSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ GlobalSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for GlobalSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ GlobalSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for GlobalSectionReader<'a> {
+ type Item = Result<Global<'a>>;
+ type IntoIter = SectionIteratorLimited<GlobalSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/import_section.rs b/third_party/rust/wasmparser/src/readers/import_section.rs
new file mode 100644
index 0000000000..4f75bcfe86
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/import_section.rs
@@ -0,0 +1,98 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use crate::{
+ BinaryReader, ImportSectionEntryType, Range, Result, SectionIteratorLimited, SectionReader,
+ SectionWithLimitedItems,
+};
+
+#[derive(Debug, Copy, Clone)]
+pub struct Import<'a> {
+ pub module: &'a str,
+ pub field: Option<&'a str>,
+ pub ty: ImportSectionEntryType,
+}
+
+#[derive(Clone)]
+pub struct ImportSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> ImportSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<ImportSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(ImportSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ /// Reads content of the import section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::ImportSectionReader;
+ /// # let data: &[u8] = &[0x01, 0x01, 0x41, 0x01, 0x66, 0x00, 0x00];
+ /// let mut import_reader = ImportSectionReader::new(data, 0).unwrap();
+ /// for _ in 0..import_reader.get_count() {
+ /// let import = import_reader.read().expect("import");
+ /// println!("Import: {:?}", import);
+ /// }
+ /// ```
+ pub fn read<'b>(&mut self) -> Result<Import<'b>>
+ where
+ 'a: 'b,
+ {
+ self.reader.read_import()
+ }
+}
+
+impl<'a> SectionReader for ImportSectionReader<'a> {
+ type Item = Import<'a>;
+ fn read(&mut self) -> Result<Self::Item> {
+ ImportSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ ImportSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for ImportSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ ImportSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for ImportSectionReader<'a> {
+ type Item = Result<Import<'a>>;
+ type IntoIter = SectionIteratorLimited<ImportSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/init_expr.rs b/third_party/rust/wasmparser/src/readers/init_expr.rs
new file mode 100644
index 0000000000..98c301d350
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/init_expr.rs
@@ -0,0 +1,42 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{BinaryReader, OperatorsReader};
+
+#[derive(Debug, Copy, Clone)]
+pub struct InitExpr<'a> {
+ offset: usize,
+ data: &'a [u8],
+}
+
+impl<'a> InitExpr<'a> {
+ pub fn new(data: &[u8], offset: usize) -> InitExpr {
+ InitExpr { offset, data }
+ }
+
+ pub fn get_binary_reader<'b>(&self) -> BinaryReader<'b>
+ where
+ 'a: 'b,
+ {
+ BinaryReader::new_with_offset(self.data, self.offset)
+ }
+
+ pub fn get_operators_reader<'b>(&self) -> OperatorsReader<'b>
+ where
+ 'a: 'b,
+ {
+ OperatorsReader::new(self.data, self.offset)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/instance_section.rs b/third_party/rust/wasmparser/src/readers/instance_section.rs
new file mode 100644
index 0000000000..5c27954044
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/instance_section.rs
@@ -0,0 +1,162 @@
+use crate::{
+ BinaryReader, BinaryReaderError, ExternalKind, Range, Result, SectionIteratorLimited,
+ SectionReader, SectionWithLimitedItems,
+};
+
+#[derive(Clone)]
+pub struct InstanceSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> InstanceSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<InstanceSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(InstanceSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn read(&mut self) -> Result<Instance<'a>> {
+ let instance = Instance::new(
+ &self.reader.buffer[self.reader.position..],
+ self.original_position(),
+ )?;
+ self.reader.skip_bytes(1)?;
+ self.reader.skip_var_32()?;
+ let count = self.reader.read_var_u32()?;
+ for _ in 0..count {
+ self.reader.skip_bytes(1)?;
+ self.reader.skip_var_32()?;
+ }
+ Ok(instance)
+ }
+}
+
+impl<'a> SectionReader for InstanceSectionReader<'a> {
+ type Item = Instance<'a>;
+
+ fn read(&mut self) -> Result<Self::Item> {
+ InstanceSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ InstanceSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for InstanceSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ InstanceSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for InstanceSectionReader<'a> {
+ type Item = Result<Instance<'a>>;
+ type IntoIter = SectionIteratorLimited<InstanceSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
+
+pub struct Instance<'a> {
+ reader: BinaryReader<'a>,
+ module: u32,
+}
+
+impl<'a> Instance<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<Instance<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ if reader.read_u8()? != 0 {
+ return Err(BinaryReaderError::new(
+ "instantiate instruction not found",
+ offset,
+ ));
+ }
+ let module = reader.read_var_u32()?;
+ Ok(Instance { module, reader })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn module(&self) -> u32 {
+ self.module
+ }
+
+ pub fn args(&self) -> Result<InstanceArgsReader<'a>> {
+ let mut reader = self.reader.clone();
+ let count = reader.read_var_u32()?;
+ Ok(InstanceArgsReader {
+ count,
+ remaining: count,
+ reader,
+ })
+ }
+}
+
+#[derive(Clone)]
+pub struct InstanceArgsReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+ remaining: u32,
+}
+
+impl<'a> InstanceArgsReader<'a> {
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn read(&mut self) -> Result<(ExternalKind, u32)> {
+ let kind = self.reader.read_external_kind()?;
+ let index = self.reader.read_var_u32()?;
+ self.remaining -= 1;
+ Ok((kind, index))
+ }
+}
+
+impl<'a> SectionReader for InstanceArgsReader<'a> {
+ type Item = (ExternalKind, u32);
+
+ fn read(&mut self) -> Result<Self::Item> {
+ InstanceArgsReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.remaining == 0
+ }
+ fn original_position(&self) -> usize {
+ InstanceArgsReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for InstanceArgsReader<'a> {
+ fn get_count(&self) -> u32 {
+ self.count
+ }
+}
+
+impl<'a> IntoIterator for InstanceArgsReader<'a> {
+ type Item = Result<(ExternalKind, u32)>;
+ type IntoIter = SectionIteratorLimited<InstanceArgsReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/linking_section.rs b/third_party/rust/wasmparser/src/readers/linking_section.rs
new file mode 100644
index 0000000000..4b999744f0
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/linking_section.rs
@@ -0,0 +1,78 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, LinkingType, Range, Result, SectionIteratorLimited, SectionReader,
+ SectionWithLimitedItems,
+};
+
+pub struct LinkingSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> LinkingSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<LinkingSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(LinkingSectionReader { reader, count })
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn read<'b>(&mut self) -> Result<LinkingType>
+ where
+ 'a: 'b,
+ {
+ Ok(self.reader.read_linking_type()?)
+ }
+}
+
+impl<'a> SectionReader for LinkingSectionReader<'a> {
+ type Item = LinkingType;
+ fn read(&mut self) -> Result<Self::Item> {
+ LinkingSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ LinkingSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for LinkingSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ LinkingSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for LinkingSectionReader<'a> {
+ type Item = Result<LinkingType>;
+ type IntoIter = SectionIteratorLimited<LinkingSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/memory_section.rs b/third_party/rust/wasmparser/src/readers/memory_section.rs
new file mode 100644
index 0000000000..b84a59dff1
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/memory_section.rs
@@ -0,0 +1,88 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, MemoryType, Range, Result, SectionIteratorLimited, SectionReader,
+ SectionWithLimitedItems,
+};
+
+#[derive(Clone)]
+pub struct MemorySectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> MemorySectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<MemorySectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(MemorySectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ /// Reads content of the memory section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::MemorySectionReader;
+ /// # let data: &[u8] = &[0x01, 0x00, 0x02];
+ /// let mut memory_reader = MemorySectionReader::new(data, 0).unwrap();
+ /// for _ in 0..memory_reader.get_count() {
+ /// let memory = memory_reader.read().expect("memory");
+ /// println!("Memory: {:?}", memory);
+ /// }
+ /// ```
+ pub fn read(&mut self) -> Result<MemoryType> {
+ self.reader.read_memory_type()
+ }
+}
+
+impl<'a> SectionReader for MemorySectionReader<'a> {
+ type Item = MemoryType;
+ fn read(&mut self) -> Result<Self::Item> {
+ MemorySectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ MemorySectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for MemorySectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ MemorySectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for MemorySectionReader<'a> {
+ type Item = Result<MemoryType>;
+ type IntoIter = SectionIteratorLimited<MemorySectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/mod.rs b/third_party/rust/wasmparser/src/readers/mod.rs
new file mode 100644
index 0000000000..9cf8bf1a81
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/mod.rs
@@ -0,0 +1,63 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, BinaryReaderError, ExternalKind, GlobalType, LinkingType, MemoryType, NameType,
+ Naming, Operator, Range, RelocType, Result, SectionCode, TableType, Type,
+};
+
+pub use self::alias_section::*;
+pub use self::code_section::*;
+pub use self::data_section::*;
+pub use self::element_section::*;
+pub use self::export_section::*;
+pub use self::function_section::*;
+pub use self::global_section::*;
+pub use self::import_section::*;
+pub use self::init_expr::*;
+pub use self::instance_section::*;
+pub use self::linking_section::*;
+pub use self::memory_section::*;
+pub use self::module_code_section::*;
+pub use self::module_section::*;
+pub use self::name_section::*;
+pub use self::operators::*;
+pub use self::producers_section::*;
+pub use self::reloc_section::*;
+pub use self::section_reader::*;
+pub use self::table_section::*;
+pub use self::type_section::*;
+
+mod alias_section;
+mod code_section;
+mod data_section;
+mod element_section;
+mod export_section;
+mod function_section;
+mod global_section;
+mod import_section;
+mod init_expr;
+mod instance_section;
+mod linking_section;
+mod memory_section;
+mod module_code_section;
+mod module_section;
+mod name_section;
+mod operators;
+mod producers_section;
+mod reloc_section;
+mod section_reader;
+mod table_section;
+mod type_section;
diff --git a/third_party/rust/wasmparser/src/readers/module_code_section.rs b/third_party/rust/wasmparser/src/readers/module_code_section.rs
new file mode 100644
index 0000000000..866cd443af
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/module_code_section.rs
@@ -0,0 +1,96 @@
+use crate::{
+ BinaryReader, BinaryReaderError, Range, Result, SectionIteratorLimited, SectionReader,
+ SectionWithLimitedItems,
+};
+
+pub struct ModuleCodeSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+#[derive(Debug)]
+pub struct ModuleCode<'a> {
+ reader: BinaryReader<'a>,
+}
+
+impl<'a> ModuleCodeSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<ModuleCodeSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(ModuleCodeSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ fn verify_module_end(&self, end: usize) -> Result<()> {
+ if self.reader.buffer.len() < end {
+ return Err(BinaryReaderError::new(
+ "module body extends past end of the module code section",
+ self.reader.original_offset + self.reader.buffer.len(),
+ ));
+ }
+ Ok(())
+ }
+
+ pub fn read(&mut self) -> Result<ModuleCode<'a>> {
+ let size = self.reader.read_var_u32()? as usize;
+ let module_start = self.reader.position;
+ let module_end = module_start + size;
+ self.verify_module_end(module_end)?;
+ self.reader.skip_to(module_end);
+ Ok(ModuleCode {
+ reader: BinaryReader::new_with_offset(
+ &self.reader.buffer[module_start..module_end],
+ self.reader.original_offset + module_start,
+ ),
+ })
+ }
+}
+
+impl<'a> SectionReader for ModuleCodeSectionReader<'a> {
+ type Item = ModuleCode<'a>;
+
+ fn read(&mut self) -> Result<Self::Item> {
+ ModuleCodeSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ ModuleCodeSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for ModuleCodeSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ ModuleCodeSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for ModuleCodeSectionReader<'a> {
+ type Item = Result<ModuleCode<'a>>;
+ type IntoIter = SectionIteratorLimited<ModuleCodeSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
+
+impl<'a> ModuleCode<'a> {
+ pub fn raw_bytes(&self) -> (usize, &[u8]) {
+ (self.reader.original_position(), self.reader.buffer)
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/module_section.rs b/third_party/rust/wasmparser/src/readers/module_section.rs
new file mode 100644
index 0000000000..86b73f7a7f
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/module_section.rs
@@ -0,0 +1,61 @@
+use super::{
+ BinaryReader, Range, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems,
+};
+
+#[derive(Clone)]
+pub struct ModuleSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> ModuleSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<ModuleSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(ModuleSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn read(&mut self) -> Result<u32> {
+ self.reader.read_var_u32()
+ }
+}
+
+impl<'a> SectionReader for ModuleSectionReader<'a> {
+ type Item = u32;
+
+ fn read(&mut self) -> Result<Self::Item> {
+ ModuleSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ ModuleSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for ModuleSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ ModuleSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for ModuleSectionReader<'a> {
+ type Item = Result<u32>;
+ type IntoIter = SectionIteratorLimited<ModuleSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/name_section.rs b/third_party/rust/wasmparser/src/readers/name_section.rs
new file mode 100644
index 0000000000..343a7441ab
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/name_section.rs
@@ -0,0 +1,253 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, BinaryReaderError, NameType, Naming, Range, Result, SectionIterator,
+ SectionReader,
+};
+
+#[derive(Debug, Copy, Clone)]
+pub struct ModuleName<'a> {
+ data: &'a [u8],
+ offset: usize,
+}
+
+impl<'a> ModuleName<'a> {
+ pub fn get_name<'b>(&self) -> Result<&'b str>
+ where
+ 'a: 'b,
+ {
+ let mut reader = BinaryReader::new_with_offset(self.data, self.offset);
+ reader.read_string()
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.offset
+ }
+}
+
+pub struct NamingReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> NamingReader<'a> {
+ fn new(data: &'a [u8], offset: usize) -> Result<NamingReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(NamingReader { reader, count })
+ }
+
+ fn skip(reader: &mut BinaryReader) -> Result<()> {
+ let count = reader.read_var_u32()?;
+ for _ in 0..count {
+ reader.skip_var_32()?;
+ reader.skip_string()?;
+ }
+ Ok(())
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn read<'b>(&mut self) -> Result<Naming<'b>>
+ where
+ 'a: 'b,
+ {
+ let index = self.reader.read_var_u32()?;
+ let name = self.reader.read_string()?;
+ Ok(Naming { index, name })
+ }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub struct FunctionName<'a> {
+ data: &'a [u8],
+ offset: usize,
+}
+
+impl<'a> FunctionName<'a> {
+ pub fn get_map<'b>(&self) -> Result<NamingReader<'b>>
+ where
+ 'a: 'b,
+ {
+ NamingReader::new(self.data, self.offset)
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.offset
+ }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub struct FunctionLocalName<'a> {
+ pub func_index: u32,
+ data: &'a [u8],
+ offset: usize,
+}
+
+impl<'a> FunctionLocalName<'a> {
+ pub fn get_map<'b>(&self) -> Result<NamingReader<'b>>
+ where
+ 'a: 'b,
+ {
+ NamingReader::new(self.data, self.offset)
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.offset
+ }
+}
+
+pub struct FunctionLocalReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> FunctionLocalReader<'a> {
+ fn new(data: &'a [u8], offset: usize) -> Result<FunctionLocalReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(FunctionLocalReader { reader, count })
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn read<'b>(&mut self) -> Result<FunctionLocalName<'b>>
+ where
+ 'a: 'b,
+ {
+ let func_index = self.reader.read_var_u32()?;
+ let start = self.reader.position;
+ NamingReader::skip(&mut self.reader)?;
+ let end = self.reader.position;
+ Ok(FunctionLocalName {
+ func_index,
+ data: &self.reader.buffer[start..end],
+ offset: self.reader.original_offset + start,
+ })
+ }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub struct LocalName<'a> {
+ data: &'a [u8],
+ offset: usize,
+}
+
+impl<'a> LocalName<'a> {
+ pub fn get_function_local_reader<'b>(&self) -> Result<FunctionLocalReader<'b>>
+ where
+ 'a: 'b,
+ {
+ FunctionLocalReader::new(self.data, self.offset)
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.offset
+ }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub enum Name<'a> {
+ Module(ModuleName<'a>),
+ Function(FunctionName<'a>),
+ Local(LocalName<'a>),
+}
+
+pub struct NameSectionReader<'a> {
+ reader: BinaryReader<'a>,
+}
+
+impl<'a> NameSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<NameSectionReader<'a>> {
+ Ok(NameSectionReader {
+ reader: BinaryReader::new_with_offset(data, offset),
+ })
+ }
+
+ fn verify_section_end(&self, end: usize) -> Result<()> {
+ if self.reader.buffer.len() < end {
+ return Err(BinaryReaderError::new(
+ "Name entry extends past end of the code section",
+ self.reader.original_offset + self.reader.buffer.len(),
+ ));
+ }
+ Ok(())
+ }
+
+ pub fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn read<'b>(&mut self) -> Result<Name<'b>>
+ where
+ 'a: 'b,
+ {
+ let ty = self.reader.read_name_type()?;
+ let payload_len = self.reader.read_var_u32()? as usize;
+ let payload_start = self.reader.position;
+ let payload_end = payload_start + payload_len;
+ self.verify_section_end(payload_end)?;
+ let offset = self.reader.original_offset + payload_start;
+ let data = &self.reader.buffer[payload_start..payload_end];
+ self.reader.skip_to(payload_end);
+ Ok(match ty {
+ NameType::Module => Name::Module(ModuleName { data, offset }),
+ NameType::Function => Name::Function(FunctionName { data, offset }),
+ NameType::Local => Name::Local(LocalName { data, offset }),
+ })
+ }
+}
+
+impl<'a> SectionReader for NameSectionReader<'a> {
+ type Item = Name<'a>;
+ fn read(&mut self) -> Result<Self::Item> {
+ NameSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ NameSectionReader::eof(self)
+ }
+ fn original_position(&self) -> usize {
+ NameSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> IntoIterator for NameSectionReader<'a> {
+ type Item = Result<Name<'a>>;
+ type IntoIter = SectionIterator<NameSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIterator::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/operators.rs b/third_party/rust/wasmparser/src/readers/operators.rs
new file mode 100644
index 0000000000..cda42571dd
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/operators.rs
@@ -0,0 +1,161 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{BinaryReader, BinaryReaderError, Operator, Result};
+
+#[derive(Clone)]
+pub struct OperatorsReader<'a> {
+ pub(crate) reader: BinaryReader<'a>,
+}
+
+impl<'a> OperatorsReader<'a> {
+ pub(crate) fn new<'b>(data: &'a [u8], offset: usize) -> OperatorsReader<'b>
+ where
+ 'a: 'b,
+ {
+ OperatorsReader {
+ reader: BinaryReader::new_with_offset(data, offset),
+ }
+ }
+
+ pub fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn ensure_end(&self) -> Result<()> {
+ if self.eof() {
+ return Ok(());
+ }
+ Err(BinaryReaderError::new(
+ "Unexpected data at the end of operators",
+ self.reader.original_position(),
+ ))
+ }
+
+ pub fn read<'b>(&mut self) -> Result<Operator<'b>>
+ where
+ 'a: 'b,
+ {
+ self.reader.read_operator()
+ }
+
+ pub fn into_iter_with_offsets<'b>(self) -> OperatorsIteratorWithOffsets<'b>
+ where
+ 'a: 'b,
+ {
+ OperatorsIteratorWithOffsets {
+ reader: self,
+ err: false,
+ }
+ }
+
+ pub fn read_with_offset<'b>(&mut self) -> Result<(Operator<'b>, usize)>
+ where
+ 'a: 'b,
+ {
+ let pos = self.reader.original_position();
+ Ok((self.read()?, pos))
+ }
+}
+
+impl<'a> IntoIterator for OperatorsReader<'a> {
+ type Item = Result<Operator<'a>>;
+ type IntoIter = OperatorsIterator<'a>;
+
+ /// Reads content of the code section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::{Operator, CodeSectionReader, Result};
+ /// # let data: &[u8] = &[
+ /// # 0x01, 0x03, 0x00, 0x01, 0x0b];
+ /// let mut code_reader = CodeSectionReader::new(data, 0).unwrap();
+ /// for _ in 0..code_reader.get_count() {
+ /// let body = code_reader.read().expect("function body");
+ /// let mut op_reader = body.get_operators_reader().expect("op reader");
+ /// let ops = op_reader.into_iter().collect::<Result<Vec<Operator>>>().expect("ops");
+ /// assert!(
+ /// if let [Operator::Nop, Operator::End] = ops.as_slice() { true } else { false },
+ /// "found {:?}",
+ /// ops
+ /// );
+ /// }
+ /// ```
+ fn into_iter(self) -> Self::IntoIter {
+ OperatorsIterator {
+ reader: self,
+ err: false,
+ }
+ }
+}
+
+pub struct OperatorsIterator<'a> {
+ reader: OperatorsReader<'a>,
+ err: bool,
+}
+
+impl<'a> Iterator for OperatorsIterator<'a> {
+ type Item = Result<Operator<'a>>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.err || self.reader.eof() {
+ return None;
+ }
+ let result = self.reader.read();
+ self.err = result.is_err();
+ Some(result)
+ }
+}
+
+pub struct OperatorsIteratorWithOffsets<'a> {
+ reader: OperatorsReader<'a>,
+ err: bool,
+}
+
+impl<'a> Iterator for OperatorsIteratorWithOffsets<'a> {
+ type Item = Result<(Operator<'a>, usize)>;
+
+ /// Reads content of the code section with offsets.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::{Operator, CodeSectionReader, Result};
+ /// # let data: &[u8] = &[
+ /// # 0x01, 0x03, 0x00, /* offset = 23 */ 0x01, 0x0b];
+ /// let mut code_reader = CodeSectionReader::new(data, 20).unwrap();
+ /// for _ in 0..code_reader.get_count() {
+ /// let body = code_reader.read().expect("function body");
+ /// let mut op_reader = body.get_operators_reader().expect("op reader");
+ /// let ops = op_reader.into_iter_with_offsets().collect::<Result<Vec<(Operator, usize)>>>().expect("ops");
+ /// assert!(
+ /// if let [(Operator::Nop, 23), (Operator::End, 24)] = ops.as_slice() { true } else { false },
+ /// "found {:?}",
+ /// ops
+ /// );
+ /// }
+ /// ```
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.err || self.reader.eof() {
+ return None;
+ }
+ let result = self.reader.read_with_offset();
+ self.err = result.is_err();
+ Some(result)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/producers_section.rs b/third_party/rust/wasmparser/src/readers/producers_section.rs
new file mode 100644
index 0000000000..d6a9051b16
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/producers_section.rs
@@ -0,0 +1,197 @@
+/* Copyright 2019 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, Range, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems,
+};
+
+#[derive(Debug, Copy, Clone)]
+pub struct ProducersFieldValue<'a> {
+ pub name: &'a str,
+ pub version: &'a str,
+}
+
+pub struct ProducersFieldValuesReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> ProducersFieldValuesReader<'a> {
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ fn skip(reader: &mut BinaryReader, values_count: u32) -> Result<()> {
+ for _ in 0..values_count {
+ reader.skip_string()?;
+ reader.skip_string()?;
+ }
+ Ok(())
+ }
+
+ pub fn read<'b>(&mut self) -> Result<ProducersFieldValue<'b>>
+ where
+ 'a: 'b,
+ {
+ let name = self.reader.read_string()?;
+ let version = self.reader.read_string()?;
+ Ok(ProducersFieldValue { name, version })
+ }
+}
+
+impl<'a> IntoIterator for ProducersFieldValuesReader<'a> {
+ type Item = Result<ProducersFieldValue<'a>>;
+ type IntoIter = ProducersFieldValuesIterator<'a>;
+ fn into_iter(self) -> Self::IntoIter {
+ let count = self.count;
+ ProducersFieldValuesIterator {
+ reader: self,
+ left: count,
+ err: false,
+ }
+ }
+}
+
+pub struct ProducersFieldValuesIterator<'a> {
+ reader: ProducersFieldValuesReader<'a>,
+ left: u32,
+ err: bool,
+}
+
+impl<'a> Iterator for ProducersFieldValuesIterator<'a> {
+ type Item = Result<ProducersFieldValue<'a>>;
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.err || self.left == 0 {
+ return None;
+ }
+ let result = self.reader.read();
+ self.err = result.is_err();
+ self.left -= 1;
+ Some(result)
+ }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let count = self.reader.get_count() as usize;
+ (count, Some(count))
+ }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub struct ProducersField<'a> {
+ pub name: &'a str,
+ values_count: u32,
+ values_data: &'a [u8],
+ values_offset: usize,
+}
+
+impl<'a> ProducersField<'a> {
+ pub fn get_producer_field_values_reader<'b>(&self) -> Result<ProducersFieldValuesReader<'b>>
+ where
+ 'a: 'b,
+ {
+ Ok(ProducersFieldValuesReader {
+ reader: BinaryReader::new_with_offset(self.values_data, self.values_offset),
+ count: self.values_count,
+ })
+ }
+}
+
+pub struct ProducersSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> ProducersSectionReader<'a> {
+ /// Creates reader for the producers section.
+ ///
+ /// # Examples
+ /// ```
+ /// # let data: &[u8] = &[0x01, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65,
+ /// # 0x02, 0x03, 0x77, 0x61, 0x74, 0x01, 0x31, 0x01, 0x43, 0x03, 0x39, 0x2e, 0x30];
+ /// use wasmparser::{ProducersSectionReader, ProducersFieldValue, Result};
+ /// let mut reader = ProducersSectionReader::new(data, 0).expect("producers reader");
+ /// let field = reader.read().expect("producers field");
+ /// assert!(field.name == "language");
+ /// let mut values_reader = field.get_producer_field_values_reader().expect("values reader");
+ /// let value = values_reader.into_iter().collect::<Result<Vec<ProducersFieldValue>>>().expect("values");
+ /// assert!(value.len() == 2);
+ /// assert!(value[0].name == "wat" && value[0].version == "1");
+ /// assert!(value[1].name == "C" && value[1].version == "9.0");
+ /// ```
+ pub fn new(data: &'a [u8], offset: usize) -> Result<ProducersSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(ProducersSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn read<'b>(&mut self) -> Result<ProducersField<'b>>
+ where
+ 'a: 'b,
+ {
+ let name = self.reader.read_string()?;
+ let values_count = self.reader.read_var_u32()?;
+ let values_start = self.reader.position;
+ ProducersFieldValuesReader::skip(&mut self.reader, values_count)?;
+ let values_end = self.reader.position;
+ Ok(ProducersField {
+ name,
+ values_count,
+ values_data: &self.reader.buffer[values_start..values_end],
+ values_offset: self.reader.original_offset + values_start,
+ })
+ }
+}
+
+impl<'a> SectionReader for ProducersSectionReader<'a> {
+ type Item = ProducersField<'a>;
+ fn read(&mut self) -> Result<Self::Item> {
+ ProducersSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ ProducersSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for ProducersSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ ProducersSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for ProducersSectionReader<'a> {
+ type Item = Result<ProducersField<'a>>;
+ type IntoIter = SectionIteratorLimited<ProducersSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/reloc_section.rs b/third_party/rust/wasmparser/src/readers/reloc_section.rs
new file mode 100644
index 0000000000..b390ff90b6
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/reloc_section.rs
@@ -0,0 +1,118 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, Range, RelocType, Result, SectionCode, SectionIteratorLimited, SectionReader,
+ SectionWithLimitedItems,
+};
+
+#[derive(Debug, Copy, Clone)]
+pub struct Reloc {
+ pub ty: RelocType,
+ pub offset: u32,
+ pub index: u32,
+ pub addend: Option<u32>,
+}
+
+pub struct RelocSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ section_code: SectionCode<'a>,
+ count: u32,
+}
+
+impl<'a> RelocSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<RelocSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+
+ let section_id_position = reader.position;
+ let section_id = reader.read_var_u7()?;
+ let section_code = reader.read_section_code(section_id, section_id_position)?;
+
+ let count = reader.read_var_u32()?;
+ Ok(RelocSectionReader {
+ reader,
+ section_code,
+ count,
+ })
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ pub fn get_section_code<'b>(&self) -> SectionCode<'b>
+ where
+ 'a: 'b,
+ {
+ self.section_code
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn read(&mut self) -> Result<Reloc> {
+ let ty = self.reader.read_reloc_type()?;
+ let offset = self.reader.read_var_u32()?;
+ let index = self.reader.read_var_u32()?;
+ let addend = match ty {
+ RelocType::FunctionIndexLEB
+ | RelocType::TableIndexSLEB
+ | RelocType::TableIndexI32
+ | RelocType::TypeIndexLEB
+ | RelocType::GlobalIndexLEB => None,
+ RelocType::GlobalAddrLEB | RelocType::GlobalAddrSLEB | RelocType::GlobalAddrI32 => {
+ Some(self.reader.read_var_u32()?)
+ }
+ };
+ Ok(Reloc {
+ ty,
+ offset,
+ index,
+ addend,
+ })
+ }
+}
+
+impl<'a> SectionReader for RelocSectionReader<'a> {
+ type Item = Reloc;
+ fn read(&mut self) -> Result<Self::Item> {
+ RelocSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ RelocSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for RelocSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ RelocSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for RelocSectionReader<'a> {
+ type Item = Result<Reloc>;
+ type IntoIter = SectionIteratorLimited<RelocSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/section_reader.rs b/third_party/rust/wasmparser/src/readers/section_reader.rs
new file mode 100644
index 0000000000..395c1a2fd4
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/section_reader.rs
@@ -0,0 +1,124 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{BinaryReaderError, Range, Result};
+
+pub trait SectionReader {
+ type Item;
+ fn read(&mut self) -> Result<Self::Item>;
+ fn eof(&self) -> bool;
+ fn original_position(&self) -> usize;
+ fn range(&self) -> Range;
+ fn ensure_end(&self) -> Result<()> {
+ if self.eof() {
+ return Ok(());
+ }
+ Err(BinaryReaderError::new(
+ "Unexpected data at the end of the section",
+ self.original_position(),
+ ))
+ }
+}
+
+pub trait SectionWithLimitedItems {
+ fn get_count(&self) -> u32;
+}
+
+pub struct SectionIterator<R>
+where
+ R: SectionReader,
+{
+ reader: R,
+ err: bool,
+}
+
+impl<R> SectionIterator<R>
+where
+ R: SectionReader,
+{
+ pub fn new(reader: R) -> SectionIterator<R> {
+ SectionIterator { reader, err: false }
+ }
+}
+
+impl<R> Iterator for SectionIterator<R>
+where
+ R: SectionReader,
+{
+ type Item = Result<R::Item>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.err || self.reader.eof() {
+ return None;
+ }
+ let result = self.reader.read();
+ self.err = result.is_err();
+ Some(result)
+ }
+}
+
+pub struct SectionIteratorLimited<R>
+where
+ R: SectionReader + SectionWithLimitedItems,
+{
+ reader: R,
+ left: u32,
+ end: bool,
+}
+
+impl<R> SectionIteratorLimited<R>
+where
+ R: SectionReader + SectionWithLimitedItems,
+{
+ pub fn new(reader: R) -> SectionIteratorLimited<R> {
+ let left = reader.get_count();
+ SectionIteratorLimited {
+ reader,
+ left,
+ end: false,
+ }
+ }
+}
+
+impl<R> Iterator for SectionIteratorLimited<R>
+where
+ R: SectionReader + SectionWithLimitedItems,
+{
+ type Item = Result<R::Item>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.end {
+ return None;
+ }
+ if self.left == 0 {
+ return match self.reader.ensure_end() {
+ Ok(()) => None,
+ Err(err) => {
+ self.end = true;
+ Some(Err(err))
+ }
+ };
+ }
+ let result = self.reader.read();
+ self.end = result.is_err();
+ self.left -= 1;
+ Some(result)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let count = self.reader.get_count() as usize;
+ (count, Some(count))
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/table_section.rs b/third_party/rust/wasmparser/src/readers/table_section.rs
new file mode 100644
index 0000000000..40fb4942ee
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/table_section.rs
@@ -0,0 +1,89 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+ BinaryReader, Range, Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems,
+ TableType,
+};
+
+#[derive(Clone)]
+pub struct TableSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> TableSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<TableSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(TableSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ /// Reads content of the table section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::TableSectionReader;
+ ///
+ /// # let data: &[u8] = &[0x01, 0x70, 0x01, 0x01, 0x01];
+ /// let mut table_reader = TableSectionReader::new(data, 0).unwrap();
+ /// for _ in 0..table_reader.get_count() {
+ /// let table = table_reader.read().expect("table");
+ /// println!("Table: {:?}", table);
+ /// }
+ /// ```
+ pub fn read(&mut self) -> Result<TableType> {
+ self.reader.read_table_type()
+ }
+}
+
+impl<'a> SectionReader for TableSectionReader<'a> {
+ type Item = TableType;
+ fn read(&mut self) -> Result<Self::Item> {
+ TableSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ TableSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for TableSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ TableSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for TableSectionReader<'a> {
+ type Item = Result<TableType>;
+ type IntoIter = SectionIteratorLimited<TableSectionReader<'a>>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}
diff --git a/third_party/rust/wasmparser/src/readers/type_section.rs b/third_party/rust/wasmparser/src/readers/type_section.rs
new file mode 100644
index 0000000000..addd756727
--- /dev/null
+++ b/third_party/rust/wasmparser/src/readers/type_section.rs
@@ -0,0 +1,109 @@
+/* Copyright 2018 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use crate::{
+ BinaryReader, BinaryReaderError, Range, Result, SectionIteratorLimited, SectionReader,
+ SectionWithLimitedItems, TypeDef,
+};
+
+#[derive(Clone)]
+pub struct TypeSectionReader<'a> {
+ reader: BinaryReader<'a>,
+ count: u32,
+}
+
+impl<'a> TypeSectionReader<'a> {
+ pub fn new(data: &'a [u8], offset: usize) -> Result<TypeSectionReader<'a>> {
+ let mut reader = BinaryReader::new_with_offset(data, offset);
+ let count = reader.read_var_u32()?;
+ Ok(TypeSectionReader { reader, count })
+ }
+
+ pub fn original_position(&self) -> usize {
+ self.reader.original_position()
+ }
+
+ pub fn get_count(&self) -> u32 {
+ self.count
+ }
+
+ /// Reads content of the type section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::TypeSectionReader;
+ /// # let data: &[u8] = &[0x01, 0x60, 0x00, 0x00];
+ /// let mut type_reader = TypeSectionReader::new(data, 0).unwrap();
+ /// for _ in 0..type_reader.get_count() {
+ /// let ty = type_reader.read().expect("type");
+ /// println!("Type {:?}", ty);
+ /// }
+ /// ```
+ pub fn read(&mut self) -> Result<TypeDef<'a>> {
+ Ok(match self.reader.read_u8()? {
+ 0x60 => TypeDef::Func(self.reader.read_func_type()?),
+ 0x61 => TypeDef::Module(self.reader.read_module_type()?),
+ 0x62 => TypeDef::Instance(self.reader.read_instance_type()?),
+ _ => {
+ return Err(BinaryReaderError::new(
+ "invalid leading byte in type definition",
+ self.original_position() - 1,
+ ))
+ }
+ })
+ }
+}
+
+impl<'a> SectionReader for TypeSectionReader<'a> {
+ type Item = TypeDef<'a>;
+ fn read(&mut self) -> Result<Self::Item> {
+ TypeSectionReader::read(self)
+ }
+ fn eof(&self) -> bool {
+ self.reader.eof()
+ }
+ fn original_position(&self) -> usize {
+ TypeSectionReader::original_position(self)
+ }
+ fn range(&self) -> Range {
+ self.reader.range()
+ }
+}
+
+impl<'a> SectionWithLimitedItems for TypeSectionReader<'a> {
+ fn get_count(&self) -> u32 {
+ TypeSectionReader::get_count(self)
+ }
+}
+
+impl<'a> IntoIterator for TypeSectionReader<'a> {
+ type Item = Result<TypeDef<'a>>;
+ type IntoIter = SectionIteratorLimited<TypeSectionReader<'a>>;
+
+ /// Implements iterator over the type section.
+ ///
+ /// # Examples
+ /// ```
+ /// use wasmparser::TypeSectionReader;
+ /// # let data: &[u8] = &[0x01, 0x60, 0x00, 0x00];
+ /// let mut type_reader = TypeSectionReader::new(data, 0).unwrap();
+ /// for ty in type_reader {
+ /// println!("Type {:?}", ty);
+ /// }
+ /// ```
+ fn into_iter(self) -> Self::IntoIter {
+ SectionIteratorLimited::new(self)
+ }
+}