diff options
| author | Henry <mail@henrygressmann.de> | 2026-04-25 16:47:54 +0200 |
|---|---|---|
| committer | Henry <mail@henrygressmann.de> | 2026-04-25 16:47:54 +0200 |
| commit | e6691d035b6948452d6073317451b3f1ff0a24f8 (patch) | |
| tree | b29eee89fcb4e4df1630b2d09a6286e5ddfd620e /crates/parser/src/visit.rs | |
| parent | 4d829a824834b470ada9981ab3ab2caa3e289378 (diff) | |
fix: remove unsafe rewrites
Signed-off-by: Henry <mail@henrygressmann.de>
Diffstat (limited to 'crates/parser/src/visit.rs')
| -rw-r--r-- | crates/parser/src/visit.rs | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 9a094ed..de0c8fb 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -218,14 +218,52 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild fn visit_local_tee(&mut self, idx: u32) -> Self::Output { let resolved_idx = self.local_addr_map[idx as usize]; if let Some(Some(t)) = self.validator.get_operand_type(0) { - self.instructions.push(match t { - wasmparser::ValType::I32 => Instruction::LocalTee32(resolved_idx), - wasmparser::ValType::F32 => Instruction::LocalTee32(resolved_idx), - wasmparser::ValType::I64 => Instruction::LocalTee64(resolved_idx), - wasmparser::ValType::F64 => Instruction::LocalTee64(resolved_idx), - wasmparser::ValType::V128 => Instruction::LocalTee128(resolved_idx), - wasmparser::ValType::Ref(_) => Instruction::LocalTee32(resolved_idx), - }) + let last = self.instructions.last(); + let src = match t { + wasmparser::ValType::I32 | wasmparser::ValType::F32 => { + if let Some(Instruction::LocalGet32(src)) = last { Some(*src) } else { None } + } + wasmparser::ValType::I64 | wasmparser::ValType::F64 => { + if let Some(Instruction::LocalGet64(src)) = last { Some(*src) } else { None } + } + wasmparser::ValType::V128 => { + if let Some(Instruction::LocalGet128(src)) = last { Some(*src) } else { None } + } + wasmparser::ValType::Ref(_) => { + if let Some(Instruction::LocalGet32(src)) = last { Some(*src) } else { None } + } + }; + + if let Some(src) = src { + self.instructions.pop(); + match t { + wasmparser::ValType::I32 | wasmparser::ValType::F32 => { + self.instructions.push(Instruction::LocalCopy32(src, resolved_idx)); + self.instructions.push(Instruction::LocalGet32(resolved_idx)); + } + wasmparser::ValType::I64 | wasmparser::ValType::F64 => { + self.instructions.push(Instruction::LocalCopy64(src, resolved_idx)); + self.instructions.push(Instruction::LocalGet64(resolved_idx)); + } + wasmparser::ValType::V128 => { + self.instructions.push(Instruction::LocalCopy128(src, resolved_idx)); + self.instructions.push(Instruction::LocalGet128(resolved_idx)); + } + wasmparser::ValType::Ref(_) => { + self.instructions.push(Instruction::LocalCopy32(src, resolved_idx)); + self.instructions.push(Instruction::LocalGet32(resolved_idx)); + } + } + } else { + self.instructions.push(match t { + wasmparser::ValType::I32 => Instruction::LocalTee32(resolved_idx), + wasmparser::ValType::F32 => Instruction::LocalTee32(resolved_idx), + wasmparser::ValType::I64 => Instruction::LocalTee64(resolved_idx), + wasmparser::ValType::F64 => Instruction::LocalTee64(resolved_idx), + wasmparser::ValType::V128 => Instruction::LocalTee128(resolved_idx), + wasmparser::ValType::Ref(_) => Instruction::LocalTee32(resolved_idx), + }) + } } } |
