Skip to content

Commit c0b356b

Browse files
chore: simplify parser & reduce allocations
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent 2aa1f31 commit c0b356b

6 files changed

Lines changed: 127 additions & 238 deletions

File tree

crates/parser/build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ use std::env;
33
fn main() {
44
println!("cargo::rustc-check-cfg=cfg(parallel_parser)");
55

6-
if env::var("CARGO_FEATURE_PARALLEL").is_err() {
6+
if env::var_os("CARGO_FEATURE_PARALLEL").is_none() {
77
return;
88
}
99

1010
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
1111
let os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
1212

1313
if !arch.starts_with("wasm") && os != "unknown" && os != "none" {
14-
println!("cargo:rustc-cfg=parallel_parser");
14+
println!("cargo::rustc-cfg=parallel_parser");
1515
}
1616
}

crates/parser/src/conversion.rs

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,10 @@ use alloc::sync::Arc;
33
use crate::{Result, module::FunctionCode, visit::process_operators_and_validate};
44
use alloc::{boxed::Box, format, string::ToString, vec::Vec};
55
use tinywasm_types::*;
6-
use wasmparser::{CompositeInnerType, FuncValidator, FuncValidatorAllocations, OperatorsReader, ValidatorResources};
7-
8-
pub(crate) fn convert_module_elements<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Element<'a>>>>(
9-
elements: T,
10-
) -> Result<Vec<tinywasm_types::Element>> {
11-
elements.into_iter().map(|element| convert_module_element(element?)).collect::<Result<Vec<_>>>()
12-
}
6+
use wasmparser::{
7+
CompositeInnerType, FuncValidator, FuncValidatorAllocations, OperatorsReader, OperatorsReaderAllocations,
8+
ValidatorResources,
9+
};
1310

