Compile a boolean operation as an expression, with an optional short-circuit target override. When `short_circuit_target` is `Some`, the short-circuit jumps go to that block instead of the default `after_block`, enabling jump threading to avoid redundant `__bool__` calls.
(
&mut self,
op: &ast::BoolOp,
values: &[ast::Expr],
short_circuit_target: Option<BlockIdx>,
)
| 7486 | /// the short-circuit jumps go to that block instead of the default |
| 7487 | /// `after_block`, enabling jump threading to avoid redundant `__bool__` calls. |
| 7488 | fn compile_bool_op_with_target( |
| 7489 | &mut self, |
| 7490 | op: &ast::BoolOp, |
| 7491 | values: &[ast::Expr], |
| 7492 | short_circuit_target: Option<BlockIdx>, |
| 7493 | ) -> CompileResult<()> { |
| 7494 | let after_block = self.new_block(); |
| 7495 | let (last_value, values) = values.split_last().unwrap(); |
| 7496 | let jump_target = short_circuit_target.unwrap_or(after_block); |
| 7497 | |
| 7498 | for value in values { |
| 7499 | // Optimization: when a non-last value is a BoolOp with the opposite |
| 7500 | // operator, redirect its short-circuit exits to skip the outer's |
| 7501 | // redundant __bool__ test (jump threading). |
| 7502 | if short_circuit_target.is_none() |
| 7503 | && let ast::Expr::BoolOp(ast::ExprBoolOp { |
| 7504 | op: inner_op, |
| 7505 | values: inner_values, |
| 7506 | .. |
| 7507 | }) = value |
| 7508 | && inner_op != op |
| 7509 | { |
| 7510 | let pop_block = self.new_block(); |
| 7511 | self.compile_bool_op_with_target(inner_op, inner_values, Some(pop_block))?; |
| 7512 | self.emit_short_circuit_test(op, after_block); |
| 7513 | self.switch_to_block(pop_block); |
| 7514 | emit!(self, Instruction::PopTop); |
| 7515 | continue; |
| 7516 | } |
| 7517 | |
| 7518 | self.compile_expression(value)?; |
| 7519 | self.emit_short_circuit_test(op, jump_target); |
| 7520 | emit!(self, Instruction::PopTop); |
| 7521 | } |
| 7522 | |
| 7523 | // If all values did not qualify, take the value of the last value: |
| 7524 | self.compile_expression(last_value)?; |
| 7525 | self.switch_to_block(after_block); |
| 7526 | Ok(()) |
| 7527 | } |
| 7528 | |
| 7529 | /// Emit `Copy 1` + conditional jump for short-circuit evaluation. |
| 7530 | /// For `And`, emits `PopJumpIfFalse`; for `Or`, emits `PopJumpIfTrue`. |
no test coverage detected