summaryrefslogtreecommitdiff
path: root/crates/parser/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/parser/src/lib.rs')
-rw-r--r--crates/parser/src/lib.rs92
1 files changed, 72 insertions, 20 deletions
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs
index d2b6d9c..5b17fb8 100644
--- a/crates/parser/src/lib.rs
+++ b/crates/parser/src/lib.rs
@@ -9,49 +9,101 @@ extern crate std;
mod conversion;
mod error;
mod module;
+use alloc::vec::Vec;
pub use error::*;
use module::ModuleReader;
-use tinywasm_types::TinyWasmModule;
+use tinywasm_types::{Function, TinyWasmModule};
+use wasmparser::Validator;
pub struct Parser {}
impl Parser {
pub fn parse_module_bytes(wasm: &[u8]) -> Result<TinyWasmModule> {
- let reader = ModuleReader::new();
- reader.try_into()
- }
+ let mut validator = Validator::new();
+ let mut reader = ModuleReader::new();
+
+ for payload in wasmparser::Parser::new(0).parse_all(wasm) {
+ reader.process_payload(payload?, &mut validator)?;
+ }
+
+ if !reader.end_reached {
+ return Err(ParseError::EndNotReached);
+ }
- pub fn parse_module_file(file_name: &str) -> Result<TinyWasmModule> {
- let reader = ModuleReader::new();
reader.try_into()
}
#[cfg(feature = "std")]
- pub fn parse_module_stream(stream: impl std::io::Read) -> Result<TinyWasmModule> {
- let reader = ModuleReader::new();
- reader.try_into()
- }
+ pub fn parse_module_file(path: impl AsRef<crate::std::path::Path>) -> Result<TinyWasmModule> {
+ use alloc::format;
+ let f = crate::std::fs::File::open("log.txt").map_err(|e| {
+ ParseError::Other(format!("Error opening file {:?}: {}", path.as_ref(), e))
+ })?;
- pub fn read_module_bytes(bytes: &[u8]) -> Result<TinyWasmModule> {
- unimplemented!()
- }
- pub fn read_module_file(file_name: &str) -> Result<TinyWasmModule> {
- unimplemented!()
+ let mut reader = crate::std::io::BufReader::new(f);
+ Self::parse_module_stream(&mut reader)
}
+
#[cfg(feature = "std")]
- pub fn read_module_stream(stream: impl std::io::Read) -> Result<TinyWasmModule> {
- unimplemented!()
+ pub fn parse_module_stream(mut stream: impl std::io::Read) -> Result<TinyWasmModule> {
+ use alloc::format;
+
+ let mut validator = Validator::new();
+ let mut reader = ModuleReader::new();
+ let mut buffer = Vec::new();
+ let mut parser = wasmparser::Parser::new(0);
+ let mut eof = false;
+
+ loop {
+ match parser.parse(&buffer, eof)? {
+ wasmparser::Chunk::NeedMoreData(hint) => {
+ let len = buffer.len();
+ buffer.extend((0..hint).map(|_| 0u8));
+ let read_bytes = stream.read(&mut buffer[len..]).map_err(|e| {
+ ParseError::Other(format!("Error reading from stream: {}", e))
+ })?;
+ buffer.truncate(len + read_bytes);
+ eof = read_bytes == 0;
+ }
+ wasmparser::Chunk::Parsed { consumed, payload } => {
+ reader.process_payload(payload, &mut validator)?;
+ buffer.drain(..consumed);
+ if eof || reader.end_reached {
+ return reader.try_into();
+ }
+ }
+ };
+ }
}
}
-impl TryFrom<ModuleReader<'_>> for TinyWasmModule {
+impl TryFrom<ModuleReader> for TinyWasmModule {
type Error = ParseError;
- fn try_from(reader: ModuleReader<'_>) -> Result<Self> {
+ fn try_from(reader: ModuleReader) -> Result<Self> {
if !reader.end_reached {
return Err(ParseError::EndNotReached);
}
- unimplemented!()
+ let func_types = reader.function_section;
+ let funcs = reader
+ .code_section
+ .into_iter()
+ .zip(func_types)
+ .map(|(f, ty)| Function {
+ body: f.body,
+ locals: f.locals,
+ ty,
+ })
+ .collect::<Vec<_>>()
+ .into_boxed_slice();
+
+ Ok(TinyWasmModule {
+ version: reader.version,
+ start_func: reader.start_func,
+ types: reader.type_section.into_boxed_slice(),
+ funcs,
+ exports: reader.export_section.into_boxed_slice(),
+ })
}
}