summaryrefslogtreecommitdiff
path: root/crates/core/src
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2023-11-28 20:06:41 +0100
committerHenry Gressmann <mail@henrygressmann.de>2023-11-28 20:06:41 +0100
commitfe76d91f33b2441de87597ae5885ea9005f35b1c (patch)
treebda08242444d91dbf55e5e96233ae826c5e4e376 /crates/core/src
parent1256c4248d2a3a9f73c2a14d997a337ba0eee2b4 (diff)
refactor: seperate cli crate
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates/core/src')
-rw-r--r--crates/core/src/bin.rs9
-rw-r--r--crates/core/src/error.rs28
-rw-r--r--crates/core/src/lib.rs185
-rw-r--r--crates/core/src/module.rs155
-rw-r--r--crates/core/src/std.rs18
5 files changed, 221 insertions, 174 deletions
diff --git a/crates/core/src/bin.rs b/crates/core/src/bin.rs
deleted file mode 100644
index c4257e8..0000000
--- a/crates/core/src/bin.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-use wasmcore::{self, Module};
-
-pub static WASM: &'static [u8] = include_bytes!("../helloworld.wasm");
-
-fn main() {
- let module = Module::new(WASM);
-
- println!("{:#?}", module);
-}
diff --git a/crates/core/src/error.rs b/crates/core/src/error.rs
new file mode 100644
index 0000000..b9c93c4
--- /dev/null
+++ b/crates/core/src/error.rs
@@ -0,0 +1,28 @@
+use alloc::string::{String, ToString};
+use thiserror::Error;
+
+#[derive(Debug, Error)]
+pub enum Error {
+ #[error("error parsing module")]
+ ParseError { message: String, offset: usize },
+
+ #[error("unknown error: {0}")]
+ Other(String),
+}
+
+impl Error {
+ pub fn other<T>(message: &str) -> Result<T, Self> {
+ Err(Self::Other(message.to_string()))
+ }
+}
+
+impl From<wasmparser::BinaryReaderError> for Error {
+ fn from(value: wasmparser::BinaryReaderError) -> Self {
+ Self::ParseError {
+ message: value.message().to_string(),
+ offset: value.offset(),
+ }
+ }
+}
+
+pub type Result<T, E = Error> = crate::std::result::Result<T, E>;
diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs
index ee8a3be..3d572a2 100644
--- a/crates/core/src/lib.rs
+++ b/crates/core/src/lib.rs
@@ -1,178 +1,33 @@
#![no_std]
#![forbid(unsafe_code)]
+#![cfg_attr(not(feature = "std"), feature(error_in_core))]
-#[cfg(feature = "std")]
-extern crate std;
-use std::println;
-
+mod std;
extern crate alloc;
-use alloc::vec::Vec;
-
-use wasmparser::{
- DataSectionReader, ElementSectionReader, ExportSectionReader, FunctionBody,
- FunctionSectionReader, GlobalSectionReader, ImportSectionReader, MemorySectionReader, Payload,
- TableSectionReader, TypeSectionReader, Validator,
-};
-mod instructions;
-
-struct Store {}
-
-pub struct Module<'a> {
- reader: ModuleReader<'a>,
-}
-
-impl<'a> core::fmt::Debug for Module<'a> {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- f.debug_struct("Module")
- .field("version", &self.reader.version)
- .field("type_section", &self.reader.type_section)
- .field("function_section", &self.reader.function_section)
- .field("table_section", &self.reader.table_section)
- .field("memory_section", &self.reader.memory_section)
- .field("global_section", &self.reader.global_section)
- .field("element_section", &self.reader.element_section)
- .field("data_section", &self.reader.data_section)
- .field("code_section", &self.reader.code_section)
- .field("import_section", &self.reader.import_section)
- .field("export_section", &self.reader.export_section)
- .finish()
- }
-}
-
-#[derive(Default)]
-pub struct ModuleReader<'a> {
- pub version: Option<u16>,
- pub type_section: Option<TypeSectionReader<'a>>,
- pub function_section: Option<FunctionSectionReader<'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 code_section: Option<CodeSection<'a>>,
- pub import_section: Option<ImportSectionReader<'a>>,
- pub export_section: Option<ExportSectionReader<'a>>,
-}
-
-#[derive(Debug)]
-pub struct CodeSection<'a> {
- pub(crate) functions: Vec<FunctionBody<'a>>,
-}
-impl<'a> CodeSection<'a> {
- fn new() -> Self {
- Self {
- functions: Vec::new(),
- }
- }
-}
-
-impl<'a> Module<'a> {
- pub fn new(wasm: &'a [u8]) -> Result<Module, ()> {
- let mut validator = Validator::new();
- let mut reader = ModuleReader::new();
-
- for payload in wasmparser::Parser::new(0).parse_all(wasm) {
- reader.process_payload(payload.unwrap(), &mut validator)?;
- }
-
- Ok(Self { reader })
- }
-}
-
-impl<'a> ModuleReader<'a> {
- pub fn new() -> Self {
- Self::default()
- }
+mod error;
+pub mod instructions;
+pub mod module;
+pub use error::*;
+pub use module::Module;
- pub fn process_payload(
- &mut self,
- payload: Payload<'a>,
- validator: &mut Validator,
- ) -> Result<bool, ()> {
- use wasmparser::Payload::*;
- match payload {
- Version {
- num,
- encoding,
- range,
- } => {
- validator.version(num, encoding, &range).map_err(|_| ())?;
- self.version = Some(num);
- match encoding {
- wasmparser::Encoding::Module => {}
- wasmparser::Encoding::Component => return Err(()),
- }
- }
- TypeSection(reader) => {
- validator.type_section(&reader).map_err(|_| ())?;
- self.type_section = Some(reader);
- }
- FunctionSection(reader) => {
- validator.function_section(&reader).map_err(|_| ())?;
- self.function_section = Some(reader);
- }
- TableSection(reader) => {
- validator.table_section(&reader).map_err(|_| ())?;
- self.table_section = Some(reader);
- }
- MemorySection(reader) => {
- validator.memory_section(&reader).map_err(|_| ())?;
- self.memory_section = Some(reader);
- }
- GlobalSection(reader) => {
- validator.global_section(&reader).map_err(|_| ())?;
- self.global_section = Some(reader);
- }
- ElementSection(reader) => {
- validator.element_section(&reader).map_err(|_| ())?;
- self.element_section = Some(reader);
- }
- DataSection(reader) => {
- validator.data_section(&reader).map_err(|_| ())?;
- self.data_section = Some(reader);
- }
- CodeSectionStart { count, range, .. } => {
- validator
- .code_section_start(count, &range)
- .map_err(|_| ())?;
+pub struct Store {}
- self.code_section = Some(CodeSection::new());
- }
- CodeSectionEntry(function) => {
- validator.code_section_entry(&function).map_err(|_| ())?;
+pub struct Instance {}
- if let Some(code_section) = &mut self.code_section {
- code_section.functions.push(function);
- } else {
- return Err(());
- }
- }
- ImportSection(reader) => {
- validator.import_section(&reader).map_err(|_| ())?;
- self.import_section = Some(reader);
- }
- ExportSection(reader) => {
- validator.export_section(&reader).map_err(|_| ())?;
- self.export_section = Some(reader);
- }
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::{error::Result, Module};
+ use std::dbg;
- End(offset) => {
- validator.end(offset).map_err(|_| ())?;
- return Ok(true);
- }
- x => println!("Unknown payload: {:?}", x),
- };
+ #[test]
+ fn it_works() -> Result<()> {
+ let wasm = include_bytes!("../../../examples/wasm/helloworld.wasm");
+ let module = Module::new(wasm)?;
- Ok(false)
- }
-}
-struct Instance {}
+ dbg!(module);
-pub fn parse(wasm: &[u8]) -> Result<Payload<'_>, ()> {
- for payload in wasmparser::Parser::new(0).parse_all(wasm) {
- return Ok(payload.unwrap());
+ Ok(())
}
-
- return Err(());
}
diff --git a/crates/core/src/module.rs b/crates/core/src/module.rs
new file mode 100644
index 0000000..1ed42c4
--- /dev/null
+++ b/crates/core/src/module.rs
@@ -0,0 +1,155 @@
+use crate::error::{Error, Result};
+use alloc::{format, vec::Vec};
+use tracing::error;
+use wasmparser::*;
+
+pub struct Module<'a> {
+ reader: ModuleReader<'a>,
+}
+
+impl<'a> core::fmt::Debug for Module<'a> {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ f.debug_struct("Module")
+ .field("version", &self.reader.version)
+ .field("type_section", &self.reader.type_section)
+ .field("function_section", &self.reader.function_section)
+ .field("table_section", &self.reader.table_section)
+ .field("memory_section", &self.reader.memory_section)
+ .field("global_section", &self.reader.global_section)
+ .field("element_section", &self.reader.element_section)
+ .field("data_section", &self.reader.data_section)
+ .field("code_section", &self.reader.code_section)
+ .field("import_section", &self.reader.import_section)
+ .field("export_section", &self.reader.export_section)
+ .finish()
+ }
+}
+
+#[derive(Default)]
+pub struct ModuleReader<'a> {
+ pub version: Option<u16>,
+ pub type_section: Option<TypeSectionReader<'a>>,
+ pub function_section: Option<FunctionSectionReader<'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 code_section: Option<CodeSection<'a>>,
+ pub import_section: Option<ImportSectionReader<'a>>,
+ pub export_section: Option<ExportSectionReader<'a>>,
+}
+
+#[derive(Debug)]
+pub struct CodeSection<'a> {
+ pub(crate) functions: Vec<FunctionBody<'a>>,
+}
+
+impl<'a> CodeSection<'a> {
+ fn new() -> Self {
+ Self {
+ functions: Vec::new(),
+ }
+ }
+}
+
+impl<'a> Module<'a> {
+ pub fn new(wasm: &'a [u8]) -> Result<Self> {
+ 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)?;
+ }
+
+ Ok(Self { reader })
+ }
+}
+
+impl<'a> ModuleReader<'a> {
+ pub fn new() -> Self {
+ 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 Error::other("Component"),
+ }
+ }
+ TypeSection(reader) => {
+ validator.type_section(&reader)?;
+ self.type_section = Some(reader);
+ }
+ FunctionSection(reader) => {
+ validator.function_section(&reader)?;
+ self.function_section = Some(reader);
+ }
+ TableSection(reader) => {
+ validator.table_section(&reader)?;
+ self.table_section = Some(reader);
+ }
+ MemorySection(reader) => {
+ validator.memory_section(&reader)?;
+ self.memory_section = Some(reader);
+ }
+ GlobalSection(reader) => {
+ validator.global_section(&reader)?;
+ self.global_section = Some(reader);
+ }
+ ElementSection(reader) => {
+ validator.element_section(&reader)?;
+ self.element_section = Some(reader);
+ }
+ DataSection(reader) => {
+ validator.data_section(&reader)?;
+ self.data_section = Some(reader);
+ }
+ CodeSectionStart { count, range, .. } => {
+ validator.code_section_start(count, &range)?;
+
+ self.code_section = Some(CodeSection::new());
+ }
+ CodeSectionEntry(function) => {
+ validator.code_section_entry(&function)?;
+
+ if let Some(code_section) = &mut self.code_section {
+ code_section.functions.push(function);
+ } else {
+ return Error::other("Empty code section");
+ }
+ }
+ ImportSection(reader) => {
+ validator.import_section(&reader)?;
+ self.import_section = Some(reader);
+ }
+ ExportSection(reader) => {
+ validator.export_section(&reader)?;
+ self.export_section = Some(reader);
+ }
+
+ End(offset) => {
+ validator.end(offset)?;
+ return Ok(());
+ }
+ x => Error::other(&format!("Unknown payload: {:?}", x))?,
+ };
+
+ error!("Missing end");
+
+ Ok(())
+ }
+}
diff --git a/crates/core/src/std.rs b/crates/core/src/std.rs
new file mode 100644
index 0000000..6c112f1
--- /dev/null
+++ b/crates/core/src/std.rs
@@ -0,0 +1,18 @@
+pub use core::*;
+
+#[cfg(feature = "std")]
+extern crate std;
+
+#[cfg(feature = "std")]
+pub use std::*;
+
+pub mod error {
+ #[cfg(feature = "std")]
+ extern crate std;
+
+ #[cfg(feature = "std")]
+ pub use std::error::Error;
+
+ #[cfg(not(feature = "std"))]
+ pub use core::error::Error;
+}