luaur-compiler 0.1.3

Luau source-to-bytecode compiler (Rust).
Documentation
use crate::records::compiler::Compiler;
use luaur_ast::records::ast_expr_function::AstExprFunction;
use luaur_common::enums::luau_capture_type::LuauCaptureType;
use luaur_common::enums::luau_opcode::LuauOpcode;
use luaur_common::macros::luau_assert::LUAU_ASSERT;

impl Compiler {
    pub fn compile_expr_function(&mut self, expr: *mut AstExprFunction, target: u8) {
        let f = self.functions.find(&expr).unwrap();
        let fid = f.id;
        let upvals = f.upvals.clone();
        let pid = unsafe { (*self.bytecode).add_child_function(fid) };
        if pid < 0 {
            unsafe {
                crate::records::compile_error::CompileError::raise(
                    &(*expr).base.base.location,
                    format_args!("Exceeded closure limit"),
                );
            }
        }
        self.captures.clear();
        for uv in upvals {
            let reg = self.get_local_reg(uv);
            if reg >= 0 {
                let ul = self.variables.find(&uv);
                let immutable = ul.map_or(true, |ul| !ul.written);
                self.captures.push(crate::records::capture::Capture {
                    r#type: if immutable {
                        LuauCaptureType::LCT_VAL
                    } else {
                        LuauCaptureType::LCT_REF
                    },
                    data: reg as u8,
                });
            } else if let Some(uc) = self.locstants.find(&uv).copied() {
                let reg = self.alloc_reg(expr as *mut _, 1);
                self.compile_expr_constant(expr as *mut _, &uc, reg);
                self.captures.push(crate::records::capture::Capture {
                    r#type: LuauCaptureType::LCT_VAL,
                    data: reg,
                });
            } else {
                let uid = self.get_upval(uv);
                self.captures.push(crate::records::capture::Capture {
                    r#type: LuauCaptureType::LCT_UPVAL,
                    data: uid,
                });
            }
        }
        let mut shared = -1i16;
        if self.options.optimization_level >= 1
            && self.should_share_closure(expr)
            && !self.setfenv_used
        {
            let cid = unsafe { (*self.bytecode).add_constant_closure(fid) };
            if cid >= 0 && cid < 32768 {
                shared = cid as i16;
            }
        }
        unsafe {
            if shared >= 0 {
                (*self.bytecode).emit_ad(LuauOpcode::LOP_DUPCLOSURE, target, shared);
            } else {
                (*self.bytecode).emit_ad(LuauOpcode::LOP_NEWCLOSURE, target, pid);
            }
            for c in &self.captures {
                (*self.bytecode).emit_abc(LuauOpcode::LOP_CAPTURE, c.r#type as u8, c.data, 0);
            }
        }
    }
}