summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/parser/build.rs4
-rw-r--r--crates/parser/src/conversion.rs51
-rw-r--r--crates/parser/src/macros.rs87
-rw-r--r--crates/parser/src/module.rs197
-rw-r--r--crates/parser/src/parallel.rs6
-rw-r--r--crates/parser/src/visit.rs18
6 files changed, 126 insertions, 237 deletions
diff --git a/crates/parser/build.rs b/crates/parser/build.rs
index d5c6dec..6b3f385 100644
--- a/crates/parser/build.rs
+++ b/crates/parser/build.rs
@@ -3,7 +3,7 @@ use std::env;
fn main() {
println!("cargo::rustc-check-cfg=cfg(parallel_parser)");
- if env::var("CARGO_FEATURE_PARALLEL").is_err() {
+ if env::var_os("CARGO_FEATURE_PARALLEL").is_none() {
return;
}
@@ -11,6 +11,6 @@ fn main() {
let os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
if !arch.starts_with("wasm") && os != "unknown" && os != "none" {
- println!("cargo:rustc-cfg=parallel_parser");
+ println!("cargo::rustc-cfg=parallel_parser");
}
}
diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs
index fea43ba..4561974 100644
--- a/crates/parser/src/conversion.rs
+++ b/crates/parser/src/conversion.rs
@@ -3,13 +3,10 @@ use alloc::sync::Arc;
use crate::{Result, module::FunctionCode, visit::process_operators_and_validate};
use alloc::{boxed::Box, format, string::ToString, vec::Vec};
use tinywasm_types::*;
-use wasmparser::{CompositeInnerType, FuncValidator, FuncValidatorAllocations, OperatorsReader, ValidatorResources};
-
-pub(crate) fn convert_module_elements<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Element<'a>>>>(
- elements: T,
-) -> Result<Vec<tinywasm_types::Element>> {
- elements.into_iter().map(|element| convert_module_element(element?)).collect::<Result<Vec<_>>>()
-}
+use wasmparser::{
+ CompositeInnerType, FuncValidator, FuncValidatorAllocations, OperatorsReader, OperatorsReaderAllocations,
+ ValidatorResources,
+};
pub(crate) fn convert_module_element(element: wasmparser::Element<'_>) -> Result<tinywasm_types::Element> {
let kind = match element.kind {
@@ -44,12 +41,6 @@ pub(crate) fn convert_module_element(element: wasmparser::Element<'_>) -> Result
}
}
-pub(crate) fn convert_module_data_sections<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Data<'a>>>>(
- data_sections: T,
-) -> Result<Vec<tinywasm_types::Data>> {
- data_sections.into_iter().map(|data| convert_module_data(data?)).collect::<Result<Vec<_>>>()
-}
-
pub(crate) fn convert_module_data(data: wasmparser::Data<'_>) -> Result<tinywasm_types::Data> {
Ok(tinywasm_types::Data {
data: data.data.to_vec().into_boxed_slice(),
@@ -64,12 +55,6 @@ pub(crate) fn convert_module_data(data: wasmparser::Data<'_>) -> Result<tinywasm
})
}
-pub(crate) fn convert_module_imports<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Import<'a>>>>(
- imports: T,
-) -> Result<Vec<Import>> {
- imports.into_iter().map(|import| convert_module_import(import?)).collect::<Result<Vec<_>>>()
-}
-
pub(crate) fn convert_module_import(import: wasmparser::Import<'_>) -> Result<Import> {
let kind = match import.ty {
wasmparser::TypeRef::Func(ty) => ImportKind::Function(ty),
@@ -100,12 +85,6 @@ pub(crate) fn convert_module_import(import: wasmparser::Import<'_>) -> Result<Im
Ok(Import { module: import.module.into(), name: import.name.into(), kind })
}
-pub(crate) fn convert_module_memories<T: IntoIterator<Item = wasmparser::Result<wasmparser::MemoryType>>>(
- memory_types: T,
-) -> Result<Vec<MemoryType>> {
- memory_types.into_iter().map(|memory| Ok(convert_module_memory(memory?))).collect::<Result<Vec<_>>>()
-}
-
pub(crate) fn convert_module_memory(memory: wasmparser::MemoryType) -> MemoryType {
MemoryType::new(
if memory.memory64 { MemoryArch::I64 } else { MemoryArch::I32 },
@@ -115,12 +94,6 @@ pub(crate) fn convert_module_memory(memory: wasmparser::MemoryType) -> MemoryTyp
)
}
-pub(crate) fn convert_module_tables<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Table<'a>>>>(
- table_types: T,
-) -> Result<Vec<TableType>> {
- table_types.into_iter().map(|table| convert_module_table(table?)).collect::<Result<Vec<_>>>()
-}
-
pub(crate) fn convert_module_table(table: wasmparser::Table<'_>) -> Result<TableType> {
let size_initial = table.ty.initial.try_into().map_err(|_| {
crate::ParseError::UnsupportedOperator(format!("Table size initial is too large: {}", table.ty.initial))
@@ -134,7 +107,7 @@ pub(crate) fn convert_module_table(table: wasmparser::Table<'_>) -> Result<Table
pub(crate) fn convert_module_globals(
globals: wasmparser::SectionLimited<'_, wasmparser::Global<'_>>,
-) -> Result<Vec<Global>> {
+) -> Result<Box<[Global]>> {
globals
.into_iter()
.map(|global| {
@@ -143,7 +116,7 @@ pub(crate) fn convert_module_globals(
let ops = global.init_expr.get_operators_reader();
Ok(Global { init: process_const_operators(ops)?, ty: GlobalType::new(ty, global.ty.mutable) })
})
- .collect::<Result<Vec<_>>>()
+ .collect::<Result<Box<_>>>()
}
pub(crate) fn convert_module_export(export: wasmparser::Export<'_>) -> Result<Export> {
@@ -163,7 +136,8 @@ pub(crate) fn convert_module_export(export: wasmparser::Export<'_>) -> Result<Ex
pub(crate) fn convert_module_code(
func: wasmparser::FunctionBody<'_>,
mut validator: FuncValidator<ValidatorResources>,
-) -> Result<(FunctionCode, FuncValidatorAllocations)> {
+ reader_allocs: OperatorsReaderAllocations,
+) -> Result<(FunctionCode, FuncValidatorAllocations, OperatorsReaderAllocations)> {
let locals_reader = func.get_locals_reader()?;
let count = locals_reader.get_count();
let pos = locals_reader.original_position();
@@ -199,8 +173,13 @@ pub(crate) fn convert_module_code(
}
}
- let (body, data, allocations) = process_operators_and_validate(validator, func, local_addr_map)?;
- Ok((FunctionCode { instructions: body, data, locals: local_counts, uses_local_memory: false }, allocations))
+ let (body, data, validator_allocs, reader_allocs) =
+ process_operators_and_validate(validator, func, local_addr_map, reader_allocs)?;
+ Ok((
+ FunctionCode { instructions: body, data, locals: local_counts, uses_local_memory: false },
+ validator_allocs,
+ reader_allocs,
+ ))
}
pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result<Arc<FuncType>> {
diff --git a/crates/parser/src/macros.rs b/crates/parser/src/macros.rs
index dded6d8..b21c1e8 100644
--- a/crates/parser/src/macros.rs
+++ b/crates/parser/src/macros.rs
@@ -1,94 +1,19 @@
pub(crate) mod visit {
macro_rules! validate_then_visit {
- ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
- $(validate_then_visit!(@@$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann)*));)*
- };
-
- // These special-case arms exist so we only clone wasmparser's non-Copy payloads
- (@@mvp BrTable { $arg:ident: $argty:ty } => $visit:ident ($($ann:tt)*)) => {
- fn $visit(&mut self, $arg: $argty) -> Self::Output {
- self.0.$visit($arg.clone());
- let validation = self.0.validator.visitor(self.0.position).$visit($arg);
- if let Err(e) = validation {
- cold_path();
- self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
- }
- }
- };
-
- (@@reference_types TypedSelectMulti { $arg:ident: $argty:ty } => $visit:ident ($($ann:tt)*)) => {
- fn $visit(&mut self, $arg: $argty) -> Self::Output {
- self.0.$visit($arg.clone());
- let validation = self.0.validator.visitor(self.0.position).$visit($arg);
- if let Err(e) = validation {
- cold_path();
- self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
- }
- }
- };
-
- (@@exceptions TryTable { $arg:ident: $argty:ty } => $visit:ident ($($ann:tt)*)) => {
- fn $visit(&mut self, $arg: $argty) -> Self::Output {
- self.0.$visit($arg.clone());
- let validation = self.0.validator.visitor(self.0.position).$visit($arg);
- if let Err(e) = validation {
- cold_path();
- self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
- }
- }
- };
-
- (@@stack_switching Resume { cont_type_index: $cont:ty, resume_table: $table:ty } => $visit:ident ($($ann:tt)*)) => {
- fn $visit(&mut self, cont_type_index: $cont, resume_table: $table) -> Self::Output {
- self.0.$visit(cont_type_index, resume_table.clone());
- let validation = self.0.validator.visitor(self.0.position).$visit(cont_type_index, resume_table);
- if let Err(e) = validation {
- cold_path();
- self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
- }
- }
- };
-
- (@@stack_switching ResumeThrow { cont_type_index: $cont:ty, tag_index: $tag:ty, resume_table: $table:ty } => $visit:ident ($($ann:tt)*)) => {
- fn $visit(&mut self, cont_type_index: $cont, tag_index: $tag, resume_table: $table) -> Self::Output {
- self.0.$visit(cont_type_index, tag_index, resume_table.clone());
- let validation = self.0.validator.visitor(self.0.position).$visit(cont_type_index, tag_index, resume_table);
- if let Err(e) = validation {
- cold_path();
- self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
- }
- }
- };
-
- (@@stack_switching ResumeThrowRef { cont_type_index: $cont:ty, resume_table: $table:ty } => $visit:ident ($($ann:tt)*)) => {
- fn $visit(&mut self, cont_type_index: $cont, resume_table: $table) -> Self::Output {
- self.0.$visit(cont_type_index, resume_table.clone());
- let validation = self.0.validator.visitor(self.0.position).$visit(cont_type_index, resume_table);
- if let Err(e) = validation {
- cold_path();
- self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
- }
- }
- };
-
- (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => {
+ ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {$(
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
- self.0.$visit($($($arg),*)?);
+ self.0.$visit($($($arg.clone()),*)?);
let validation = self.0.validator.visitor(self.0.position).$visit($($($arg),*)?);
if let Err(e) = validation {
cold_path();
self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
}
}
- };
+ )*};
}
macro_rules! validate_then_visit_simd {
- ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
- $(validate_then_visit_simd!(@@$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann)*));)*
- };
-
- (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => {
+ ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {$(
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
self.0.$visit($($($arg),*)?);
let validation = self.0.validator.simd_visitor(self.0.position).$visit($($($arg),*)?);
@@ -97,7 +22,7 @@ pub(crate) mod visit {
self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
}
}
- };
+ )*};
}
macro_rules! define_operand {
@@ -166,7 +91,7 @@ pub(crate) mod visit {
(@@tail_call $($rest:tt)* ) => {};
(@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => {
- fn $visit(&mut self $($(,_: $argty)*)?) {
+ fn $visit(&mut self $($(,_: $argty)*)?) -> Self::Output {
self.unsupported(stringify!($visit))
}
};
diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs
index 5f5e5e2..fab6258 100644
--- a/crates/parser/src/module.rs
+++ b/crates/parser/src/module.rs
@@ -1,11 +1,11 @@
use crate::log::debug;
-use crate::{ParseError, ParserOptions, Result, conversion, optimize};
+use crate::{ParseError, ParserOptions, Result, conversion::*, optimize};
use alloc::sync::Arc;
-use alloc::{format, string::ToString, vec::Vec};
+use alloc::{boxed::Box, format, string::ToString, vec::Vec};
use core::marker::PhantomData;
use core::ops::Range;
use tinywasm_types::*;
-use wasmparser::{FuncValidatorAllocations, Payload, Validator};
+use wasmparser::{FuncValidatorAllocations, OperatorsReaderAllocations, Payload, Validator};
pub(crate) struct FunctionCode {
pub instructions: Vec<Instruction>,
@@ -46,21 +46,23 @@ pub(crate) fn optimize_function_code(
#[derive(Default)]
pub(crate) struct ModuleReader<'a> {
func_validator_allocations: Option<FuncValidatorAllocations>,
+ operators_reader_allocations: Option<OperatorsReaderAllocations>,
+
has_code_section: bool,
marker: PhantomData<&'a [u8]>,
pub(crate) version: Option<u16>,
pub(crate) start_func: Option<u32>,
- pub(crate) func_types: Vec<Arc<FuncType>>,
- pub(crate) code_type_addrs: Vec<u32>,
- pub(crate) exports: Vec<Export>,
+ pub(crate) func_types: Arc<[Arc<FuncType>]>,
+ pub(crate) code_type_addrs: Box<[u32]>,
+ pub(crate) exports: Arc<[Export]>,
pub(crate) code: Vec<FunctionCode>,
- pub(crate) globals: Vec<Global>,
- pub(crate) table_types: Vec<TableType>,
- pub(crate) memory_types: Vec<MemoryType>,
- pub(crate) imports: Vec<Import>,
- pub(crate) data: Vec<Data>,
- pub(crate) elements: Vec<Element>,
+ pub(crate) globals: Box<[Global]>,
+ pub(crate) table_types: Box<[TableType]>,
+ pub(crate) memory_types: Box<[MemoryType]>,
+ pub(crate) imports: Box<[Import]>,
+ pub(crate) data: Box<[Data]>,
+ pub(crate) elements: Box<[Element]>,
pub(crate) end_reached: bool,
#[cfg(parallel_parser)]
@@ -75,6 +77,14 @@ impl<'a> ModuleReader<'a> {
}
pub(crate) fn process_payload(&mut self, payload: Payload<'_>, validator: &mut Validator) -> Result<()> {
+ fn check_section(section: &str, duplicate: bool) -> Result<()> {
+ debug!("found {section} section");
+ if duplicate {
+ return Err(ParseError::DuplicateSection(format!("{section} section")));
+ }
+ Ok(())
+ }
+
match payload {
Payload::Version { num, encoding, range } => {
validator.version(num, encoding, &range)?;
@@ -84,99 +94,65 @@ impl<'a> ModuleReader<'a> {
}
}
Payload::StartSection { func, range } => {
- if self.start_func.is_some() {
- return Err(ParseError::DuplicateSection("Start section".into()));
- }
-
- debug!("Found start section");
+ check_section("start", self.start_func.is_some())?;
validator.start_section(func, &range)?;
self.start_func = Some(func);
}
Payload::TypeSection(reader) => {
- if !self.func_types.is_empty() {
- return Err(ParseError::DuplicateSection("Type section".into()));
- }
-
- debug!("Found type section");
+ check_section("type", !self.func_types.is_empty())?;
validator.type_section(&reader)?;
- self.func_types =
- reader.into_iter().map(|t| conversion::convert_module_type(t?)).collect::<Result<Vec<_>>>()?;
+ self.func_types = reader.into_iter().map(|t| convert_module_type(t?)).collect::<Result<_>>()?;
}
Payload::GlobalSection(reader) => {
- if !self.globals.is_empty() {
- return Err(ParseError::DuplicateSection("Global section".into()));
- }
-
- debug!("Found global section");
+ check_section("global", !self.globals.is_empty())?;
validator.global_section(&reader)?;
- self.globals = conversion::convert_module_globals(reader)?;
+ self.globals = convert_module_globals(reader)?;
}
Payload::TableSection(reader) => {
- if !self.table_types.is_empty() {
- return Err(ParseError::DuplicateSection("Table section".into()));
- }
-
- debug!("Found table section");
+ check_section("table", !self.table_types.is_empty())?;
validator.table_section(&reader)?;
- self.table_types = conversion::convert_module_tables(reader)?;
+ self.table_types =
+ reader.into_iter().map(|table| convert_module_table(table?)).collect::<Result<_>>()?;
}
Payload::MemorySection(reader) => {
- if !self.memory_types.is_empty() {
- return Err(ParseError::DuplicateSection("Memory section".into()));
- }
-
- debug!("Found memory section");
+ check_section("memory", !self.memory_types.is_empty())?;
validator.memory_section(&reader)?;
- self.memory_types = conversion::convert_module_memories(reader)?;
+ self.memory_types =
+ reader.into_iter().map(|memory| Ok(convert_module_memory(memory?))).collect::<Result<_>>()?;
}
Payload::ElementSection(reader) => {
debug!("Found element section");
validator.element_section(&reader)?;
- self.elements = conversion::convert_module_elements(reader)?;
+ self.elements =
+ reader.into_iter().map(|element| convert_module_element(element?)).collect::<Result<_>>()?;
}
Payload::DataSection(reader) => {
- if !self.data.is_empty() {
- return Err(ParseError::DuplicateSection("Data section".into()));
- }
-
- debug!("Found data section");
+ check_section("data", !self.data.is_empty())?;
validator.data_section(&reader)?;
- self.data = conversion::convert_module_data_sections(reader)?;
+ self.data = reader.into_iter().map(|data| convert_module_data(data?)).collect::<Result<_>>()?;
}
Payload::DataCountSection { count, range } => {
debug!("Found data count section");
if !self.data.is_empty() {
- return Err(ParseError::DuplicateSection("Data count section".into()));
+ return Err(ParseError::UnsupportedSection("Data count section after data section".into()));
}
validator.data_count_section(count, &range)?;
}
Payload::FunctionSection(reader) => {
- if !self.code_type_addrs.is_empty() {
- return Err(ParseError::DuplicateSection("Function section".into()));
- }
-
- debug!("Found function section");
+ check_section("function", !self.code_type_addrs.is_empty())?;
validator.function_section(&reader)?;
- self.code_type_addrs = reader.into_iter().map(|f| Ok(f?)).collect::<Result<Vec<_>>>()?;
+ self.code_type_addrs = reader.into_iter().map(|f| Ok(f?)).collect::<Result<_>>()?;
}
Payload::ImportSection(reader) => {
- if !self.imports.is_empty() {
- return Err(ParseError::DuplicateSection("Import section".into()));
- }
-
- debug!("Found import section");
+ check_section("import", !self.imports.is_empty())?;
validator.import_section(&reader)?;
- self.imports = conversion::convert_module_imports(reader.into_imports())?;
+ self.imports =
+ reader.into_imports().map(|import| convert_module_import(import?)).collect::<Result<_>>()?;
}
Payload::ExportSection(reader) => {
- if !self.exports.is_empty() {
- return Err(ParseError::DuplicateSection("Export section".into()));
- }
-
- debug!("Found export section");
+ check_section("export", !self.exports.is_empty())?;
validator.export_section(&reader)?;
- self.exports =
- reader.into_iter().map(|e| conversion::convert_module_export(e?)).collect::<Result<Vec<_>>>()?;
+ self.exports = reader.into_iter().map(|e| convert_module_export(e?)).collect::<Result<_>>()?;
}
Payload::End(offset) => {
debug!("Reached end of module");
@@ -192,7 +168,7 @@ impl<'a> ModuleReader<'a> {
debug!("Skipping custom section: {:?}", _reader.name());
}
Payload::CodeSectionStart { .. } | Payload::CodeSectionEntry(_) => {
- return Err(ParseError::Other("code section payload handled separately".into()));
+ unreachable!("code section payload handled separately")
}
Payload::UnknownSection { .. } => return Err(ParseError::UnsupportedSection("Unknown section".into())),
section => return Err(ParseError::UnsupportedSection(format!("Unsupported section: {section:?}"))),
@@ -242,20 +218,26 @@ impl<'a> ModuleReader<'a> {
options: &ParserOptions,
) -> Result<()> {
debug!("Found code section entry");
- let ordinal = self.code.len();
+
+ let func_validator_allocs = self.func_validator_allocations.take().unwrap_or_default();
+ let operators_reader_allocs = self.operators_reader_allocations.take().unwrap_or_default();
+
let func_to_validate = validator.code_section_entry(&function)?;
- let func_validator =
- func_to_validate.into_validator(self.func_validator_allocations.take().unwrap_or_default());
- let (code, allocations) = conversion::convert_module_code(function, func_validator)?;
- let code = optimize_function_code(
+ let func_validator = func_to_validate.into_validator(func_validator_allocs);
+
+ let (code, func_validator_allocs, operators_reader_allocs) =
+ convert_module_code(function, func_validator, operators_reader_allocs)?;
+
+ self.code.push(optimize_function_code(
code,
options,
- self.function_results(ordinal),
- (imported_func_count(&self.imports) + ordinal) as u32,
+ self.function_results(self.code.len()),
+ (imported_func_count(&self.imports) + self.code.len()) as u32,
imported_memory_count(&self.imports),
- );
- self.code.push(code);
- self.func_validator_allocations = Some(allocations);
+ ));
+
+ self.func_validator_allocations = Some(func_validator_allocs);
+ self.operators_reader_allocations = Some(operators_reader_allocs);
Ok(())
}
@@ -376,50 +358,51 @@ impl<'a> ModuleReader<'a> {
LocalMemoryAllocation::Skip
};
- let mut funcs = Vec::with_capacity(self.code.len());
- let mut func_type_idxs = self
+ let func_type_idxs = self
.imports
.iter()
.filter_map(|import| match import.kind {
ImportKind::Function(type_idx) => Some(type_idx),
_ => None,
})
- .collect::<Vec<_>>();
- func_type_idxs.extend(self.code_type_addrs.iter().copied());
+ .chain(self.code_type_addrs.iter().copied())
+ .collect();
- for (code, ty_idx) in self.code.into_iter().zip(self.code_type_addrs) {
- let ty = self.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone();
- let params = ValueCounts::from_iter(ty.params());
- let results = ValueCounts::from_iter(ty.results());
- if code.uses_local_memory {
- local_memory_allocation = LocalMemoryAllocation::Eager;
- }
+ let funcs = self
+ .code
+ .into_iter()
+ .zip(self.code_type_addrs)
+ .map(|(code, ty_idx)| {
+ let ty = self.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone();
+ let params = ValueCounts::from_iter(ty.params());
+ let results = ValueCounts::from_iter(ty.results());
+ if code.uses_local_memory {
+ local_memory_allocation = LocalMemoryAllocation::Eager;
+ }
- funcs.push(
- WasmFunction {
+ Arc::new(WasmFunction {
instructions: code.instructions.into(),
data: code.data,
locals: code.locals,
params,
results,
ty,
- }
- .into(),
- );
- }
+ })
+ })
+ .collect();
Ok(ModuleInner {
- funcs: funcs.into(),
- func_types: self.func_types.into(),
- func_type_idxs: func_type_idxs.into(),
- globals: self.globals.into(),
- table_types: self.table_types.into(),
- imports: self.imports.into(),
+ funcs,
+ func_types: self.func_types,
+ func_type_idxs,
+ globals: self.globals,
+ table_types: self.table_types,
+ imports: self.imports,
start_func: self.start_func,
- data: self.data.into(),
- exports: self.exports.into(),
- elements: self.elements.into(),
- memory_types: self.memory_types.into(),
+ data: self.data,
+ exports: self.exports,
+ elements: self.elements,
+ memory_types: self.memory_types,
local_memory_allocation,
}
.into())
diff --git a/crates/parser/src/parallel.rs b/crates/parser/src/parallel.rs
index 778e4ad..4400053 100644
--- a/crates/parser/src/parallel.rs
+++ b/crates/parser/src/parallel.rs
@@ -66,12 +66,12 @@ fn process_function_job(
imported_memory_count: u32,
) -> Result<(usize, FunctionCode)> {
let validator = job.func_to_validate.into_validator(FuncValidatorAllocations::default());
- let (code, _allocations) = match job.body {
- FunctionBodyInput::Borrowed(func) => conversion::convert_module_code(func, validator)?,
+ let (code, _, _) = match job.body {
+ FunctionBodyInput::Borrowed(func) => conversion::convert_module_code(func, validator, Default::default())?,
FunctionBodyInput::Owned(body) => {
let reader = wasmparser::BinaryReader::new(&body.section_bytes[body.body_range], body.body_offset);
let func = wasmparser::FunctionBody::new(reader);
- conversion::convert_module_code(func, validator)?
+ conversion::convert_module_code(func, validator, Default::default())?
}
};
diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs
index d1612ed..5fddad9 100644
--- a/crates/parser/src/visit.rs
+++ b/crates/parser/src/visit.rs
@@ -5,8 +5,8 @@ use alloc::string::ToString;
use alloc::vec::Vec;
use tinywasm_types::{Instruction, MemoryArg, WasmFunctionData};
use wasmparser::{
- FrameKind, FuncValidator, FuncValidatorAllocations, FunctionBody, VisitOperator, VisitSimdOperator,
- WasmModuleResources,
+ FrameKind, FuncValidator, FuncValidatorAllocations, FunctionBody, OperatorsReader, OperatorsReaderAllocations,
+ VisitOperator, VisitSimdOperator, WasmModuleResources,
};
#[derive(Debug, Clone, Copy)]
@@ -51,7 +51,6 @@ impl FunctionDataBuilder {
}
}
}
-
struct ValidateThenVisit<'a, R: WasmModuleResources>(&'a mut FunctionBuilder<R>);
fn operand_size(ty: wasmparser::ValType) -> OperandSize {
@@ -75,12 +74,14 @@ impl<R: WasmModuleResources> VisitSimdOperator<'_> for ValidateThenVisit<'_, R>
wasmparser::for_each_visit_simd_operator!(validate_then_visit_simd);
}
-pub(crate) fn process_operators_and_validate<R: WasmModuleResources>(
- validator: FuncValidator<R>,
+pub(crate) fn process_operators_and_validate(
+ validator: FuncValidator<impl WasmModuleResources>,
body: FunctionBody<'_>,
local_addr_map: Vec<u16>,
-) -> Result<(Vec<Instruction>, WasmFunctionData, FuncValidatorAllocations)> {
- let mut reader = body.get_operators_reader()?;
+ allocs: OperatorsReaderAllocations,
+) -> Result<(Vec<Instruction>, WasmFunctionData, FuncValidatorAllocations, OperatorsReaderAllocations)> {
+ let reader = body.get_binary_reader_for_operators()?;
+ let mut reader = OperatorsReader::new_with_allocs(reader, allocs);
let mut builder = FunctionBuilder::new(validator, local_addr_map);
while !reader.eof() {
@@ -92,11 +93,12 @@ pub(crate) fn process_operators_and_validate<R: WasmModuleResources>(
}
reader.finish()?;
+
if let Some(error) = builder.error {
return Err(error);
}
- Ok((builder.instructions, builder.data.finish(), builder.validator.into_allocations()))
+ Ok((builder.instructions, builder.data.finish(), builder.validator.into_allocations(), reader.into_allocations()))
}
pub(crate) struct FunctionBuilder<R> {