luaur-compiler 0.1.3

Luau source-to-bytecode compiler (Rust).
Documentation
use crate::enums::type_constant_folding::Type;
use crate::functions::fold_constants::fold_constants;
use crate::functions::model_cost_cost_model::model_cost_ast_node_ast_local_usize_dense_hash_map_ast_expr_call_i32_dense_hash_map_ast_expr_constant;
use crate::functions::undo_changes_constant_folding::undo_changes_dense_hash_map_ast_expr_constant_expr_constant_change_log;
use crate::functions::undo_changes_constant_folding_alt_b::undo_changes_dense_hash_map_ast_local_constant_local_constant_change_log;
use crate::records::compiler::Compiler;
use crate::records::constant::{Constant, ConstantData};
use luaur_ast::records::ast_expr_call::AstExprCall;
use luaur_ast::records::ast_expr_function::AstExprFunction;
use luaur_ast::records::ast_node::AstNode;

impl Compiler {
    pub fn cost_model_inlined_call(
        &mut self,
        expr: *mut AstExprCall,
        func: *mut AstExprFunction,
    ) -> u64 {
        unsafe {
            let func_ref = &*func;
            let expr_ref = &*expr;

            for i in 0..func_ref.args.size {
                let var = *func_ref.args.data.add(i);
                let arg = if i < expr_ref.args.size {
                    *expr_ref.args.data.add(i)
                } else {
                    core::ptr::null_mut()
                };

                if i + 1 == expr_ref.args.size
                    && func_ref.args.size > expr_ref.args.size
                    && self.is_expr_mult_ret(arg)
                {
                    break;
                }

                if self.variables.find(&var).map_or(false, |vv| vv.written) {
                    continue;
                }

                if arg.is_null() {
                    *self.locstants.get_or_insert(var) = Constant {
                        r#type: Type::Type_Nil,
                        string_length: 0,
                        data: ConstantData::default(),
                    };
                } else if let Some(cv) = self.constants.find(&arg) {
                    if cv.r#type != Type::Type_Unknown {
                        *self.locstants.get_or_insert(var) = *cv;
                    }
                }
            }

            let record_changes = luaur_common::FFlag::LuauCompilePropagateTableProps2.get()
                && luaur_common::FFlag::LuauCompileFoldOptimize.get();

            if record_changes {
                self.expr_changes.clear();
                self.local_changes.clear();
            }

            fold_constants(
                &mut self.constants,
                &mut self.variables,
                &mut self.locstants,
                self.builtins_fold,
                self.builtins_fold_library_k,
                self.options.library_member_constant_cb,
                func_ref.body as *mut AstNode,
                &mut *self.names,
                &self.table_constants,
                if record_changes {
                    &mut self.expr_changes as *mut _
                } else {
                    core::ptr::null_mut()
                },
                if record_changes {
                    &mut self.local_changes as *mut _
                } else {
                    core::ptr::null_mut()
                },
            );

            let cost = model_cost_ast_node_ast_local_usize_dense_hash_map_ast_expr_call_i32_dense_hash_map_ast_expr_constant(
                func_ref.body as *mut AstNode,
                func_ref.args.data as *const _,
                func_ref.args.size,
                &self.builtins,
                &self.constants,
            );

            for i in 0..func_ref.args.size {
                let arg = *func_ref.args.data.add(i);
                if let Some(var) = self.locstants.find_mut(&arg) {
                    var.r#type = Type::Type_Unknown;
                }
            }

            if record_changes {
                undo_changes_dense_hash_map_ast_expr_constant_expr_constant_change_log(
                    &mut self.constants,
                    &self.expr_changes,
                );
                undo_changes_dense_hash_map_ast_local_constant_local_constant_change_log(
                    &mut self.locstants,
                    &self.local_changes,
                );
            } else {
                fold_constants(
                    &mut self.constants,
                    &mut self.variables,
                    &mut self.locstants,
                    self.builtins_fold,
                    self.builtins_fold_library_k,
                    self.options.library_member_constant_cb,
                    func_ref.body as *mut AstNode,
                    &mut *self.names,
                    &self.table_constants,
                    core::ptr::null_mut(),
                    core::ptr::null_mut(),
                );
            }

            cost
        }
    }
}