summaryrefslogtreecommitdiff
path: root/crates/parser/src/module.rs
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2023-12-01 14:00:46 +0100
committerHenry Gressmann <mail@henrygressmann.de>2023-12-01 14:00:46 +0100
commit871398ff821255debdbd9452e46ca55a05e8cb92 (patch)
treebac4777cf6123ff3640f4377fa33091b68d02d91 /crates/parser/src/module.rs
parent266afb16777970b37a61889039a0a2ea1ad1f83a (diff)
feat: wip: seperate parser and types crates
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates/parser/src/module.rs')
-rw-r--r--crates/parser/src/module.rs181
1 files changed, 181 insertions, 0 deletions
diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs
new file mode 100644
index 0000000..e2e1bde
--- /dev/null
+++ b/crates/parser/src/module.rs
@@ -0,0 +1,181 @@
+use alloc::{format, vec::Vec};
+use core::fmt::Debug;
+use tracing::debug;
+use wasmparser::{
+ ExportSectionReader, FunctionBody, FunctionSectionReader, Payload, TypeSectionReader, Validator,
+};
+
+use crate::{ParseError, Result};
+
+#[derive(Default)]
+pub struct ModuleReader<'a> {
+ pub version: Option<u16>,
+ pub start_func: Option<u32>,
+
+ pub type_section: Option<TypeSectionReader<'a>>,
+ pub function_section: Option<FunctionSectionReader<'a>>,
+ pub export_section: Option<ExportSectionReader<'a>>,
+ pub code_section: Option<CodeSection<'a>>,
+
+ // pub table_section: Option<TableSectionReader<'a>>,
+ // pub memory_section: Option<MemorySectionReader<'a>>,
+ // pub global_section: Option<GlobalSectionReader<'a>>,
+ // pub element_section: Option<ElementSectionReader<'a>>,
+ // pub data_section: Option<DataSectionReader<'a>>,
+ // pub import_section: Option<ImportSectionReader<'a>>,
+ pub end_reached: bool,
+}
+
+impl Debug for ModuleReader<'_> {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ f.debug_struct("ModuleReader")
+ .field("version", &self.version)
+ .field("type_section", &self.type_section)
+ .field("function_section", &self.function_section)
+ .field("code_section", &self.code_section)
+ .field("export_section", &self.export_section)
+ // .field("table_section", &self.table_section)
+ // .field("memory_section", &self.memory_section)
+ // .field("global_section", &self.global_section)
+ // .field("element_section", &self.element_section)
+ // .field("data_section", &self.data_section)
+ // .field("import_section", &self.import_section)
+ .finish()
+ }
+}
+
+impl<'a> ModuleReader<'a> {
+ pub fn new() -> ModuleReader<'a> {
+ Self::default()
+ }
+
+ pub fn process_payload(
+ &mut self,
+ payload: Payload<'a>,
+ validator: &mut Validator,
+ ) -> Result<()> {
+ use wasmparser::Payload::*;
+
+ match payload {
+ Version {
+ num,
+ encoding,
+ range,
+ } => {
+ validator.version(num, encoding, &range)?;
+ self.version = Some(num);
+ match encoding {
+ wasmparser::Encoding::Module => {}
+ wasmparser::Encoding::Component => {
+ return Err(ParseError::InvalidEncoding(encoding))
+ }
+ }
+ }
+ StartSection { func, range } => {
+ debug!("Found start section");
+ validator.start_section(func, &range)?;
+ self.start_func = Some(func);
+ }
+ TypeSection(reader) => {
+ debug!("Found type section");
+ validator.type_section(&reader)?;
+ self.type_section = Some(reader);
+ }
+ FunctionSection(reader) => {
+ debug!("Found function section");
+ validator.function_section(&reader)?;
+ self.function_section = Some(reader);
+ }
+ TableSection(_reader) => {
+ return Err(ParseError::UnsupportedSection("Table section".into()));
+ // debug!("Found table section");
+ // validator.table_section(&reader)?;
+ // self.table_section = Some(reader);
+ }
+ MemorySection(_reader) => {
+ return Err(ParseError::UnsupportedSection("Memory section".into()));
+ // debug!("Found memory section");
+ // validator.memory_section(&reader)?;
+ // self.memory_section = Some(reader);
+ }
+ GlobalSection(_reader) => {
+ return Err(ParseError::UnsupportedSection("Global section".into()));
+ // debug!("Found global section");
+ // validator.global_section(&reader)?;
+ // self.global_section = Some(reader);
+ }
+ ElementSection(_reader) => {
+ return Err(ParseError::UnsupportedSection("Element section".into()));
+ // debug!("Found element section");
+ // validator.element_section(&reader)?;
+ // self.element_section = Some(reader);
+ }
+ DataSection(_reader) => {
+ return Err(ParseError::UnsupportedSection("Data section".into()));
+ // debug!("Found data section");
+ // validator.data_section(&reader)?;
+ // self.data_section = Some(reader);
+ }
+ CodeSectionStart { count, range, .. } => {
+ debug!("Found code section ({} functions)", count);
+ if self.code_section.is_some() {
+ return Err(ParseError::DuplicateSection("Code section".into()));
+ }
+
+ validator.code_section_start(count, &range)?;
+ self.code_section = Some(CodeSection::new());
+ }
+ CodeSectionEntry(function) => {
+ debug!("Found code section entry");
+ validator.code_section_entry(&function)?;
+
+ if let Some(code_section) = &mut self.code_section {
+ code_section.functions.push(function);
+ } else {
+ return Err(ParseError::EmptySection("Code section".into()));
+ }
+ }
+ ImportSection(_reader) => {
+ return Err(ParseError::UnsupportedSection("Import section".into()));
+
+ // debug!("Found import section");
+ // validator.import_section(&reader)?;
+ // self.import_section = Some(reader);
+ }
+ ExportSection(reader) => {
+ debug!("Found export section");
+ validator.export_section(&reader)?;
+ self.export_section = Some(reader);
+ }
+ End(offset) => {
+ debug!("Reached end of module");
+ if self.end_reached {
+ return Err(ParseError::DuplicateSection("End section".into()));
+ }
+
+ validator.end(offset)?;
+ self.end_reached = true;
+ }
+ UnknownSection { .. } | _ => {
+ return Err(ParseError::UnsupportedSection(format!("Unknown section")))
+ }
+ };
+
+ Ok(())
+ }
+}
+
+/// A WebAssembly code section
+/// Can be cloned to read functions multiple times
+#[derive(Debug, Clone)]
+pub struct CodeSection<'a> {
+ pub(crate) functions: Vec<FunctionBody<'a>>,
+}
+
+impl<'a> CodeSection<'a> {
+ fn new() -> Self {
+ Self {
+ functions: Vec::new(),
+ }
+ }
+}