Add Ctrl-C handling to the REPL

This commit is contained in:
Jay Kruer 2022-06-12 14:33:59 -07:00
parent b066e4c8f8
commit 58c5c601aa
4 changed files with 24 additions and 2 deletions

View file

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

View file

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

View file

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

View file

@ -13,6 +13,7 @@
#include "lbuiltins.h"
#include "lnumutils.h"
#include "lbytecode.h"
#include <csignal>
#include <string.h>
@ -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"
{