Switch to using interrupt handler

This commit is contained in:
Jay Kruer 2022-06-15 17:55:12 -07:00
parent 2578a9a342
commit 278fb91287
4 changed files with 37 additions and 12 deletions

View file

@ -21,6 +21,10 @@
#include <fcntl.h>
#endif
#ifndef _WIN32
#include <csignal>
#endif
#include <locale.h>
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<lua_State, void (*)(lua_State*)> 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);
}

View file

@ -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)

View file

@ -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);

View file

@ -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"
{