1#![allow(clippy::cargo_common_metadata)]
2
3use mlua::prelude::*;
4
5use lune_utils::{TableBuilder, jit::JitEnablement};
6
7mod options;
8
9use self::options::{LuauCompileOptions, LuauLoadOptions};
10
11const TYPEDEFS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/types.d.luau"));
12
13#[must_use]
17pub fn typedefs() -> String {
18 TYPEDEFS.to_string()
19}
20
21pub fn module(lua: Lua) -> LuaResult<LuaTable> {
29 TableBuilder::new(lua)?
30 .with_function("compile", compile_source)?
31 .with_function("load", load_source)?
32 .build_readonly()
33}
34
35fn compile_source(
36 lua: &Lua,
37 (source, options): (LuaString, LuauCompileOptions),
38) -> LuaResult<LuaString> {
39 options
40 .into_compiler()
41 .compile(source.as_bytes())
42 .and_then(|s| lua.create_string(s))
43}
44
45fn load_source(
46 lua: &Lua,
47 (source, options): (LuaString, LuauLoadOptions),
48) -> LuaResult<LuaFunction> {
49 let mut chunk = lua
50 .load(source.as_bytes().to_vec())
51 .set_name(options.debug_name);
52 let env_changed = options.environment.is_some();
53
54 if let Some(custom_environment) = options.environment {
55 let environment = lua.create_table()?;
56
57 if options.inject_globals {
59 for pair in lua.globals().pairs() {
60 let (key, value): (LuaValue, LuaValue) = pair?;
61 environment.set(key, value)?;
62 }
63
64 if let Some(global_metatable) = lua.globals().metatable() {
65 environment.set_metatable(Some(global_metatable))?;
66 }
67 } else if let Some(custom_metatable) = custom_environment.metatable() {
68 environment.set_metatable(Some(custom_metatable))?;
71 }
72
73 for pair in custom_environment.pairs() {
75 let (key, value): (LuaValue, LuaValue) = pair?;
76 environment.set(key, value)?;
77 }
78
79 chunk = chunk.set_environment(environment);
80 }
81
82 lua.enable_jit(options.codegen_enabled && !env_changed);
85 let function = chunk.into_function()?;
86 lua.enable_jit(
87 lua.app_data_ref::<JitEnablement>()
88 .ok_or(LuaError::runtime(
89 "Failed to get current JitStatus ref from AppData",
90 ))?
91 .enabled(),
92 );
93
94 Ok(function)
95}