Windows Ctrl-C working.
This commit is contained in:
@ -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
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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 ;
|
||||||
|
|||||||
@ -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 + @ ,
|
||||||
|
|||||||
Reference in New Issue
Block a user