Skip to content

Commit 9d7c192

Browse files
chore: improve parser, clean up interpreter loop
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
1 parent dce86f8 commit 9d7c192

File tree

12 files changed

+575
-730
lines changed

12 files changed

+575
-730
lines changed

benchmarks/benches/selfhosted.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ fn criterion_benchmark(c: &mut Criterion) {
6060
}
6161

6262
{
63-
let mut group = c.benchmark_group("selfhosted");
64-
group.bench_function("native", |b| b.iter(run_native));
65-
group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(TINYWASM)));
66-
group.bench_function("wasmi", |b| b.iter(|| run_wasmi(TINYWASM)));
67-
group.bench_function("wasmer", |b| b.iter(|| run_wasmer(TINYWASM)));
63+
// let mut group = c.benchmark_group("selfhosted");
64+
// group.bench_function("native", |b| b.iter(run_native));
65+
// group.bench_function("tinywasm", |b| b.iter(|| run_tinywasm(TINYWASM)));
66+
// group.bench_function("wasmi", |b| b.iter(|| run_wasmi(TINYWASM)));
67+
// group.bench_function("wasmer", |b| b.iter(|| run_wasmer(TINYWASM)));
6868
}
6969
}
7070

crates/parser/src/conversion.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::Result;
2-
use crate::{module::Code, visit::process_operators};
2+
use crate::{module::Code, visit::process_operators_and_validate};
33
use alloc::{boxed::Box, format, string::ToString, vec::Vec};
44
use tinywasm_types::*;
55
use wasmparser::{FuncValidator, OperatorsReader, ValidatorResources};
@@ -174,17 +174,20 @@ pub(crate) fn convert_module_code(
174174
let count = locals_reader.get_count();
175175
let pos = locals_reader.original_position();
176176

177-
let mut locals = Vec::with_capacity(count as usize);
178-
for (i, local) in locals_reader.into_iter().enumerate() {
179-
let local = local?;
180-
validator.define_locals(pos + i, local.0, local.1)?;
181-
for _ in 0..local.0 {
182-
locals.push(convert_valtype(&local.1));
177+
let locals = {
178+
let mut locals = Vec::new();
179+
locals.reserve_exact(count as usize);
180+
for (i, local) in locals_reader.into_iter().enumerate() {
181+
let local = local?;
182+
validator.define_locals(pos + i, local.0, local.1)?;
183+
for _ in 0..local.0 {
184+
locals.push(convert_valtype(&local.1));
185+
}
183186
}
184-
}
187+
locals.into_boxed_slice()
188+
};
185189

186-
let body = process_operators(Some(validator), func)?;
187-
let locals = locals.into_boxed_slice();
190+
let body = process_operators_and_validate(validator, func)?;
188191
Ok((body, locals))
189192
}
190193

@@ -196,6 +199,7 @@ pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result<FuncType>
196199
"Expected exactly one type in the type section".to_string(),
197200
));
198201
}
202+
199203
let ty = types.next().unwrap().unwrap_func();
200204
let params = ty.params().iter().map(convert_valtype).collect::<Vec<ValType>>().into_boxed_slice();
201205
let results = ty.results().iter().map(convert_valtype).collect::<Vec<ValType>>().into_boxed_slice();
@@ -230,10 +234,6 @@ pub(crate) fn convert_valtype(valtype: &wasmparser::ValType) -> ValType {
230234
}
231235
}
232236

233-
pub(crate) fn convert_memarg(memarg: wasmparser::MemArg) -> MemoryArg {
234-
MemoryArg { offset: memarg.offset, mem_addr: memarg.memory }
235-
}
236-
237237
pub(crate) fn process_const_operators(ops: OperatorsReader<'_>) -> Result<ConstInstruction> {
238238
let ops = ops.into_iter().collect::<wasmparser::Result<Vec<_>>>()?;
239239
// In practice, the len can never be something other than 2,

crates/parser/src/lib.rs

+4-41
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,9 @@ mod conversion;
3131
mod error;
3232
mod module;
3333
mod visit;
34-
use alloc::{string::ToString, vec::Vec};
34+
use alloc::vec::Vec;
3535
pub use error::*;
3636
use module::ModuleReader;
37-
use tinywasm_types::WasmFunction;
3837
use wasmparser::{Validator, WasmFeaturesInflated};
3938

4039
pub use tinywasm_types::TinyWasmModule;
@@ -93,7 +92,7 @@ impl Parser {
9392
return Err(ParseError::EndNotReached);
9493
}
9594

96-
reader.try_into()
95+
reader.to_module()
9796
}
9897