1411
pub(crate) fn convert_module_element(element: wasmparser::Element<'_>) -> Result<tinywasm_types::Element> {
1512
let kind = match element.kind {
@@ -44,12 +41,6 @@ pub(crate) fn convert_module_element(element: wasmparser::Element<'_>) -> Result
4441
}
4542
}
4643

47-
pub(crate) fn convert_module_data_sections<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Data<'a>>>>(
48-
data_sections: T,
49-
) -> Result<Vec<tinywasm_types::Data>> {
50-
data_sections.into_iter().map(|data| convert_module_data(data?)).collect::<Result<Vec<_>>>()
51-
}
52-
5344
pub(crate) fn convert_module_data(data: wasmparser::Data<'_>) -> Result<tinywasm_types::Data> {
5445
Ok(tinywasm_types::Data {
5546
data: data.data.to_vec().into_boxed_slice(),
@@ -64,12 +55,6 @@ pub(crate) fn convert_module_data(data: wasmparser::Data<'_>) -> Result<tinywasm
6455
})
6556
}
6657

67-
pub(crate) fn convert_module_imports<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Import<'a>>>>(
68-
imports: T,
69-
) -> Result<Vec<Import>> {
70-
imports.into_iter().map(|import| convert_module_import(import?)).collect::<Result<Vec<_>>>()
71-
}
72-
7358
pub(crate) fn convert_module_import(import: wasmparser::Import<'_>) -> Result<Import> {
7459
let kind = match import.ty {
7560
wasmparser::TypeRef::Func(ty) => ImportKind::Function(ty),
@@ -100,12 +85,6 @@ pub(crate) fn convert_module_import(import: wasmparser::Import<'_>) -> Result<Im
10085
Ok(Import { module: import.module.into(), name: import.name.into(), kind })
10186
}
10287

103-
pub(crate) fn convert_module_memories<T: IntoIterator<Item = wasmparser::Result<wasmparser::MemoryType>>>(
104-
memory_types: T,
105-
) -> Result<Vec<MemoryType>> {
106-
memory_types.into_iter().map(|memory| Ok(convert_module_memory(memory?))).collect::<Result<Vec<_>>>()
107-
}
108-
10988
pub(crate) fn convert_module_memory(memory: wasmparser::MemoryType) -> MemoryType {
11089
MemoryType::new(
11190
if memory.memory64 { MemoryArch::I64 } else { MemoryArch::I32 },
@@ -115,12 +94,6 @@ pub(crate) fn convert_module_memory(memory: wasmparser::MemoryType) -> MemoryTyp
11594
)
11695
}
11796

118-
pub(crate) fn convert_module_tables<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Table<'a>>>>(
119-
table_types: T,
120-
) -> Result<Vec<TableType>> {
121-
table_types.into_iter().map(|table| convert_module_table(table?)).collect::<Result<Vec<_>>>()
122-
}
123-
12497
pub(crate) fn convert_module_table(table: wasmparser::Table<'_>) -> Result<TableType> {
12598
let size_initial = table.ty.initial.try_into().map_err(|_| {
12699
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
134107

135108
pub(crate) fn convert_module_globals(
136109
globals: wasmparser::SectionLimited<'_, wasmparser::Global<'_>>,
137-
) -> Result<Vec<Global>> {
110+
) -> Result<Box<[Global]>> {
138111
globals
139112
.into_iter()
140113
.map(|global| {
@@ -143,7 +116,7 @@ pub(crate) fn convert_module_globals(
143116
let ops = global.init_expr.get_operators_reader();
144117
Ok(Global { init: process_const_operators(ops)?, ty: GlobalType::new(ty, global.ty.mutable) })
145118
})
146-
.collect::<Result<Vec<_>>>()
119+
.collect::<Result<Box<_>>>()
147120
}
148121

149122
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
163136
pub(crate) fn convert_module_code(
164137
func: wasmparser::FunctionBody<'_>,
165138
mut validator: FuncValidator<ValidatorResources>,
166-
) -> Result<(FunctionCode, FuncValidatorAllocations)> {
139+
reader_allocs: OperatorsReaderAllocations,
140+
) -> Result<(FunctionCode, FuncValidatorAllocations, OperatorsReaderAllocations)> {
167141
let locals_reader = func.get_locals_reader()?;
168142
let count = locals_reader.get_count();
169143
let pos = locals_reader.original_position();
@@ -199,8 +173,13 @@ pub(crate) fn convert_module_code(
199173
}
200174
}
201175

202-
let (body, data, allocations) = process_operators_and_validate(validator, func, local_addr_map)?;
203-
Ok((FunctionCode { instructions: body, data, locals: local_counts, uses_local_memory: false }, allocations))
176+
let (body, data, validator_allocs, reader_allocs) =
177+
process_operators_and_validate(validator, func, local_addr_map, reader_allocs)?;
178+
Ok((
179+
FunctionCode { instructions: body, data, locals: local_counts, uses_local_memory: false },
180+
validator_allocs,
181+
reader_allocs,
182+
))
204183
}
205184

206185
pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result<Arc<FuncType>> {

crates/parser/src/macros.rs

Lines changed: 6 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,19 @@
11
pub(crate) mod visit {
22
macro_rules! validate_then_visit {
3-
($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
4-
$(validate_then_visit!(@@$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann)*));)*
5-
};
6-
7-
// These special-case arms exist so we only clone wasmparser's non-Copy payloads
8-
(@@mvp BrTable { $arg:ident: $argty:ty } => $visit:ident ($($ann:tt)*)) => {
9-
fn $visit(&mut self, $arg: $argty) -> Self::Output {
10-
self.0.$visit($arg.clone());
11-
let validation = self.0.validator.visitor(self.0.position).$visit($arg);
12-
if let Err(e) = validation {
13-
cold_path();
14-
self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
15-
}
16-
}
17-
};
18-
19-
(@@reference_types TypedSelectMulti { $arg:ident: $argty:ty } => $visit:ident ($($ann:tt)*)) => {
20-
fn $visit(&mut self, $arg: $argty) -> Self::Output {
21-
self.0.$visit($arg.clone());
22-
let validation = self.0.validator.visitor(self.0.position).$visit($arg);
23-
if let Err(e) = validation {
24-
cold_path();
25-
self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
26-
}
27-
}
28-
};
29-
30-
(@@exceptions TryTable { $arg:ident: $argty:ty } => $visit:ident ($($ann:tt)*)) => {
31-
fn $visit(&mut self, $arg: $argty) -> Self::Output {
32-
self.0.$visit($arg.clone());
33-
let validation = self.0.validator.visitor(self.0.position).$visit($arg);
34-
if let Err(e) = validation {
35-
cold_path();
36-
self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
37-
}
38-
}
39-
};
40-
41-
(@@stack_switching Resume { cont_type_index: $cont:ty, resume_table: $table:ty } => $visit:ident ($($ann:tt)*)) => {
42-
fn $visit(&mut self, cont_type_index: $cont, resume_table: $table) -> Self::Output {
43-
self.0.$visit(cont_type_index, resume_table.clone());
44-
let validation = self.0.validator.visitor(self.0.position).$visit(cont_type_index, resume_table);
45-
if let Err(e) = validation {
46-
cold_path();
47-
self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
48-
}
49-
}
50-
};
51-
52-
(@@stack_switching ResumeThrow { cont_type_index: $cont:ty, tag_index: $tag:ty, resume_table: $table:ty } => $visit:ident ($($ann:tt)*)) => {
53-
fn $visit(&mut self, cont_type_index: $cont, tag_index: $tag, resume_table: $table) -> Self::Output {
54-
self.0.$visit(cont_type_index, tag_index, resume_table.clone());
55-
let validation = self.0.validator.visitor(self.0.position).$visit(cont_type_index, tag_index, resume_table);
56-
if let Err(e) = validation {
57-
cold_path();
58-
self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
59-
}
60-
}
61-
};
62-
63-
(@@stack_switching ResumeThrowRef { cont_type_index: $cont:ty, resume_table: $table:ty } => $visit:ident ($($ann:tt)*)) => {
64-
fn $visit(&mut self, cont_type_index: $cont, resume_table: $table) -> Self::Output {
65-
self.0.$visit(cont_type_index, resume_table.clone());
66-
let validation = self.0.validator.visitor(self.0.position).$visit(cont_type_index, resume_table);
67-
if let Err(e) = validation {
68-
cold_path();
69-
self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
70-
}
71-
}
72-
};
73-
74-
(@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => {
3+
($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {$(
754
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
76-
self.0.$visit($($($arg),*)?);
5+
self.0.$visit($($($arg.clone()),*)?);
776
let validation = self.0.validator.visitor(self.0.position).$visit($($($arg),*)?);
787
if let Err(e) = validation {
798
cold_path();
809
self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
8110
}
8211
}
83-
};
12+
)*};
8413
}
8514

8615
macro_rules! validate_then_visit_simd {
87-
($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
88-
$(validate_then_visit_simd!(@@$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann)*));)*
89-
};
90-
91-
(@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => {
16+
($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {$(
9217
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
9318
self.0.$visit($($($arg),*)?);
9419
let validation = self.0.validator.simd_visitor(self.0.position).$visit($($($arg),*)?);
@@ -97,7 +22,7 @@ pub(crate) mod visit {
9722
self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position });
9823
}
9924
}
100-
};
25+
)*};
10126
}
10227

10328
macro_rules! define_operand {
@@ -166,7 +91,7 @@ pub(crate) mod visit {
16691
(@@tail_call $($rest:tt)* ) => {};
16792

16893
(@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => {
169-
fn $visit(&mut self $($(,_: $argty)*)?) {
94+
fn $visit(&mut self $($(,_: $argty)*)?) -> Self::Output {
17095
self.unsupported(stringify!($visit))
17196
}
17297
};

0 commit comments

Comments
 (0)