|
1 | 1 | use super::{ControlFrame, FuncTranslator, LocalIdx, UnreachableControlFrame};
|
2 |
| -use crate::{core::wasm, engine::BlockType, ir::Instruction, Error}; |
| 2 | +use crate::{ |
| 3 | + core::wasm, |
| 4 | + engine::{ |
| 5 | + translator::func2::{stack::IfReachability, Operand}, |
| 6 | + BlockType, |
| 7 | + }, |
| 8 | + ir::Instruction, |
| 9 | + Error, |
| 10 | +}; |
3 | 11 | use wasmparser::VisitOperator;
|
4 | 12 |
|
5 | 13 | macro_rules! impl_visit_operator {
|
@@ -102,6 +110,31 @@ impl<'a> VisitOperator<'a> for FuncTranslator {
|
102 | 110 | }
|
103 | 111 |
|
104 | 112 | fn visit_if(&mut self, _block_ty: wasmparser::BlockType) -> Self::Output {
|
| 113 | + if !self.reachable { |
| 114 | + self.stack.push_unreachable(UnreachableControlFrame::If)?; |
| 115 | + return Ok(()); |
| 116 | + } |
| 117 | + let end_label = self.labels.new_label(); |
| 118 | + let condition = self.stack.pop(); |
| 119 | + let (reachability, consume_fuel_instr) = match condition { |
| 120 | + Operand::Immediate(operand) => { |
| 121 | + let condition = i32::from(operand.val()); |
| 122 | + let reachability = match condition { |
| 123 | + 0 => { |
| 124 | + self.reachable = false; |
| 125 | + IfReachability::OnlyElse |
| 126 | + } |
| 127 | + _ => IfReachability::OnlyThen, |
| 128 | + }; |
| 129 | + let consume_fuel_instr = self.stack.consume_fuel_instr(); |
| 130 | + (reachability, consume_fuel_instr) |
| 131 | + } |
| 132 | + operand => { |
| 133 | + let else_label = self.labels.new_label(); |
| 134 | + let reachability = IfReachability::Both { else_label }; |
| 135 | + todo!() |
| 136 | + } |
| 137 | + }; |
105 | 138 | todo!()
|
106 | 139 | }
|
107 | 140 |
|
|
0 commit comments