Skip to main content

luaur_cli_lib/functions/
set_luau_flags_default.rs

1use core::sync::atomic::Ordering;
2use luaur_common::functions::is_analysis_flag_experimental::isAnalysisFlagExperimental;
3use luaur_common::records::f_value::{FValue, FValueList};
4
5pub fn set_luau_flags_default() {
6    let mut flag_ptr = <bool as FValueList>::head().load(Ordering::Relaxed);
7
8    while !flag_ptr.is_null() {
9        let flag = unsafe { &*flag_ptr };
10
11        // The FValue fields 'name' and 'next' are pub(crate) in luau-common, so they are private to luau-cli-lib.
12        // However, the FValue struct is a #[repr(C)] struct. We can access the fields by casting to a local
13        // shadow struct with the same layout or by using pointer offsets.
14        // Given the FValue definition: { value: UnsafeCell<T>, dynamic: bool, name: *const c_char, next: UnsafeCell<*const FValue<T>>, ... }
15        #[repr(C)]
16        struct FValueLayout<T> {
17            value: core::cell::UnsafeCell<T>,
18            dynamic: bool,
19            name: *const core::ffi::c_char,
20            next: core::cell::UnsafeCell<*const FValue<T>>,
21        }
22
23        let layout = unsafe { &*(flag_ptr as *const FValueLayout<bool>) };
24        let name_ptr = layout.name;
25
26        if !name_ptr.is_null() {
27            let name_cstr = unsafe { core::ffi::CStr::from_ptr(name_ptr) };
28            let name_bytes = name_cstr.to_bytes();
29
30            if name_bytes.starts_with(b"Luau") && !isAnalysisFlagExperimental(name_ptr) {
31                flag.set(true);
32            }
33        }
34
35        flag_ptr = unsafe { *layout.next.get() as *mut FValue<bool> };
36    }
37}