Skip to main content

luaur_repl_cli/functions/
run_repl.rs

1use core::sync::atomic::Ordering;
2
3use luaur_vm::functions::lua_close::lua_close;
4use luaur_vm::functions::lua_l_newstate::lua_l_newstate;
5use luaur_vm::functions::lua_l_sandboxthread::lua_l_sandboxthread;
6use luaur_vm::type_aliases::lua_state::lua_State;
7
8use crate::functions::run_repl_impl::run_repl_impl;
9use crate::functions::setup_state::setup_state;
10use crate::functions::sigint_callback::REPL_STATE;
11
12// Faithful port of `runRepl` from Repl.cpp: create a fresh state, set it up,
13// arm Ctrl-C handling, sandbox the thread and run the interactive loop.
14pub unsafe fn run_repl() {
15    let global_state = lua_l_newstate();
16    let l: *mut lua_State = global_state;
17
18    setup_state(l);
19
20    // setup Ctrl+C handling: replState = L; signal(SIGINT, sigintHandler);
21    REPL_STATE.store(l, Ordering::SeqCst);
22    install_sigint_handler();
23
24    lua_l_sandboxthread(l);
25    run_repl_impl(l);
26
27    // C++ wraps the state in a unique_ptr<lua_State, lua_close>; close it here.
28    REPL_STATE.store(core::ptr::null_mut(), Ordering::SeqCst);
29    lua_close(global_state);
30}
31
32#[cfg(not(target_os = "windows"))]
33unsafe fn install_sigint_handler() {
34    use crate::functions::sigint_handler_repl::sigint_handler;
35
36    // POSIX: signal(SIGINT, sigintHandler)
37    const SIGINT: core::ffi::c_int = 2;
38    extern "C" {
39        fn signal(
40            signum: core::ffi::c_int,
41            handler: unsafe extern "C" fn(core::ffi::c_int),
42        ) -> *mut core::ffi::c_void;
43    }
44    signal(SIGINT, sigint_handler);
45}
46
47#[cfg(target_os = "windows")]
48unsafe fn install_sigint_handler() {
49    use crate::functions::sigint_handler_repl_alt_b::sigint_handler;
50
51    // Windows: SetConsoleCtrlHandler(sigintHandler, TRUE)
52    extern "system" {
53        fn SetConsoleCtrlHandler(
54            handler: Option<unsafe extern "C" fn(u32) -> core::ffi::c_int>,
55            add: core::ffi::c_int,
56        ) -> core::ffi::c_int;
57    }
58    SetConsoleCtrlHandler(Some(sigint_handler), 1);
59}