Skip to content

Commit 375f9aa

Browse files
feat: parse memory and table sections
Signed-off-by: Henry Gressmann <[email protected]>
1 parent 820ecb4 commit 375f9aa

File tree

6 files changed

+117
-43
lines changed

6 files changed

+117
-43
lines changed

crates/parser/src/conversion.rs

+42-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,53 @@
11
use alloc::{boxed::Box, format, string::ToString, vec::Vec};
22
use log::info;
33
use tinywasm_types::{
4-
BlockArgs, ConstInstruction, Export, ExternalKind, FuncType, Global, Instruction, MemArg, ValType,
4+
BlockArgs, ConstInstruction, Export, ExternalKind, FuncType, Global, Instruction, MemArg, MemoryArch, MemoryType,
5+
TableType, ValType,
56
};
67
use wasmparser::{FuncValidator, ValidatorResources};
78

89
use crate::{module::CodeSection, Result};
910

11+
pub(crate) fn convert_module_memories<T: IntoIterator<Item = wasmparser::Result<wasmparser::MemoryType>>>(
12+
memory_types: T,
13+
) -> Result<Vec<MemoryType>> {
14+
let memory_type = memory_types
15+
.into_iter()
16+
.map(|memory| {
17+
let memory = memory?;
18+
Ok(MemoryType {
19+
arch: match memory.memory64 {
20+
true => MemoryArch::I64,
21+
false => MemoryArch::I32,
22+
},
23+
page_count_initial: memory.initial,
24+
page_count_max: memory.maximum,
25+
})
26+
})
27+
.collect::<Result<Vec<_>>>()?;
28+
29+
Ok(memory_type)
30+
}
31+
32+
pub(crate) fn convert_module_tables<T: IntoIterator<Item = wasmparser::Result<wasmparser::TableType>>>(
33+
table_types: T,
34+
) -> Result<Vec<TableType>> {
35+
let table_type = table_types
36+
.into_iter()
37+
.map(|table| {
38+
let table = table?;
39+
let ty = convert_valtype(&table.element_type);
40+
Ok(TableType {
41+
element_type: ty,
42+
size_initial: table.initial,
43+
size_max: table.maximum,
44+
})
45+
})
46+
.collect::<Result<Vec<_>>>()?;
47+
48+
Ok(table_type)
49+
}
50+
1051
pub(crate) fn convert_module_globals<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Global<'a>>>>(
1152
globals: T,
1253
) -> Result<Vec<Global>> {

crates/parser/src/lib.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ impl TryFrom<ModuleReader> for TinyWasmModule {
102102
return Err(ParseError::EndNotReached);
103103
}
104104

105-
let func_types = reader.function_section;
105+
let func_types = reader.func_addrs;
106106
let funcs = reader
107-
.code_section
107+
.code
108108
.into_iter()
109109
.zip(func_types)
110110
.map(|(f, ty)| Function {
@@ -114,15 +114,18 @@ impl TryFrom<ModuleReader> for TinyWasmModule {
114114
})
115115
.collect::<Vec<_>>();
116116

117-
let globals = reader.global_section;
117+
let globals = reader.globals;
118+
let table_types = reader.table_types;
118119

119120
Ok(TinyWasmModule {
120121
version: reader.version,
121122
start_func: reader.start_func,
122-
types: reader.type_section.into_boxed_slice(),
123+
func_types: reader.func_types.into_boxed_slice(),
123124
funcs: funcs.into_boxed_slice(),
124-
exports: reader.export_section.into_boxed_slice(),
125+
exports: reader.exports.into_boxed_slice(),
125126
globals: globals.into_boxed_slice(),
127+
table_types: table_types.into_boxed_slice(),
128+
memory_types: reader.memory_types.into_boxed_slice(),
126129
})
127130
}
128131
}

crates/parser/src/module.rs

+33-32
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::log::debug;
22
use alloc::{boxed::Box, format, vec::Vec};
33
use core::fmt::Debug;
4-
use tinywasm_types::{Export, FuncType, Global, Instruction, ValType};
4+
use tinywasm_types::{Export, FuncType, Global, Instruction, MemoryType, TableType, ValType};
55
use wasmparser::{Payload, Validator};
66

