Skip to main content

luaur_compiler/methods/
compiler_should_share_closure.rs

1use crate::records::compiler::Compiler;
2use luaur_ast::records::ast_expr_function::AstExprFunction;
3use luaur_ast::records::ast_node::AstNode;
4
5impl Compiler {
6    pub fn should_share_closure(&mut self, func: *mut AstExprFunction) -> bool {
7        let f = match self.functions.find(&func) {
8            Some(f) => f,
9            None => return false,
10        };
11
12        let upvals = f.upvals.clone();
13
14        for uv in upvals {
15            let ul = match self.variables.find(&uv) {
16                Some(ul) => *ul,
17                None => return false,
18            };
19
20            if ul.written {
21                return false;
22            }
23
24            unsafe {
25                if (*uv).function_depth != 0 || (*uv).loop_depth != 0 {
26                    let uf = if !ul.init.is_null() {
27                        luaur_ast::rtti::ast_node_as::<AstExprFunction>(ul.init as *mut AstNode)
28                    } else {
29                        core::ptr::null_mut()
30                    };
31
32                    if uf.is_null() {
33                        return false;
34                    }
35
36                    if uf != func && !self.should_share_closure(uf) {
37                        return false;
38                    }
39                }
40            }
41        }
42
43        true
44    }
45}