Skip to main content

luaur_compiler/methods/
compiler_cost_model_inlined_call.rs

1use crate::enums::type_constant_folding::Type;
2use crate::functions::fold_constants::fold_constants;
3use 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;
4use crate::functions::undo_changes_constant_folding::undo_changes_dense_hash_map_ast_expr_constant_expr_constant_change_log;
5use crate::functions::undo_changes_constant_folding_alt_b::undo_changes_dense_hash_map_ast_local_constant_local_constant_change_log;
6use crate::records::compiler::Compiler;
7use crate::records::constant::{Constant, ConstantData};
8use luaur_ast::records::ast_expr_call::AstExprCall;
9use luaur_ast::records::ast_expr_function::AstExprFunction;
10use luaur_ast::records::ast_node::AstNode;
11
12impl Compiler {
13    pub fn cost_model_inlined_call(
14        &mut self,
15        expr: *mut AstExprCall,
16        func: *mut AstExprFunction,
17    ) -> u64 {
18        unsafe {
19            let func_ref = &*func;
20            let expr_ref = &*expr;
21
22            for i in 0..func_ref.args.size {
23                let var = *func_ref.args.data.add(i);
24                let arg = if i < expr_ref.args.size {
25                    *expr_ref.args.data.add(i)
26                } else {
27                    core::ptr::null_mut()
28                };
29
30                if i + 1 == expr_ref.args.size
31                    && func_ref.args.size > expr_ref.args.size
32                    && self.is_expr_mult_ret(arg)
33                {
34                    break;
35                }
36
37                if self.variables.find(&var).map_or(false, |vv| vv.written) {
38                    continue;
39                }
40
41                if arg.is_null() {
42                    *self.locstants.get_or_insert(var) = Constant {
43                        r#type: Type::Type_Nil,
44                        string_length: 0,
45                        data: ConstantData::default(),
46                    };
47                } else if let Some(cv) = self.constants.find(&arg) {
48                    if cv.r#type != Type::Type_Unknown {
49                        *self.locstants.get_or_insert(var) = *cv;
50                    }
51                }
52            }
53
54            let record_changes = luaur_common::FFlag::LuauCompilePropagateTableProps2.get()
55                && luaur_common::FFlag::LuauCompileFoldOptimize.get();
56
57            if record_changes {
58                self.expr_changes.clear();
59                self.local_changes.clear();
60            }
61
62            fold_constants(
63                &mut self.constants,
64                &mut self.variables,
65                &mut self.locstants,
66                self.builtins_fold,
67                self.builtins_fold_library_k,
68                self.options.library_member_constant_cb,
69                func_ref.body as *mut AstNode,
70                &mut *self.names,
71                &self.table_constants,
72                if record_changes {
73                    &mut self.expr_changes as *mut _
74                } else {
75                    core::ptr::null_mut()
76                },
77                if record_changes {
78                    &mut self.local_changes as *mut _
79                } else {
80                    core::ptr::null_mut()
81                },
82            );
83
84            let cost = model_cost_ast_node_ast_local_usize_dense_hash_map_ast_expr_call_i32_dense_hash_map_ast_expr_constant(
85                func_ref.body as *mut AstNode,
86                func_ref.args.data as *const _,
87                func_ref.args.size,
88                &self.builtins,
89                &self.constants,
90            );
91
92            for i in 0..func_ref.args.size {
93                let arg = *func_ref.args.data.add(i);
94                if let Some(var) = self.locstants.find_mut(&arg) {
95                    var.r#type = Type::Type_Unknown;
96                }
97            }
98
99            if record_changes {
100                undo_changes_dense_hash_map_ast_expr_constant_expr_constant_change_log(
101                    &mut self.constants,
102                    &self.expr_changes,
103                );
104                undo_changes_dense_hash_map_ast_local_constant_local_constant_change_log(
105                    &mut self.locstants,
106                    &self.local_changes,
107                );
108            } else {
109                fold_constants(
110                    &mut self.constants,
111                    &mut self.variables,
112                    &mut self.locstants,
113                    self.builtins_fold,
114                    self.builtins_fold_library_k,
115                    self.options.library_member_constant_cb,
116                    func_ref.body as *mut AstNode,
117                    &mut *self.names,
118                    &self.table_constants,
119                    core::ptr::null_mut(),
120                    core::ptr::null_mut(),
121                );
122            }
123
124            cost
125        }
126    }
127}