77
use crate::{conversion, ParseError, Result};
@@ -17,14 +17,14 @@ pub struct ModuleReader {
1717
pub version: Option<u16>,
1818
pub start_func: Option<u32>,
1919

20-
pub type_section: Vec<FuncType>,
21-
pub function_section: Vec<u32>,
22-
pub export_section: Vec<Export>,
23-
pub code_section: Vec<CodeSection>,
24-
pub global_section: Vec<Global>,
20+
pub func_types: Vec<FuncType>,
21+
pub func_addrs: Vec<u32>,
22+
pub exports: Vec<Export>,
23+
pub code: Vec<CodeSection>,
24+
pub globals: Vec<Global>,
25+
pub table_types: Vec<TableType>,
26+
pub memory_types: Vec<MemoryType>,
2527

26-
// pub table_section: Option<TableSectionReader<'a>>,
27-
// pub memory_section: Option<MemorySectionReader<'a>>,
2828
// pub element_section: Option<ElementSectionReader<'a>>,
2929
// pub data_section: Option<DataSectionReader<'a>>,
3030
// pub import_section: Option<ImportSectionReader<'a>>,
@@ -35,13 +35,13 @@ impl Debug for ModuleReader {
3535
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
3636
f.debug_struct("ModuleReader")
3737
.field("version", &self.version)
38-
.field("type_section", &self.type_section)
39-
.field("function_section", &self.function_section)
40-
.field("code_section", &self.code_section)
41-
.field("export_section", &self.export_section)
42-
.field("global_section", &self.global_section)
43-
// .field("table_section", &self.table_section)
44-
// .field("memory_section", &self.memory_section)
38+
.field("func_types", &self.func_types)
39+
.field("func_addrs", &self.func_addrs)
40+
.field("code", &self.code)
41+
.field("exports", &self.exports)
42+
.field("globals", &self.globals)
43+
.field("table_types", &self.table_types)
44+
.field("memory_types", &self.memory_types)
4545
// .field("element_section", &self.element_section)
4646
// .field("data_section", &self.data_section)
4747
// .field("import_section", &self.import_section)
@@ -74,34 +74,31 @@ impl ModuleReader {
7474
TypeSection(reader) => {
7575
debug!("Found type section");
7676
validator.type_section(&reader)?;
77-
self.type_section = reader
77+
self.func_types = reader
7878
.into_iter()
7979
.map(|t| conversion::convert_module_type(t?))
8080
.collect::<Result<Vec<FuncType>>>()?;
8181
}
8282
FunctionSection(reader) => {
8383
debug!("Found function section");
8484
validator.function_section(&reader)?;
85-
self.function_section = reader.into_iter().map(|f| Ok(f?)).collect::<Result<Vec<_>>>()?;
85+
self.func_addrs = reader.into_iter().map(|f| Ok(f?)).collect::<Result<Vec<_>>>()?;
8686
}
8787
GlobalSection(reader) => {
8888
debug!("Found global section");
8989
validator.global_section(&reader)?;
90-
self.global_section = conversion::convert_module_globals(reader)?;
90+
self.globals = conversion::convert_module_globals(reader)?;
9191
}
92-
TableSection(_reader) => {
93-
return Err(ParseError::UnsupportedSection("Table section".into()));
94-
// debug!("Found table section");
95-
// validator.table_section(&reader)?;
96-
// self.table_section = Some(reader);
92+
TableSection(reader) => {
93+
debug!("Found table section");
94+
validator.table_section(&reader)?;
95+
self.table_types = conversion::convert_module_tables(reader)?;
9796
}
98-
MemorySection(_reader) => {
99-
return Err(ParseError::UnsupportedSection("Memory section".into()));
100-
// debug!("Found memory section");
101-
// validator.memory_section(&reader)?;
102-
// self.memory_section = Some(reader);
97+
MemorySection(reader) => {
98+
debug!("Found memory section");
99+
validator.memory_section(&reader)?;
100+
self.memory_types = conversion::convert_module_memories(reader)?;
103101
}
104-
105102
ElementSection(_reader) => {
106103
return Err(ParseError::UnsupportedSection("Element section".into()));
107104
// debug!("Found element section");
@@ -116,7 +113,7 @@ impl ModuleReader {
116113
}
117114
CodeSectionStart { count, range, .. } => {
118115
debug!("Found code section ({} functions)", count);
119-
if !self.code_section.is_empty() {
116+
if !self.code.is_empty() {
120117
return Err(ParseError::DuplicateSection("Code section".into()));
121118
}
122119

@@ -127,7 +124,7 @@ impl ModuleReader {
127124
let v = validator.code_section_entry(&function)?;
128125
let func_validator = v.into_validator(Default::default());
129126

130-
self.code_section
127+
self.code
131128
.push(conversion::convert_module_code(function, func_validator)?);
132129
}
133130
ImportSection(_reader) => {
@@ -140,7 +137,7 @@ impl ModuleReader {
140137
ExportSection(reader) => {
141138
debug!("Found export section");
142139
validator.export_section(&reader)?;
143-
self.export_section = reader
140+
self.exports = reader
144141
.into_iter()
145142
.map(|e| conversion::convert_module_export(e?))
146143
.collect::<Result<Vec<_>>>()?;
@@ -158,6 +155,10 @@ impl ModuleReader {
158155
debug!("Found custom section");
159156
debug!("Skipping custom section: {:?}", reader.name());
160157
}
158+
// TagSection(tag) => {
159+
// debug!("Found tag section");
160+
// validator.tag_section(&tag)?;
161+
// }
161162
UnknownSection { .. } => return Err(ParseError::UnsupportedSection("Unknown section".into())),
162163
section => {
163164
return Err(ParseError::UnsupportedSection(format!(

crates/tinywasm/src/module.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl Module {
6262

6363
let func_addrs = store.add_funcs(self.data.funcs.into(), idx);
6464
let instance = ModuleInstance::new(
65-
self.data.types,
65+
self.data.func_types,
6666
self.data.start_func,
6767
self.data.exports,
6868
func_addrs,

0 commit comments

Comments
 (0)