Windows Ctrl-C working.

This commit is contained in:
Brad Nelson
2023-01-14 17:38:58 -08:00
parent fc6c771d86
commit 3dcd421576
5 changed files with 59 additions and 17 deletions

View File

@ -553,9 +553,6 @@ e: test-windows-forth-namespace
out: ms out: ms
out: windows out: windows
check-phase1 check-phase1
out: GetProcAddress
out: LoadLibraryA
out: WindowProcShim
check-opcodes check-opcodes
out: forth-builtins out: forth-builtins
;e ;e

View File

@ -25,15 +25,6 @@ enum {
#undef Z #undef Z
}; };
static BOOL WINAPI forth_ctrl_handler(DWORD fdwCtrlType) {
if (fdwCtrlType == CTRL_C_EVENT ||
fdwCtrlType == CTRL_BREAK_EVENT) {
// RaiseException(EXCEPTION_BREAKPOINT, 0, 0, 0);
return TRUE;
}
return FALSE;
}
static cell_t *forth_run(cell_t *init_rp) { static cell_t *forth_run(cell_t *init_rp) {
static const BUILTIN_WORD builtins[] = { static const BUILTIN_WORD builtins[] = {
#define Z(flags, name, op, code) \ #define Z(flags, name, op, code) \
@ -54,7 +45,6 @@ static cell_t *forth_run(cell_t *init_rp) {
} }
register cell_t *ip, *rp, *sp, tos, w; register cell_t *ip, *rp, *sp, tos, w;
register float *fp, ft; register float *fp, ft;
SetConsoleCtrlHandler(forth_ctrl_handler, TRUE);
rp = init_rp; UNPARK; rp = init_rp; UNPARK;
for (;;) { for (;;) {
__try { __try {

View File

@ -38,16 +38,18 @@
#define STACK_CELLS (8 * 1024) #define STACK_CELLS (8 * 1024)
static LRESULT WindowProcShim(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); static LRESULT WindowProcShim(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static void SetupCtrlBreakHandler(void);
#define PLATFORM_OPCODE_LIST \ #define PLATFORM_OPCODE_LIST \
Y(GetProcAddress, \ YV(windows, GetProcAddress, \
tos = (cell_t) GetProcAddress((HMODULE) *sp, (LPCSTR) tos); --sp) \ tos = (cell_t) GetProcAddress((HMODULE) *sp, (LPCSTR) tos); --sp) \
Y(LoadLibraryA, tos = (cell_t) LoadLibraryA((LPCSTR) tos)) \ YV(windows, LoadLibraryA, tos = (cell_t) LoadLibraryA((LPCSTR) tos)) \
Y(WindowProcShim, DUP; tos = (cell_t) &WindowProcShim) \ YV(windows, WindowProcShim, DUP; tos = (cell_t) &WindowProcShim) \
YV(windows, SetupCtrlBreakHandler, SetupCtrlBreakHandler()) \
CALLING_OPCODE_LIST \ CALLING_OPCODE_LIST \
FLOATING_POINT_LIST FLOATING_POINT_LIST
#define VOCABULARY_LIST V(forth) V(internals) #define VOCABULARY_LIST V(forth) V(internals) V(windows)
#include "common/bits.h" #include "common/bits.h"
#include "common/core.h" #include "common/core.h"
@ -55,6 +57,57 @@ static LRESULT WindowProcShim(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
#include "gen/windows_boot.h" #include "gen/windows_boot.h"
static DWORD forth_main_thread_id;
static uintptr_t forth_main_thread_resume_sp;
static uintptr_t forth_main_thread_resume_bp;
static BOOL WINAPI forth_ctrl_handler(DWORD fdwCtrlType) {
HANDLE main_thread;
CONTEXT context = { 0 };
if (fdwCtrlType == CTRL_C_EVENT ||
fdwCtrlType == CTRL_BREAK_EVENT) {
// Using explicit instead of THREAD_ALL_ACCESS to be explicit as per docs.
// THREAD_QUERY_INFORMATION seems to be required for reasons unknown on x64.
main_thread = OpenThread(THREAD_QUERY_INFORMATION |
THREAD_SET_CONTEXT |
THREAD_GET_CONTEXT |
THREAD_SUSPEND_RESUME, FALSE, forth_main_thread_id);
SuspendThread(main_thread);
context.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(main_thread, &context);
#ifdef _WIN64
context.Rip = 0;
context.Rsp = forth_main_thread_resume_sp;
context.Rbp = forth_main_thread_resume_bp;
#else
context.Eip = 0;
context.Esp = forth_main_thread_resume_sp;
context.Ebp = forth_main_thread_resume_bp;
#endif
SetThreadContext(main_thread, &context);
ResumeThread(main_thread);
CloseHandle(main_thread);
return TRUE;
}
return FALSE;
}
static void SetupCtrlBreakHandler(void) {
forth_main_thread_id = GetCurrentThreadId();
SetConsoleCtrlHandler(forth_ctrl_handler, TRUE);
CONTEXT context = { 0 };
context.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(GetCurrentThread(), &context);
#ifdef _WIN64
forth_main_thread_resume_sp = context.Rsp;
forth_main_thread_resume_bp = context.Rbp;
#else
forth_main_thread_resume_sp = context.Esp;
forth_main_thread_resume_bp = context.Ebp;
#endif
}
static LRESULT WindowProcShim(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static LRESULT WindowProcShim(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (msg == WM_NCCREATE) { if (msg == WM_NCCREATE) {
SetWindowLongPtr( SetWindowLongPtr(

View File

@ -58,6 +58,7 @@ variable console-mode
ENABLE_WINDOW_INPUT or invert and SetConsoleMode drop ENABLE_WINDOW_INPUT or invert and SetConsoleMode drop
stdout console-mode GetConsoleMode drop stdout console-mode GetConsoleMode drop
stdout console-mode @ ENABLE_VIRTUAL_TERMINAL_PROCESSING or SetConsoleMode drop stdout console-mode @ ENABLE_VIRTUAL_TERMINAL_PROCESSING or SetConsoleMode drop
SetupCtrlBreakHandler
; ;
: win-type ( a n -- ) init-console stdout -rot NULL NULL WriteFile drop ; : win-type ( a n -- ) init-console stdout -rot NULL NULL WriteFile drop ;

View File

@ -21,6 +21,7 @@ internals
' call5 , ' call6 , ' call7 , ' call8 , ' call9 , ' call5 , ' call6 , ' call7 , ' call8 , ' call9 ,
' call10 , ' call11 , ' call12 , ' call13 , ' call14 , ' call15 , ' call10 , ' call11 , ' call12 , ' call13 , ' call14 , ' call15 ,
windows windows
transfer windows-builtins
: sofunc ( z n a "name" -- ) : sofunc ( z n a "name" -- )
>r dup 15 > throw r> ( Check there aren't too many args ) >r dup 15 > throw r> ( Check there aren't too many args )
swap >r swap GetProcAddress dup 0= throw create , r> cells calls + @ , swap >r swap GetProcAddress dup 0= throw create , r> cells calls + @ ,