9998
#[cfg(feature = "std")]
@@ -133,7 +132,7 @@ impl Parser {
133132
reader.process_payload(payload, &mut validator)?;
134133
buffer.drain(..consumed);
135134
if eof || reader.end_reached {
136-
return reader.try_into();
135+
return reader.to_module();
137136
}
138137
}
139138
};
@@ -145,42 +144,6 @@ impl TryFrom<ModuleReader> for TinyWasmModule {
145144
type Error = ParseError;
146145

147146
fn try_from(reader: ModuleReader) -> Result<Self> {
148-
if !reader.end_reached {
149-
return Err(ParseError::EndNotReached);
150-
}
151-
152-
let code_type_addrs = reader.code_type_addrs;
153-
let local_function_count = reader.code.len();
154-
155-
if code_type_addrs.len() != local_function_count {
156-
return Err(ParseError::Other("Code and code type address count mismatch".to_string()));
157-
}
158-
159-
let funcs = reader
160-
.code
161-
.into_iter()
162-
.zip(code_type_addrs)
163-
.map(|((instructions, locals), ty_idx)| WasmFunction {
164-
instructions,
165-
locals,
166-
ty: reader.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone(),
167-
})
168-
.collect::<Vec<_>>();
169-
170-
let globals = reader.globals;
171-
let table_types = reader.table_types;
172-
173-
Ok(TinyWasmModule {
174-
funcs: funcs.into_boxed_slice(),
175-
func_types: reader.func_types.into_boxed_slice(),
176-
globals: globals.into_boxed_slice(),
177-
table_types: table_types.into_boxed_slice(),
178-
imports: reader.imports.into_boxed_slice(),
179-
start_func: reader.start_func,
180-
data: reader.data.into_boxed_slice(),
181-
exports: reader.exports.into_boxed_slice(),
182-
elements: reader.elements.into_boxed_slice(),
183-
memory_types: reader.memory_types.into_boxed_slice(),
184-
})
147+
reader.to_module()
185148
}
186149
}

crates/parser/src/module.rs

+45-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
use crate::log::debug;
22
use crate::{conversion, ParseError, Result};
3+
use alloc::string::ToString;
34
use alloc::{boxed::Box, format, vec::Vec};
4-
use tinywasm_types::{Data, Element, Export, FuncType, Global, Import, Instruction, MemoryType, TableType, ValType};
5+
use tinywasm_types::{
6+
Data, Element, Export, FuncType, Global, Import, Instruction, MemoryType, TableType, TinyWasmModule, ValType,
7+
WasmFunction,
8+
};
59
use wasmparser::{FuncValidatorAllocations, Payload, Validator};
610

711
pub(crate) type Code = (Box<[Instruction]>, Box<[ValType]>);
@@ -173,4 +177,44 @@ impl ModuleReader {
173177

174178
Ok(())
175179
}
180+
181+
#[inline]
182+
pub(crate) fn to_module(self) -> Result<TinyWasmModule> {
183+
if !self.end_reached {
184+
return Err(ParseError::EndNotReached);
185+
}
186+
187+
let local_function_count = self.code.len();
188+
189+
if self.code_type_addrs.len() != local_function_count {
190+
return Err(ParseError::Other("Code and code type address count mismatch".to_string()));
191+
}
192+
193+
let funcs = self
194+
.code
195+
.into_iter()
196+
.zip(self.code_type_addrs)
197+
.map(|((instructions, locals), ty_idx)| WasmFunction {
198+
instructions,
199+
locals,
200+
ty: self.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone(),
201+
})
202+
.collect::<Vec<_>>();
203+
204+
let globals = self.globals;
205+
let table_types = self.table_types;
206+
207+
Ok(TinyWasmModule {
208+
funcs: funcs.into_boxed_slice(),
209+
func_types: self.func_types.into_boxed_slice(),
210+
globals: globals.into_boxed_slice(),
211+
table_types: table_types.into_boxed_slice(),
212+
imports: self.imports.into_boxed_slice(),
213+
start_func: self.start_func,
214+
data: self.data.into_boxed_slice(),
215+
exports: self.exports.into_boxed_slice(),
216+
elements: self.elements.into_boxed_slice(),
217+
memory_types: self.memory_types.into_boxed_slice(),
218+
})
219+
}
176220
}

0 commit comments

Comments
 (0)