diff --git a/CLI/Repl.cpp b/CLI/Repl.cpp index ab66d1df..7e0c059b 100644 --- a/CLI/Repl.cpp +++ b/CLI/Repl.cpp @@ -21,6 +21,10 @@ #include #endif +#ifndef _WIN32 +#include +#endif + #include LUAU_FASTFLAG(DebugLuauTimeTracing) @@ -42,6 +46,12 @@ enum class CompileFormat constexpr int MaxTraversalLimit = 50; +// Ctrl-C handling +volatile sig_atomic_t sigint_received = 0; +static void handle_sig(int signum) { + sigint_received = 1; +} + struct GlobalOptions { int optimizationLevel = 1; @@ -489,12 +499,27 @@ static void runReplImpl(lua_State* L) } } +void ihandler(lua_State* L, int k) { + if (sigint_received) { + // when VM_INTERRUPT sees that the status is non-zero it will + // exit the interpreter loop + lua_setstatus(L,LUA_SIGINT); + } +}; + static void runRepl() { std::unique_ptr globalState(luaL_newstate(), lua_close); lua_State* L = globalState.get(); setupState(L); + + // FIXME: add corresponding windows functionality + #ifndef _WIN32 + signal(SIGINT, handle_sig); + lua_setinterrupt(L, &ihandler); + #endif + luaL_sandboxthread(L); runReplImpl(L); } diff --git a/VM/include/lua.h b/VM/include/lua.h index ad07ca75..eb0be8df 100644 --- a/VM/include/lua.h +++ b/VM/include/lua.h @@ -206,6 +206,8 @@ LUA_API void lua_rawset(lua_State* L, int idx); LUA_API void lua_rawseti(lua_State* L, int idx, int n); LUA_API int lua_setmetatable(lua_State* L, int objindex); LUA_API int lua_setfenv(lua_State* L, int idx); +LUA_API void lua_setstatus(lua_State* L, int status); +LUA_API void lua_setinterrupt(lua_State* L, void (*interrupt)(lua_State* Lp, int k)); /* ** `load' and `call' functions (load and run Luau bytecode) diff --git a/VM/src/lapi.cpp b/VM/src/lapi.cpp index 3c3b7bd0..fd8646b3 100644 --- a/VM/src/lapi.cpp +++ b/VM/src/lapi.cpp @@ -811,6 +811,16 @@ void lua_getfenv(lua_State* L, int idx) ** set functions (stack -> Lua) */ +void lua_setstatus(lua_State* L, int status) { + L->status = status; + return; +} + +void lua_setinterrupt(lua_State* L, void (*interrupt)(lua_State* Lp, int k)) { + L->global->cb.interrupt = interrupt; + return; +} + void lua_settable(lua_State* L, int idx) { api_checknelems(L, 2); diff --git a/VM/src/lvmexecute.cpp b/VM/src/lvmexecute.cpp index a8797d5d..40e63717 100644 --- a/VM/src/lvmexecute.cpp +++ b/VM/src/lvmexecute.cpp @@ -74,12 +74,6 @@ #else #define VM_INTERRUPT() \ { \ - if (sigint_received)\ - { \ - sigint_received = 0; \ - L->status = LUA_SIGINT; \ - goto exit; \ - } \ void (*interrupt)(lua_State*, int) = L->global->cb.interrupt; \ if (LUAU_UNLIKELY(!!interrupt)) \ { /* the interrupt hook is called right before we advance pc */ \ @@ -131,10 +125,6 @@ * VM_CONTINUE() Use an opcode override to dispatch with computed goto or * switch statement to skip a LOP_BREAK instruction. */ -volatile sig_atomic_t sigint_received = 0; -static void handle_sig(int signum) { - sigint_received = 1; -} #if VM_USE_CGOTO #define VM_CASE(op) CASE_##op: @@ -332,8 +322,6 @@ static void luau_execute(lua_State* L) base = L->base; k = cl->l.p->k; - signal(SIGINT, handle_sig); - VM_NEXT(); // starts the interpreter "loop" {