Skip to main content

luaur_repl_cli/functions/
lua_loadstring.rs

1use alloc::string::String;
2use core::ffi::c_char;
3
4use luaur_ast::records::parse_options::ParseOptions;
5use luaur_bytecode::records::bytecode_encoder::BytecodeEncoder;
6use luaur_compiler::functions::compile::compile;
7use luaur_vm::functions::lua_insert::lua_insert;
8use luaur_vm::functions::lua_l_checklstring::lua_l_checklstring;
9use luaur_vm::functions::lua_l_optlstring::lua_l_optlstring;
10use luaur_vm::functions::lua_pushnil::lua_pushnil;
11use luaur_vm::functions::lua_setsafeenv::lua_setsafeenv;
12use luaur_vm::functions::luau_load::luau_load;
13use luaur_vm::macros::lua_environindex::LUA_ENVIRONINDEX;
14use luaur_vm::type_aliases::lua_state::lua_State;
15
16use crate::functions::copts::copts;
17
18pub unsafe fn lua_loadstring(l: *mut lua_State) -> i32 {
19    let mut len: usize = 0;
20    let s = lua_l_checklstring(l, 1, &mut len as *mut usize);
21    let chunkname = lua_l_optlstring(l, 2, s, core::ptr::null_mut());
22
23    lua_setsafeenv(l, LUA_ENVIRONINDEX, false as core::ffi::c_int);
24
25    let source_bytes = core::slice::from_raw_parts(s as *const u8, len);
26    let source: String = core::str::from_utf8_unchecked(source_bytes).into();
27
28    struct NoopEncoder;
29    impl BytecodeEncoder for NoopEncoder {
30        fn encode(&mut self, _data: &mut [u32]) {}
31    }
32    let options = copts();
33    let parse_options = ParseOptions::default();
34    let mut encoder = NoopEncoder;
35    let bytecode = compile(
36        &source,
37        &options,
38        &parse_options,
39        &mut encoder as *mut dyn BytecodeEncoder,
40    );
41
42    if luau_load(
43        l,
44        chunkname,
45        bytecode.as_ptr() as *const c_char,
46        bytecode.len(),
47        0,
48    ) == 0
49    {
50        return 1;
51    }
52
53    lua_pushnil(l);
54    lua_insert(l, -2); // put before error message
55    2 // return nil plus error message
56}