luaur_compiler/methods/
compiler_cost_model_inlined_call.rs1use 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}