Skip to content

Commit c2499d9

Browse files
fix: fix remaining issues with extended-const
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent dcd8b15 commit c2499d9

12 files changed

Lines changed: 213 additions & 139 deletions

File tree

crates/parser/src/conversion.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -235,29 +235,45 @@ pub(crate) fn convert_valtype(valtype: &wasmparser::ValType) -> ValType {
235235
}
236236
}
237237

238-
pub(crate) fn process_const_operators(ops: OperatorsReader<'_>) -> Result<ConstInstruction> {
238+
pub(crate) fn process_const_operators(ops: OperatorsReader<'_>) -> Result<Box<[ConstInstruction]>> {
239239
let ops = ops.into_iter().collect::<wasmparser::Result<Vec<_>>>()?;
240240
// In practice, the len can never be something other than 2,
241241
// but we'll keep this here since it's part of the spec
242242
// Invalid modules will be rejected by the validator anyway (there are also tests for this in the testsuite)
243243
assert!(ops.len() >= 2);
244244
assert!(matches!(ops[ops.len() - 1], wasmparser::Operator::End));
245245

246-
match &ops[ops.len() - 2] {
247-
wasmparser::Operator::RefNull { hty } => match convert_heaptype(*hty) {
248-
ValType::RefFunc => Ok(ConstInstruction::RefFunc(None)),
249-
ValType::RefExtern => Ok(ConstInstruction::RefExtern(None)),
250-
_ => unimplemented!("Unsupported heap type: {:?}", hty),
251-
},
252-
wasmparser::Operator::RefFunc { function_index } => Ok(ConstInstruction::RefFunc(Some(*function_index))),
253-
wasmparser::Operator::I32Const { value } => Ok(ConstInstruction::I32Const(*value)),
254-
wasmparser::Operator::I64Const { value } => Ok(ConstInstruction::I64Const(*value)),
255-
wasmparser::Operator::F32Const { value } => Ok(ConstInstruction::F32Const(f32::from_bits(value.bits()))),
256-
wasmparser::Operator::F64Const { value } => Ok(ConstInstruction::F64Const(f64::from_bits(value.bits()))),
257-
wasmparser::Operator::V128Const { value } => Ok(ConstInstruction::V128Const(value.i128())),
258-
wasmparser::Operator::GlobalGet { global_index } => Ok(ConstInstruction::GlobalGet(*global_index)),
259-
op => Err(crate::ParseError::UnsupportedOperator(format!("Unsupported const instruction: {op:?}"))),
246+
let mut out = Vec::with_capacity(ops.len().saturating_sub(1));
247+
for op in ops.iter().take(ops.len() - 1) {
248+
let instr = match op {
249+
wasmparser::Operator::RefNull { hty } => match convert_heaptype(*hty) {
250+
ValType::RefFunc => ConstInstruction::RefFunc(None),
251+
ValType::RefExtern => ConstInstruction::RefExtern(None),
252+
_ => unimplemented!("Unsupported heap type: {:?}", hty),
253+
},
254+
wasmparser::Operator::RefFunc { function_index } => ConstInstruction::RefFunc(Some(*function_index)),
255+
wasmparser::Operator::I32Const { value } => ConstInstruction::I32Const(*value),
256+
wasmparser::Operator::I64Const { value } => ConstInstruction::I64Const(*value),
257+
wasmparser::Operator::F32Const { value } => ConstInstruction::F32Const(f32::from_bits(value.bits())),
258+
wasmparser::Operator::F64Const { value } => ConstInstruction::F64Const(f64::from_bits(value.bits())),
259+
wasmparser::Operator::V128Const { value } => ConstInstruction::V128Const(value.i128()),
260+
wasmparser::Operator::GlobalGet { global_index } => ConstInstruction::GlobalGet(*global_index),
261+
wasmparser::Operator::I32Add => ConstInstruction::I32Add,
262+
wasmparser::Operator::I32Sub => ConstInstruction::I32Sub,
263+
wasmparser::Operator::I32Mul => ConstInstruction::I32Mul,
264+
wasmparser::Operator::I64Add => ConstInstruction::I64Add,
265+
wasmparser::Operator::I64Sub => ConstInstruction::I64Sub,
266+
wasmparser::Operator::I64Mul => ConstInstruction::I64Mul,
267+
other => {
268+
return Err(crate::ParseError::UnsupportedOperator(format!(
269+
"Unsupported const instruction: {other:?}"
270+
)));
271+
}
272+
};
273+
out.push(instr);
260274
}
275+
276+
Ok(out.into_boxed_slice())
261277
}
262278

263279
pub(crate) fn convert_heaptype(heap: wasmparser::HeapType) -> ValType {

crates/parser/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ impl Parser {
9090
| WasmFeatures::BULK_MEMORY
9191
| WasmFeatures::SATURATING_FLOAT_TO_INT
9292
| WasmFeatures::SIGN_EXTENSION
93+
| WasmFeatures::EXTENDED_CONST
9394
| WasmFeatures::FUNCTION_REFERENCES
9495
| WasmFeatures::TAIL_CALL
9596
| WasmFeatures::MULTI_MEMORY

crates/tinywasm/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ harness=false
9898
[[test]]
9999
name="test-wasm-extended-const"
100100
harness=false
101-
test=false
102101

103102
[[test]]
104103
name="test-wasm-relaxed-simd"

crates/tinywasm/src/instance.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ impl ModuleInstance {
152152
let global_addrs = store.init_globals(addrs.globals, &module.0.globals, &addrs.funcs, idx)?;
153153
let (elem_addrs, elem_trapped) =
154154
store.init_elements(&addrs.tables, &addrs.funcs, &global_addrs, &module.0.elements, idx)?;
155-
let (data_addrs, data_trapped) = store.init_data(&addrs.memories, &module.0.data, idx)?;
155+
let (data_addrs, data_trapped) =
156+
store.init_data(&addrs.memories, &global_addrs, &addrs.funcs, &module.0.data, idx)?;
156157

157158
let instance = ModuleInstanceInner {
158159
store_id: store.id(),

crates/tinywasm/src/module.rs

Lines changed: 34 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,6 @@
11
use crate::{Imports, ModuleInstance, Result, Store};
22
use tinywasm_types::{ExternalKind, FuncType, TinyWasmModule};
33

4-
fn imported_func_type(module: &TinyWasmModule, function_index: usize) -> Option<&FuncType> {
5-
let mut seen = 0usize;
6-
for import in module.imports.iter() {
7-
if let tinywasm_types::ImportKind::Function(type_idx) = import.kind {
8-
if seen == function_index {
9-
return module.func_types.get(type_idx as usize);
10-
}
11-
seen += 1;
12-
}
13-
}
14-
None
15-
}
16-
17-
fn imported_global_type(module: &TinyWasmModule, global_index: usize) -> Option<&tinywasm_types::GlobalType> {
18-
let mut seen = 0usize;
19-
for import in module.imports.iter() {
20-
if let tinywasm_types::ImportKind::Global(global_ty) = &import.kind {
21-
if seen == global_index {
22-
return Some(global_ty);
23-
}
24-
seen += 1;
25-
}
26-
}
27-
None
28-
}
29-
304
/// A module import descriptor.
315
pub struct ModuleImport<'a> {
326
/// Importing module name.
@@ -146,33 +120,24 @@ impl Module {
146120
/// The returned data mirrors the module's export section and preserves order.
147121
pub fn exports(&self) -> impl Iterator<Item = ModuleExport<'_>> {
148122
self.0.exports.iter().filter_map(|export| {
123+
let imports = self.0.imports.iter();
124+
let idx = export.index as usize;
149125
let ty = match export.kind {
150126
ExternalKind::Func => {
151-
let idx = export.index as usize;
152-
let imported_funcs = self
153-
.0
154-
.imports
155-
.iter()
156-
.filter(|import| matches!(import.kind, tinywasm_types::ImportKind::Function(_)))
157-
.count();
158-
127+
let imported_funcs =
128+
imports.filter(|import| matches!(import.kind, tinywasm_types::ImportKind::Function(_))).count();
159129
if idx < imported_funcs {
160130
ExportType::Func(imported_func_type(&self.0, idx)?)
161131
} else {
162132
let local_idx = idx - imported_funcs;
163133
ExportType::Func(&self.0.funcs.get(local_idx)?.ty)
164134
}
165135
}
166-
ExternalKind::Table => ExportType::Table(self.0.table_types.get(export.index as usize)?),
167-
ExternalKind::Memory => ExportType::Memory(self.0.memory_types.get(export.index as usize)?),
136+
ExternalKind::Table => ExportType::Table(self.0.table_types.get(idx)?),
137+
ExternalKind::Memory => ExportType::Memory(self.0.memory_types.get(idx)?),
168138
ExternalKind::Global => {
169-
let idx = export.index as usize;
170-
let imported_globals = self
171-
.0
172-
.imports
173-
.iter()
174-
.filter(|import| matches!(import.kind, tinywasm_types::ImportKind::Global(_)))
175-
.count();
139+
let imported_globals =
140+
imports.filter(|import| matches!(import.kind, tinywasm_types::ImportKind::Global(_))).count();
176141
if idx < imported_globals {
177142
ExportType::Global(imported_global_type(&self.0, idx)?)
178143
} else {
@@ -186,3 +151,29 @@ impl Module {
186151
})
187152
}
188153
}
154+
155+
fn imported_func_type(module: &TinyWasmModule, function_index: usize) -> Option<&FuncType> {
156+
let mut seen = 0usize;
157+
for import in module.imports.iter() {
158+
if let tinywasm_types::ImportKind::Function(type_idx) = import.kind {
159+
if seen == function_index {
160+
return module.func_types.get(type_idx as usize);
161+
}
162+
seen += 1;
163+
}
164+
}
165+
None
166+
}
167+
168+
fn imported_global_type(module: &TinyWasmModule, global_index: usize) -> Option<&tinywasm_types::GlobalType> {
169+
let mut seen = 0usize;
170+
for import in module.imports.iter() {
171+
if let tinywasm_types::ImportKind::Global(global_ty) = &import.kind {
172+
if seen == global_index {
173+
return Some(global_ty);
174+
}
175+
seen += 1;
176+
}
177+
}
178+
None
179+
}

0 commit comments

Comments
 (0)