mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
wasm_interp: implement if/else statements
This commit is contained in:
parent
131a9925d0
commit
fa1e0a8614
1 changed files with 33 additions and 7 deletions
|
@ -179,9 +179,9 @@ impl<'a> ExecutionState<'a> {
|
||||||
|
|
||||||
let target_block_depth = self.block_depth - relative_blocks_outward - 1;
|
let target_block_depth = self.block_depth - relative_blocks_outward - 1;
|
||||||
loop {
|
loop {
|
||||||
let skip_op = OpCode::from(module.code.bytes[self.program_counter]);
|
let skipped_op = OpCode::from(module.code.bytes[self.program_counter]);
|
||||||
OpCode::skip_bytes(&module.code.bytes, &mut self.program_counter).unwrap();
|
OpCode::skip_bytes(&module.code.bytes, &mut self.program_counter).unwrap();
|
||||||
match skip_op {
|
match skipped_op {
|
||||||
BLOCK | LOOP | IF => {
|
BLOCK | LOOP | IF => {
|
||||||
self.block_depth += 1;
|
self.block_depth += 1;
|
||||||
}
|
}
|
||||||
|
@ -219,19 +219,45 @@ impl<'a> ExecutionState<'a> {
|
||||||
}
|
}
|
||||||
NOP => {}
|
NOP => {}
|
||||||
BLOCK => {
|
BLOCK => {
|
||||||
self.fetch_immediate_u32(module); // blocktype
|
self.fetch_immediate_u32(module); // blocktype (ignored)
|
||||||
self.block_depth += 1;
|
self.block_depth += 1;
|
||||||
}
|
}
|
||||||
LOOP => {
|
LOOP => {
|
||||||
self.fetch_immediate_u32(module); // blocktype
|
self.fetch_immediate_u32(module); // blocktype (ignored)
|
||||||
self.block_depth += 1;
|
self.block_depth += 1;
|
||||||
}
|
}
|
||||||
IF => {
|
IF => {
|
||||||
self.fetch_immediate_u32(module); // blocktype
|
self.fetch_immediate_u32(module); // blocktype (ignored)
|
||||||
|
let condition = self.value_stack.pop_i32();
|
||||||
self.block_depth += 1;
|
self.block_depth += 1;
|
||||||
todo!("{:?} @ {:#x}", op_code, file_offset);
|
if condition == 0 {
|
||||||
|
let mut depth = self.block_depth;
|
||||||
|
loop {
|
||||||
|
let skipped_op = OpCode::from(module.code.bytes[self.program_counter]);
|
||||||
|
OpCode::skip_bytes(&module.code.bytes, &mut self.program_counter).unwrap();
|
||||||
|
match skipped_op {
|
||||||
|
BLOCK | LOOP | IF => {
|
||||||
|
depth += 1;
|
||||||
|
}
|
||||||
|
END => {
|
||||||
|
depth -= 1;
|
||||||
|
}
|
||||||
|
ELSE => {
|
||||||
|
if depth == self.block_depth {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ELSE => {
|
||||||
|
// We only reach this point when we finish executing the "then" block of an IF statement
|
||||||
|
// (For a false condition, we would have skipped past the ELSE when we saw the IF)
|
||||||
|
// We don't want to execute the ELSE block, so we skip it, just like `br 0` would.
|
||||||
|
self.break_forward(0, module);
|
||||||
}
|
}
|
||||||
ELSE => todo!("{:?} @ {:#x}", op_code, file_offset),
|
|
||||||
END => {
|
END => {
|
||||||
if self.block_depth == 0 {
|
if self.block_depth == 0 {
|
||||||
// implicit RETURN at end of function
|
// implicit RETURN at end of function
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue