diff --git a/CLI/Repl.cpp b/CLI/Repl.cpp index 83060f5b..ab66d1df 100644 --- a/CLI/Repl.cpp +++ b/CLI/Repl.cpp @@ -225,6 +225,10 @@ std::string runCode(lua_State* L, const std::string& source) lua_pcall(T, n, 0, 0); } } + else if (status == LUA_SIGINT) + { + fputs("\nExecution interrupted\n", stdout); + } else { std::string error; diff --git a/VM/include/lua.h b/VM/include/lua.h index 7f9647c8..ad07ca75 100644 --- a/VM/include/lua.h +++ b/VM/include/lua.h @@ -33,6 +33,7 @@ enum lua_Status LUA_ERRMEM, LUA_ERRERR, LUA_BREAK, /* yielded for a debug breakpoint */ + LUA_SIGINT, /* thread stopped after receiving a SIGINT */ }; typedef struct lua_State lua_State; diff --git a/VM/src/ldo.cpp b/VM/src/ldo.cpp index 0642cb6d..cb1eb005 100644 --- a/VM/src/ldo.cpp +++ b/VM/src/ldo.cpp @@ -290,6 +290,9 @@ static void resume_continue(lua_State* L) Closure* cl = curr_func(L); + if (L->status == LUA_SIGINT) + break; + if (cl->isC) { LUAU_ASSERT(cl->c.cont); diff --git a/VM/src/lvmexecute.cpp b/VM/src/lvmexecute.cpp index e0a96474..15e4f5a5 100644 --- a/VM/src/lvmexecute.cpp +++ b/VM/src/lvmexecute.cpp @@ -13,6 +13,7 @@ #include "lbuiltins.h" #include "lnumutils.h" #include "lbytecode.h" +#include #include @@ -124,13 +125,24 @@ * 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: -#define VM_NEXT() goto*(SingleStep ? &&dispatch : kDispatchTable[LUAU_INSN_OP(*pc)]) + +#define VM_NEXT() \ + if (sigint_received)\ + { sigint_received = 0; L->status = LUA_SIGINT; goto exit; } \ + else goto*(SingleStep ? &&dispatch : kDispatchTable[LUAU_INSN_OP(*pc)]) #define VM_CONTINUE(op) goto* kDispatchTable[uint8_t(op)] #else #define VM_CASE(op) case op: -#define VM_NEXT() goto dispatch +#define VM_NEXT() \ + if (sigint_received)\ + { sigint_received = 0; } \ + else goto dispatch #define VM_CONTINUE(op) \ dispatchOp = uint8_t(op); \ goto dispatchContinue @@ -320,6 +332,8 @@ 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" {