luaur-compiler 0.1.2

Luau source-to-bytecode compiler (Rust).
Documentation
use crate::enums::global::Global;
use crate::functions::get_builtin_function_id::get_builtin_function_id;
use crate::functions::get_global_state::get_global_state;
use crate::records::builtin::Builtin;
use crate::records::builtin_visitor::BuiltinVisitor;
use crate::records::compile_options::CompileOptions;
use crate::records::variable::Variable;
use luaur_ast::records::ast_expr_call::AstExprCall;
use luaur_ast::records::ast_local::AstLocal;
use luaur_ast::records::ast_name::AstName;
use luaur_ast::records::ast_name_table::AstNameTable;
use luaur_common::records::dense_hash_map::DenseHashMap;

use core::ffi::CStr;
use core::ptr;

fn find_dot(ptr: *const core::ffi::c_char) -> *const core::ffi::c_char {
    unsafe {
        if ptr.is_null() {
            return ptr::null();
        }
        let mut p = ptr;
        loop {
            let c = *p;
            if c == 0 {
                return ptr::null();
            }
            if c == b'.' as core::ffi::c_char {
                return p;
            }
            p = p.add(1);
        }
    }
}

fn c_str_len(ptr: *const core::ffi::c_char) -> usize {
    unsafe {
        if ptr.is_null() {
            return 0;
        }
        let bytes = CStr::from_ptr(ptr).to_bytes();
        bytes.len()
    }
}

impl BuiltinVisitor {
    pub fn new(
        result: &mut DenseHashMap<*mut AstExprCall, i32>,
        globals: &DenseHashMap<AstName, Global>,
        variables: &DenseHashMap<*mut AstLocal, Variable>,
        options: &CompileOptions,
        names: &AstNameTable,
    ) -> Self {
        let mut builtin_is_disabled = [false; 256];

        let disabled_builtins = options.disabled_builtins;
        if !disabled_builtins.is_null() {
            unsafe {
                let mut ptr = disabled_builtins;
                while !(*ptr).is_null() {
                    let current = *ptr;
                    let dot = find_dot(current);

                    if !dot.is_null() {
                        let library_len = (dot as usize) - (current as usize);
                        let (library, _) = names.get_with_type(current, library_len);
                        let name_ptr = dot.add(1);
                        let name = names.get(name_ptr);

                        if !library.value.is_null()
                            && !name.value.is_null()
                            && get_global_state(globals, name) == Global::Default
                        {
                            let builtin = Builtin {
                                object: library,
                                method: name,
                            };

                            let bfid = get_builtin_function_id(&builtin, options);
                            if bfid >= 0 && (bfid as usize) < 256 {
                                builtin_is_disabled[bfid as usize] = true;
                            }
                        }
                    } else {
                        let name = names.get(current);
                        if !name.value.is_null()
                            && get_global_state(globals, name) == Global::Default
                        {
                            let builtin = Builtin {
                                object: AstName::new(),
                                method: name,
                            };

                            let bfid = get_builtin_function_id(&builtin, options);
                            if bfid >= 0 && (bfid as usize) < 256 {
                                builtin_is_disabled[bfid as usize] = true;
                            }
                        }
                    }
                    ptr = ptr.add(1);
                }
            }
        }

        let mut visitor = Self::builtin_visitor(result, globals, variables, options, names);
        visitor.builtin_is_disabled = builtin_is_disabled;
        visitor
    }
}

#[allow(non_snake_case)]
pub fn builtin_visitor_builtin_visitor(
    result: &mut DenseHashMap<*mut AstExprCall, i32>,
    globals: &DenseHashMap<AstName, Global>,
    variables: &DenseHashMap<*mut AstLocal, Variable>,
    options: &CompileOptions,
    names: &AstNameTable,
) -> BuiltinVisitor {
    BuiltinVisitor::new(result, globals, variables, options, names)
}