Skip to main content

luaur_compiler/methods/
compiler_get_upval.rs

1use crate::records::compile_error::CompileError;
2use crate::records::compiler::Compiler;
3use luaur_ast::records::ast_local::AstLocal;
4
5const K_MAX_UPVALUE_COUNT: usize = 200;
6
7impl Compiler {
8    pub fn get_upval(&mut self, local: *mut AstLocal) -> u8 {
9        for (uid, &upval) in self.upvals.iter().enumerate() {
10            if upval == local {
11                return uid as u8;
12            }
13        }
14
15        if self.upvals.len() >= K_MAX_UPVALUE_COUNT {
16            let local_ref = unsafe { &*local };
17            let name = unsafe { core::ffi::CStr::from_ptr(local_ref.name.value) }.to_string_lossy();
18            CompileError::raise(
19                &local_ref.location,
20                format_args!(
21                    "Out of upvalue registers when trying to allocate {}: exceeded limit {}",
22                    name, K_MAX_UPVALUE_COUNT
23                ),
24            );
25        }
26
27        if self.variables.find(&local).map_or(false, |v| v.written) {
28            self.locals.get_or_insert(local).captured = true;
29        }
30
31        self.upvals.push(local);
32        (self.upvals.len() - 1) as u8
33    }
34}