boa_engine 0.17.0

Boa is a Javascript lexer, parser and compiler written in Rust. Currently, it has support for some of the language.
Documentation
use crate::{
    bytecompiler::{ByteCompiler, JumpControlInfo},
    vm::Opcode,
};
use boa_ast::statement::Break;
use boa_interner::Sym;

impl ByteCompiler<'_, '_> {
    /// Compile a [`Break`] `boa_ast` node
    pub(crate) fn compile_break(&mut self, node: Break, _use_expr: bool) {
        if let Some(info) = self.jump_info.last().filter(|info| info.is_try_block()) {
            let has_finally_or_is_finally = info.has_finally() || info.in_finally();

            let (break_label, target_jump_label) =
                self.emit_opcode_with_two_operands(Opcode::Break);

            if let Some(node_label) = node.label() {
                let info = self.jump_info_label(node_label);
                info.push_break_label(target_jump_label);

                if !has_finally_or_is_finally {
                    info.push_break_label(break_label);
                    return;
                }
            } else {
                self.jump_info
                    .last_mut()
                    .expect("jump_info must exist to reach this point")
                    .push_set_jumps(target_jump_label);
            }

            let info = self
                .jump_info
                .last_mut()
                .expect("This try block must exist");

            info.push_break_label(break_label);

            return;
        }

        // Emit the break opcode -> (Label, Label)
        let (break_label, target_label) = self.emit_opcode_with_two_operands(Opcode::Break);
        if let Some(label) = node.label() {
            let info = self.jump_info_label(label);
            info.push_break_label(break_label);
            info.push_break_label(target_label);
            return;
        }

        let info = self.jump_info_non_labelled();
        info.push_break_label(break_label);
        info.push_break_label(target_label);
    }

    fn jump_info_non_labelled(&mut self) -> &mut JumpControlInfo {
        for info in self.jump_info.iter_mut().rev() {
            if !info.is_labelled() {
                return info;
            }
        }
        panic!("Jump info without label must exist");
    }

    fn jump_info_label(&mut self, label: Sym) -> &mut JumpControlInfo {
        for info in self.jump_info.iter_mut().rev() {
            if info.label() == Some(label) {
                return info;
            }
        }
        panic!("Jump info with label must exist");
    }
}