From 37b15012e6236113d8d09af2f1a5a2225692bc6b Mon Sep 17 00:00:00 2001 From: Erik Charlebois Date: Sat, 11 May 2013 22:24:31 -0400 Subject: [PATCH] VM: Refactor os-* to Factor style --- vm/os-genunix.cpp | 53 +-- vm/os-genunix.hpp | 7 +- vm/os-linux-arm.cpp | 40 +- vm/os-linux-arm.hpp | 15 +- vm/os-linux-ppc.32.hpp | 50 +-- vm/os-linux-ppc.64.hpp | 62 ++- vm/os-linux-x86.32.hpp | 87 ++-- vm/os-linux-x86.64.hpp | 35 +- vm/os-linux.cpp | 31 +- vm/os-linux.hpp | 5 +- vm/os-macosx-x86.32.hpp | 60 ++- vm/os-macosx-x86.64.hpp | 64 ++- vm/os-macosx.hpp | 15 +- vm/os-macosx.mm | 114 +++--- vm/os-unix.cpp | 846 ++++++++++++++++++--------------------- vm/os-unix.hpp | 16 +- vm/os-windows-x86.32.cpp | 10 +- vm/os-windows-x86.64.cpp | 135 ++++--- vm/os-windows.32.hpp | 43 +- vm/os-windows.64.hpp | 3 +- vm/os-windows.cpp | 568 ++++++++++++-------------- vm/os-windows.hpp | 67 ++-- 22 files changed, 1067 insertions(+), 1259 deletions(-) diff --git a/vm/os-genunix.cpp b/vm/os-genunix.cpp index fb5ecf9f50..dc805784ce 100644 --- a/vm/os-genunix.cpp +++ b/vm/os-genunix.cpp @@ -1,47 +1,38 @@ #include "master.hpp" #include -namespace factor -{ +namespace factor { -void factor_vm::c_to_factor_toplevel(cell quot) -{ - c_to_factor(quot); -} +void factor_vm::c_to_factor_toplevel(cell quot) { c_to_factor(quot); } -void factor_vm::init_signals() -{ - unix_init_signals(); -} +void factor_vm::init_signals() { unix_init_signals(); } -void early_init() { } +void early_init() {} #define SUFFIX ".image" #define SUFFIX_LEN 6 /* You must delete[] the result yourself. */ -const char *default_image_path() -{ - const char *path = vm_executable_path(); - - if(!path) - return "factor.image"; - - int len = strlen(path); - char *new_path = new char[PATH_MAX + SUFFIX_LEN + 1]; - memcpy(new_path,path,len + 1); - memcpy(new_path + len,SUFFIX,SUFFIX_LEN + 1); - free(const_cast(path)); - return new_path; +const char* default_image_path() { + const char* path = vm_executable_path(); + + if (!path) + return "factor.image"; + + int len = strlen(path); + char* new_path = new char[PATH_MAX + SUFFIX_LEN + 1]; + memcpy(new_path, path, len + 1); + memcpy(new_path + len, SUFFIX, SUFFIX_LEN + 1); + free(const_cast(path)); + return new_path; } -u64 nano_count() -{ - struct timespec t; - int ret = clock_gettime(CLOCK_MONOTONIC,&t); - if(ret != 0) - fatal_error("clock_gettime failed", 0); - return (u64)t.tv_sec * 1000000000 + t.tv_nsec; +u64 nano_count() { + struct timespec t; + int ret = clock_gettime(CLOCK_MONOTONIC, &t); + if (ret != 0) + fatal_error("clock_gettime failed", 0); + return (u64) t.tv_sec * 1000000000 + t.tv_nsec; } } diff --git a/vm/os-genunix.hpp b/vm/os-genunix.hpp index a40e891a6e..82773a7944 100644 --- a/vm/os-genunix.hpp +++ b/vm/os-genunix.hpp @@ -1,10 +1,9 @@ -namespace factor -{ +namespace factor { #define VM_C_API extern "C" void early_init(); -const char *vm_executable_path(); -const char *default_image_path(); +const char* vm_executable_path(); +const char* default_image_path(); } diff --git a/vm/os-linux-arm.cpp b/vm/os-linux-arm.cpp index 8e131b9011..c2026226ee 100644 --- a/vm/os-linux-arm.cpp +++ b/vm/os-linux-arm.cpp @@ -1,31 +1,27 @@ #include "master.hpp" -namespace factor -{ +namespace factor { -void flush_icache(cell start, cell len) -{ - int result; +void flush_icache(cell start, cell len) { + int result; - /* XXX: why doesn't this work on Nokia n800? It should behave - identically to the below assembly. */ - /* result = syscall(__ARM_NR_cacheflush,start,start + len,0); */ + /* XXX: why doesn't this work on Nokia n800? It should behave + identically to the below assembly. */ + /* result = syscall(__ARM_NR_cacheflush,start,start + len,0); */ - /* Assembly swiped from - http://lists.arm.linux.org.uk/pipermail/linux-arm/2002-July/003931.html - */ - __asm__ __volatile__ ( - "mov r0, %1\n" - "sub r1, %2, #1\n" - "mov r2, #0\n" - "swi " __sys1(__ARM_NR_cacheflush) "\n" - "mov %0, r0\n" - : "=r" (result) - : "r" (start), "r" (start + len) - : "r0","r1","r2"); + /* Assembly swiped from + http://lists.arm.linux.org.uk/pipermail/linux-arm/2002-July/003931.html */ + __asm__ __volatile__("mov r0, %1\n" + "sub r1, %2, #1\n" + "mov r2, #0\n" + "swi " __sys1(__ARM_NR_cacheflush) "\n" + "mov %0, r0\n" + : "=r"(result) + : "r"(start), "r"(start + len) + : "r0", "r1", "r2"); - if(result < 0) - critical_error("flush_icache() failed",result); + if (result < 0) + critical_error("flush_icache() failed", result); } } diff --git a/vm/os-linux-arm.hpp b/vm/os-linux-arm.hpp index d739dfc2f8..7388698961 100644 --- a/vm/os-linux-arm.hpp +++ b/vm/os-linux-arm.hpp @@ -2,18 +2,19 @@ #include #include -namespace factor -{ +namespace factor { void flush_icache(cell start, cell len); -#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.arm_sp) -#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.arm_pc) +#define UAP_STACK_POINTER(ucontext) \ + (((ucontext_t*)ucontext)->uc_mcontext.arm_sp) +#define UAP_PROGRAM_COUNTER(ucontext) \ + (((ucontext_t*)ucontext)->uc_mcontext.arm_pc) #define UAP_STACK_POINTER_TYPE greg_t -#define UAP_SET_TOC_POINTER(uap, ptr) (void)0 +#define UAP_SET_TOC_POINTER(uap, ptr) (void) 0 -#define CODE_TO_FUNCTION_POINTER(code) (void)0 -#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void)0 +#define CODE_TO_FUNCTION_POINTER(code) (void) 0 +#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void) 0 #define FUNCTION_CODE_POINTER(ptr) ptr #define FUNCTION_TOC_POINTER(ptr) ptr } diff --git a/vm/os-linux-ppc.32.hpp b/vm/os-linux-ppc.32.hpp index 7eac07e104..67c1852bda 100644 --- a/vm/os-linux-ppc.32.hpp +++ b/vm/os-linux-ppc.32.hpp @@ -1,39 +1,39 @@ #include -namespace factor -{ +namespace factor { -#define FRAME_RETURN_ADDRESS(frame,vm) *((void **)(vm->frame_successor(frame) + 1) + 1) -#define UAP_STACK_POINTER(ucontext) ((ucontext_t *)ucontext)->uc_mcontext.uc_regs->gregs[1] -#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.uc_regs->gregs[32]) -#define UAP_SET_TOC_POINTER(uap, ptr) (void)0 +#define FRAME_RETURN_ADDRESS(frame, vm) \ + *((void**)(vm->frame_successor(frame) + 1) + 1) +#define UAP_STACK_POINTER(ucontext) \ + ((ucontext_t*)ucontext)->uc_mcontext.uc_regs->gregs[1] +#define UAP_PROGRAM_COUNTER(ucontext) \ + (((ucontext_t*)ucontext)->uc_mcontext.uc_regs->gregs[32]) +#define UAP_SET_TOC_POINTER(uap, ptr) (void) 0 -#define CODE_TO_FUNCTION_POINTER(code) (void)0 -#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void)0 +#define CODE_TO_FUNCTION_POINTER(code) (void) 0 +#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void) 0 #define FUNCTION_CODE_POINTER(ptr) ptr #define FUNCTION_TOC_POINTER(ptr) ptr #define UAP_STACK_POINTER_TYPE unsigned long -inline static unsigned int uap_fpu_status(void *uap) -{ - union { - double as_double; - unsigned int as_uint[2]; - } tmp; - tmp.as_double = ((ucontext_t*) uap)->uc_mcontext.uc_regs->fpregs.fpscr; - return tmp.as_uint[1]; +inline static unsigned int uap_fpu_status(void* uap) { + union { + double as_double; + unsigned int as_uint[2]; + } tmp; + tmp.as_double = ((ucontext_t*)uap)->uc_mcontext.uc_regs->fpregs.fpscr; + return tmp.as_uint[1]; } -inline static void uap_clear_fpu_status(void *uap) -{ - union { - double as_double; - unsigned int as_uint[2]; - } tmp; - tmp.as_double = ((ucontext_t*) uap)->uc_mcontext.uc_regs->fpregs.fpscr; - tmp.as_uint[1] &= 0x0007f8ff; - ((ucontext_t*) uap)->uc_mcontext.uc_regs->fpregs.fpscr = tmp.as_double; +inline static void uap_clear_fpu_status(void* uap) { + union { + double as_double; + unsigned int as_uint[2]; + } tmp; + tmp.as_double = ((ucontext_t*)uap)->uc_mcontext.uc_regs->fpregs.fpscr; + tmp.as_uint[1] &= 0x0007f8ff; + ((ucontext_t*)uap)->uc_mcontext.uc_regs->fpregs.fpscr = tmp.as_double; } } diff --git a/vm/os-linux-ppc.64.hpp b/vm/os-linux-ppc.64.hpp index 9d9360e043..ce016b4524 100644 --- a/vm/os-linux-ppc.64.hpp +++ b/vm/os-linux-ppc.64.hpp @@ -1,50 +1,48 @@ #include -namespace factor -{ +namespace factor { -#define FRAME_RETURN_ADDRESS(frame,vm) *((void **)(vm->frame_successor(frame) + 1) + 2) -#define UAP_STACK_POINTER(ucontext) ((ucontext_t *)ucontext)->uc_mcontext.gp_regs[1] -#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gp_regs[32]) -#define UAP_SET_TOC_POINTER(uap, ptr) (void)0 +#define FRAME_RETURN_ADDRESS(frame, vm) \ + *((void**)(vm->frame_successor(frame) + 1) + 2) +#define UAP_STACK_POINTER(ucontext) \ + ((ucontext_t*)ucontext)->uc_mcontext.gp_regs[1] +#define UAP_PROGRAM_COUNTER(ucontext) \ + (((ucontext_t*)ucontext)->uc_mcontext.gp_regs[32]) +#define UAP_SET_TOC_POINTER(uap, ptr) (void) 0 #define FACTOR_PPC_TOC 1 #define CODE_TO_FUNCTION_POINTER(code) \ - void *desc[3]; \ - code = fill_function_descriptor(desc, code) + void* desc[3]; \ + code = fill_function_descriptor(desc, code) -#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) \ - code = fill_function_descriptor(new void*[3], code); \ - vm->function_descriptors.push_back((void **)code) +#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) \ + code = fill_function_descriptor(new void* [3], code); \ + vm->function_descriptors.push_back((void**)code) -#define FUNCTION_CODE_POINTER(ptr) \ - (function_descriptor_field((void *)ptr, 0)) +#define FUNCTION_CODE_POINTER(ptr) (function_descriptor_field((void*)ptr, 0)) -#define FUNCTION_TOC_POINTER(ptr) \ - (function_descriptor_field((void *)ptr, 1)) +#define FUNCTION_TOC_POINTER(ptr) (function_descriptor_field((void*)ptr, 1)) #define UAP_STACK_POINTER_TYPE unsigned long -inline static unsigned int uap_fpu_status(void *uap) -{ - union { - double as_double; - unsigned int as_uint[2]; - } tmp; - tmp.as_double = ((ucontext_t*) uap)->uc_mcontext.fp_regs[32]; - return tmp.as_uint[1]; +inline static unsigned int uap_fpu_status(void* uap) { + union { + double as_double; + unsigned int as_uint[2]; + } tmp; + tmp.as_double = ((ucontext_t*)uap)->uc_mcontext.fp_regs[32]; + return tmp.as_uint[1]; } -inline static void uap_clear_fpu_status(void *uap) -{ - union { - double as_double; - unsigned int as_uint[2]; - } tmp; - tmp.as_double = ((ucontext_t*) uap)->uc_mcontext.fp_regs[32]; - tmp.as_uint[1] &= 0x0007f8ff; - ((ucontext_t*) uap)->uc_mcontext.fp_regs[32] = tmp.as_double; +inline static void uap_clear_fpu_status(void* uap) { + union { + double as_double; + unsigned int as_uint[2]; + } tmp; + tmp.as_double = ((ucontext_t*)uap)->uc_mcontext.fp_regs[32]; + tmp.as_uint[1] &= 0x0007f8ff; + ((ucontext_t*)uap)->uc_mcontext.fp_regs[32] = tmp.as_double; } } diff --git a/vm/os-linux-x86.32.hpp b/vm/os-linux-x86.32.hpp index 40ba68fefa..fc80c5fd56 100644 --- a/vm/os-linux-x86.32.hpp +++ b/vm/os-linux-x86.32.hpp @@ -1,60 +1,59 @@ #include -namespace factor -{ +namespace factor { -// glibc lies about the contents of the fpstate the kernel provides, hiding the FXSR +// glibc lies about the contents of the fpstate the kernel provides, hiding the +// FXSR // environment struct _fpstate { - /* Regular FPU environment */ - unsigned long cw; - unsigned long sw; - unsigned long tag; - unsigned long ipoff; - unsigned long cssel; - unsigned long dataoff; - unsigned long datasel; - struct _fpreg _st[8]; - unsigned short status; - unsigned short magic; /* 0xffff = regular FPU data only */ - - /* FXSR FPU environment */ - unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ - unsigned long mxcsr; - unsigned long reserved; - struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ - struct _xmmreg _xmm[8]; - unsigned long padding[56]; + /* Regular FPU environment */ + unsigned long cw; + unsigned long sw; + unsigned long tag; + unsigned long ipoff; + unsigned long cssel; + unsigned long dataoff; + unsigned long datasel; + struct _fpreg _st[8]; + unsigned short status; + unsigned short magic; /* 0xffff = regular FPU data only */ + + /* FXSR FPU environment */ + unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ + unsigned long mxcsr; + unsigned long reserved; + struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ + struct _xmmreg _xmm[8]; + unsigned long padding[56]; }; -#define X86_FXSR_MAGIC 0x0000 +#define X86_FXSR_MAGIC 0x0000 -inline static unsigned int uap_fpu_status(void *uap) -{ - ucontext_t *ucontext = (ucontext_t *)uap; - struct _fpstate *fpregs = (struct _fpstate *)ucontext->uc_mcontext.fpregs; - if (fpregs->magic == X86_FXSR_MAGIC) - return fpregs->sw | fpregs->mxcsr; - else - return fpregs->sw; +inline static unsigned int uap_fpu_status(void* uap) { + ucontext_t* ucontext = (ucontext_t*)uap; + struct _fpstate* fpregs = (struct _fpstate*)ucontext->uc_mcontext.fpregs; + if (fpregs->magic == X86_FXSR_MAGIC) + return fpregs->sw | fpregs->mxcsr; + else + return fpregs->sw; } -inline static void uap_clear_fpu_status(void *uap) -{ - ucontext_t *ucontext = (ucontext_t *)uap; - struct _fpstate *fpregs = (struct _fpstate *)ucontext->uc_mcontext.fpregs; - fpregs->sw = 0; - if (fpregs->magic == X86_FXSR_MAGIC) - fpregs->mxcsr &= 0xffffffc0; +inline static void uap_clear_fpu_status(void* uap) { + ucontext_t* ucontext = (ucontext_t*)uap; + struct _fpstate* fpregs = (struct _fpstate*)ucontext->uc_mcontext.fpregs; + fpregs->sw = 0; + if (fpregs->magic == X86_FXSR_MAGIC) + fpregs->mxcsr &= 0xffffffc0; } +#define UAP_STACK_POINTER(ucontext) \ + (((ucontext_t*)ucontext)->uc_mcontext.gregs[7]) +#define UAP_PROGRAM_COUNTER(ucontext) \ + (((ucontext_t*)ucontext)->uc_mcontext.gregs[14]) +#define UAP_SET_TOC_POINTER(uap, ptr) (void) 0 -#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[7]) -#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[14]) -#define UAP_SET_TOC_POINTER(uap, ptr) (void)0 - -#define CODE_TO_FUNCTION_POINTER(code) (void)0 -#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void)0 +#define CODE_TO_FUNCTION_POINTER(code) (void) 0 +#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void) 0 #define FUNCTION_CODE_POINTER(ptr) ptr #define FUNCTION_TOC_POINTER(ptr) ptr diff --git a/vm/os-linux-x86.64.hpp b/vm/os-linux-x86.64.hpp index f0b1786071..1eae40a011 100644 --- a/vm/os-linux-x86.64.hpp +++ b/vm/os-linux-x86.64.hpp @@ -1,28 +1,27 @@ #include -namespace factor -{ - -inline static unsigned int uap_fpu_status(void *uap) -{ - ucontext_t *ucontext = (ucontext_t *)uap; - return ucontext->uc_mcontext.fpregs->swd - | ucontext->uc_mcontext.fpregs->mxcsr; +namespace factor { + +inline static unsigned int uap_fpu_status(void* uap) { + ucontext_t* ucontext = (ucontext_t*)uap; + return ucontext->uc_mcontext.fpregs->swd | + ucontext->uc_mcontext.fpregs->mxcsr; } -inline static void uap_clear_fpu_status(void *uap) -{ - ucontext_t *ucontext = (ucontext_t *)uap; - ucontext->uc_mcontext.fpregs->swd = 0; - ucontext->uc_mcontext.fpregs->mxcsr &= 0xffffffc0; +inline static void uap_clear_fpu_status(void* uap) { + ucontext_t* ucontext = (ucontext_t*)uap; + ucontext->uc_mcontext.fpregs->swd = 0; + ucontext->uc_mcontext.fpregs->mxcsr &= 0xffffffc0; } -#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[15]) -#define UAP_PROGRAM_COUNTER(ucontext) (((ucontext_t *)ucontext)->uc_mcontext.gregs[16]) -#define UAP_SET_TOC_POINTER(uap, ptr) (void)0 +#define UAP_STACK_POINTER(ucontext) \ + (((ucontext_t*)ucontext)->uc_mcontext.gregs[15]) +#define UAP_PROGRAM_COUNTER(ucontext) \ + (((ucontext_t*)ucontext)->uc_mcontext.gregs[16]) +#define UAP_SET_TOC_POINTER(uap, ptr) (void) 0 -#define CODE_TO_FUNCTION_POINTER(code) (void)0 -#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void)0 +#define CODE_TO_FUNCTION_POINTER(code) (void) 0 +#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void) 0 #define FUNCTION_CODE_POINTER(ptr) ptr #define FUNCTION_TOC_POINTER(ptr) ptr diff --git a/vm/os-linux.cpp b/vm/os-linux.cpp index ebbbf7a6fe..7d0c7ba27b 100644 --- a/vm/os-linux.cpp +++ b/vm/os-linux.cpp @@ -1,27 +1,22 @@ #include "master.hpp" -namespace factor -{ +namespace factor { /* Snarfed from SBCL linux-so.c. You must free() the result yourself. */ -const char *vm_executable_path() -{ - char *path = new char[PATH_MAX + 1]; +const char* vm_executable_path() { + char* path = new char[PATH_MAX + 1]; - int size = readlink("/proc/self/exe", path, PATH_MAX); - if (size < 0) - { - fatal_error("Cannot read /proc/self/exe",0); - return NULL; - } - else - { - path[size] = '\0'; + int size = readlink("/proc/self/exe", path, PATH_MAX); + if (size < 0) { + fatal_error("Cannot read /proc/self/exe", 0); + return NULL; + } else { + path[size] = '\0'; - const char *ret = safe_strdup(path); - delete[] path; - return ret; - } + const char* ret = safe_strdup(path); + delete[] path; + return ret; + } } } diff --git a/vm/os-linux.hpp b/vm/os-linux.hpp index 8ea9b16dd1..df94e1143a 100644 --- a/vm/os-linux.hpp +++ b/vm/os-linux.hpp @@ -1,6 +1,3 @@ #include -namespace factor -{ - -} +namespace factor {} diff --git a/vm/os-macosx-x86.32.hpp b/vm/os-macosx-x86.32.hpp index 12a351ae58..58c63081b6 100644 --- a/vm/os-macosx-x86.32.hpp +++ b/vm/os-macosx-x86.32.hpp @@ -1,7 +1,6 @@ #include -namespace factor -{ +namespace factor { /* Fault handler information. MacOSX version. Copyright (C) 1993-1999, 2002-2003 Bruno Haible @@ -28,51 +27,46 @@ Modified for Factor by Slava Pestov */ #define MACH_FLOAT_STATE_COUNT i386_FLOAT_STATE_COUNT #if __DARWIN_UNIX03 - #define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->__faultvaddr - #define MACH_STACK_POINTER(thr_state) (thr_state)->__esp - #define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->__eip +#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->__faultvaddr +#define MACH_STACK_POINTER(thr_state) (thr_state)->__esp +#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->__eip - #define UAP_SS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->__ss) - #define UAP_FS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->__fs) +#define UAP_SS(ucontext) &(((ucontext_t*)(ucontext))->uc_mcontext->__ss) +#define UAP_FS(ucontext) &(((ucontext_t*)(ucontext))->uc_mcontext->__fs) - #define MXCSR(float_state) (float_state)->__fpu_mxcsr - #define X87SW(float_state) (float_state)->__fpu_fsw +#define MXCSR(float_state) (float_state)->__fpu_mxcsr +#define X87SW(float_state) (float_state)->__fpu_fsw #else - #define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->faultvaddr - #define MACH_STACK_POINTER(thr_state) (thr_state)->esp - #define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->eip +#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->faultvaddr +#define MACH_STACK_POINTER(thr_state) (thr_state)->esp +#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->eip - #define UAP_SS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->ss) - #define UAP_FS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->fs) +#define UAP_SS(ucontext) &(((ucontext_t*)(ucontext))->uc_mcontext->ss) +#define UAP_FS(ucontext) &(((ucontext_t*)(ucontext))->uc_mcontext->fs) - #define MXCSR(float_state) (float_state)->fpu_mxcsr - #define X87SW(float_state) (float_state)->fpu_fsw +#define MXCSR(float_state) (float_state)->fpu_mxcsr +#define X87SW(float_state) (float_state)->fpu_fsw #endif -#define UAP_PROGRAM_COUNTER(ucontext) \ - MACH_PROGRAM_COUNTER(UAP_SS(ucontext)) +#define UAP_PROGRAM_COUNTER(ucontext) MACH_PROGRAM_COUNTER(UAP_SS(ucontext)) -inline static unsigned int mach_fpu_status(i386_float_state_t *float_state) -{ - unsigned short x87sw; - memcpy(&x87sw, &X87SW(float_state), sizeof(x87sw)); - return MXCSR(float_state) | x87sw; +inline static unsigned int mach_fpu_status(i386_float_state_t* float_state) { + unsigned short x87sw; + memcpy(&x87sw, &X87SW(float_state), sizeof(x87sw)); + return MXCSR(float_state) | x87sw; } -inline static unsigned int uap_fpu_status(void *uap) -{ - return mach_fpu_status(UAP_FS(uap)); +inline static unsigned int uap_fpu_status(void* uap) { + return mach_fpu_status(UAP_FS(uap)); } -inline static void mach_clear_fpu_status(i386_float_state_t *float_state) -{ - MXCSR(float_state) &= 0xffffffc0; - memset(&X87SW(float_state), 0, sizeof(X87SW(float_state))); +inline static void mach_clear_fpu_status(i386_float_state_t* float_state) { + MXCSR(float_state) &= 0xffffffc0; + memset(&X87SW(float_state), 0, sizeof(X87SW(float_state))); } -inline static void uap_clear_fpu_status(void *uap) -{ - mach_clear_fpu_status(UAP_FS(uap)); +inline static void uap_clear_fpu_status(void* uap) { + mach_clear_fpu_status(UAP_FS(uap)); } } diff --git a/vm/os-macosx-x86.64.hpp b/vm/os-macosx-x86.64.hpp index 9a339881e6..7ae3cb8d1b 100644 --- a/vm/os-macosx-x86.64.hpp +++ b/vm/os-macosx-x86.64.hpp @@ -1,7 +1,6 @@ #include -namespace factor -{ +namespace factor { /* Fault handler information. MacOSX version. Copyright (C) 1993-1999, 2002-2003 Bruno Haible @@ -28,49 +27,44 @@ Modified for Factor by Slava Pestov and Daniel Ehrenberg */ #define MACH_FLOAT_STATE_COUNT x86_FLOAT_STATE64_COUNT #if __DARWIN_UNIX03 - #define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->__faultvaddr - #define MACH_STACK_POINTER(thr_state) (thr_state)->__rsp - #define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->__rip - #define UAP_SS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->__ss) - #define UAP_FS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->__fs) - - #define MXCSR(float_state) (float_state)->__fpu_mxcsr - #define X87SW(float_state) (float_state)->__fpu_fsw +#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->__faultvaddr +#define MACH_STACK_POINTER(thr_state) (thr_state)->__rsp +#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->__rip +#define UAP_SS(ucontext) &(((ucontext_t*)(ucontext))->uc_mcontext->__ss) +#define UAP_FS(ucontext) &(((ucontext_t*)(ucontext))->uc_mcontext->__fs) + +#define MXCSR(float_state) (float_state)->__fpu_mxcsr +#define X87SW(float_state) (float_state)->__fpu_fsw #else - #define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->faultvaddr - #define MACH_STACK_POINTER(thr_state) (thr_state)->rsp - #define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->rip - #define UAP_SS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->ss) - #define UAP_FS(ucontext) &(((ucontext_t *)(ucontext))->uc_mcontext->fs) - - #define MXCSR(float_state) (float_state)->fpu_mxcsr - #define X87SW(float_state) (float_state)->fpu_fsw +#define MACH_EXC_STATE_FAULT(exc_state) (exc_state)->faultvaddr +#define MACH_STACK_POINTER(thr_state) (thr_state)->rsp +#define MACH_PROGRAM_COUNTER(thr_state) (thr_state)->rip +#define UAP_SS(ucontext) &(((ucontext_t*)(ucontext))->uc_mcontext->ss) +#define UAP_FS(ucontext) &(((ucontext_t*)(ucontext))->uc_mcontext->fs) + +#define MXCSR(float_state) (float_state)->fpu_mxcsr +#define X87SW(float_state) (float_state)->fpu_fsw #endif -#define UAP_PROGRAM_COUNTER(ucontext) \ - MACH_PROGRAM_COUNTER(UAP_SS(ucontext)) +#define UAP_PROGRAM_COUNTER(ucontext) MACH_PROGRAM_COUNTER(UAP_SS(ucontext)) -inline static unsigned int mach_fpu_status(x86_float_state64_t *float_state) -{ - unsigned short x87sw; - memcpy(&x87sw, &X87SW(float_state), sizeof(x87sw)); - return MXCSR(float_state) | x87sw; +inline static unsigned int mach_fpu_status(x86_float_state64_t* float_state) { + unsigned short x87sw; + memcpy(&x87sw, &X87SW(float_state), sizeof(x87sw)); + return MXCSR(float_state) | x87sw; } -inline static unsigned int uap_fpu_status(void *uap) -{ - return mach_fpu_status(UAP_FS(uap)); +inline static unsigned int uap_fpu_status(void* uap) { + return mach_fpu_status(UAP_FS(uap)); } -inline static void mach_clear_fpu_status(x86_float_state64_t *float_state) -{ - MXCSR(float_state) &= 0xffffffc0; - memset(&X87SW(float_state), 0, sizeof(X87SW(float_state))); +inline static void mach_clear_fpu_status(x86_float_state64_t* float_state) { + MXCSR(float_state) &= 0xffffffc0; + memset(&X87SW(float_state), 0, sizeof(X87SW(float_state))); } -inline static void uap_clear_fpu_status(void *uap) -{ - mach_clear_fpu_status(UAP_FS(uap)); +inline static void uap_clear_fpu_status(void* uap) { + mach_clear_fpu_status(UAP_FS(uap)); } /* Must match the leaf-stack-frame-size, signal-handler-stack-frame-size, diff --git a/vm/os-macosx.hpp b/vm/os-macosx.hpp index 5a7f9ab842..0657d60eba 100644 --- a/vm/os-macosx.hpp +++ b/vm/os-macosx.hpp @@ -1,21 +1,20 @@ -namespace factor -{ +namespace factor { #define VM_C_API extern "C" __attribute__((visibility("default"))) #define FACTOR_OS_STRING "macosx" void early_init(); -const char *vm_executable_path(); -const char *default_image_path(); +const char* vm_executable_path(); +const char* default_image_path(); -#define UAP_STACK_POINTER(ucontext) (((ucontext_t *)ucontext)->uc_stack.ss_sp) -#define UAP_SET_TOC_POINTER(uap, ptr) (void)0 +#define UAP_STACK_POINTER(ucontext) (((ucontext_t*)ucontext)->uc_stack.ss_sp) +#define UAP_SET_TOC_POINTER(uap, ptr) (void) 0 #define UAP_STACK_POINTER_TYPE void * -#define CODE_TO_FUNCTION_POINTER(code) (void)0 -#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void)0 +#define CODE_TO_FUNCTION_POINTER(code) (void) 0 +#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void) 0 #define FUNCTION_CODE_POINTER(ptr) ptr #define FUNCTION_TOC_POINTER(ptr) ptr diff --git a/vm/os-macosx.mm b/vm/os-macosx.mm index c18c6aa1ea..be7afcb552 100644 --- a/vm/os-macosx.mm +++ b/vm/os-macosx.mm @@ -5,88 +5,78 @@ #include "master.hpp" -namespace factor -{ +namespace factor { -void factor_vm::c_to_factor_toplevel(cell quot) -{ - c_to_factor(quot); -} +void factor_vm::c_to_factor_toplevel(cell quot) { c_to_factor(quot); } // Darwin 9 is 10.5, Darwin 10 is 10.6 // http://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history -void early_init(void) -{ - struct utsname u; - int n; - uname(&u); - sscanf(u.release,"%d", &n); - if(n < 9) { - std::cout << "Factor requires Mac OS X 10.5 or later.\n"; - exit(1); - } +void early_init(void) { + struct utsname u; + int n; + uname(&u); + sscanf(u.release, "%d", &n); + if (n < 9) { + std::cout << "Factor requires Mac OS X 10.5 or later.\n"; + exit(1); + } } -const char *vm_executable_path(void) -{ - return [[[NSBundle mainBundle] executablePath] UTF8String]; +const char* vm_executable_path(void) { + return [[[NSBundle mainBundle] executablePath] UTF8String]; } -const char *default_image_path(void) -{ - NSBundle *bundle = [NSBundle mainBundle]; - NSString *path = [bundle bundlePath]; - NSString *executable = [[bundle executablePath] lastPathComponent]; - NSString *image = [executable stringByAppendingString:@".image"]; +const char* default_image_path(void) { + NSBundle* bundle = [NSBundle mainBundle]; + NSString* path = [bundle bundlePath]; + NSString* executable = [[bundle executablePath] lastPathComponent]; + NSString* image = [executable stringByAppendingString:@".image"]; - NSString *returnVal; + NSString* returnVal; - if([path hasSuffix:@".app"] || [path hasSuffix:@".app/"]) - { - NSFileManager *mgr = [NSFileManager defaultManager]; + if ([path hasSuffix:@".app"] || [path hasSuffix:@".app/"]) { + NSFileManager* mgr = [NSFileManager defaultManager]; - NSString *imageInBundle = [[path stringByAppendingPathComponent:@"Contents/Resources"] stringByAppendingPathComponent:image]; - NSString *imageAlongBundle = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:image]; + NSString* imageInBundle = + [[path stringByAppendingPathComponent:@"Contents/Resources"] + stringByAppendingPathComponent:image]; + NSString* imageAlongBundle = [[path stringByDeletingLastPathComponent] + stringByAppendingPathComponent:image]; - returnVal = ([mgr fileExistsAtPath:imageInBundle] - ? imageInBundle : imageAlongBundle); - } - else - returnVal = [path stringByAppendingPathComponent:image]; + returnVal = ([mgr fileExistsAtPath:imageInBundle] ? imageInBundle + : imageAlongBundle); + } else + returnVal = [path stringByAppendingPathComponent:image]; - return [returnVal UTF8String]; + return [returnVal UTF8String]; } -void factor_vm::init_signals(void) -{ - unix_init_signals(); - mach_initialize(); +void factor_vm::init_signals(void) { + unix_init_signals(); + mach_initialize(); } /* Amateurs at Apple: implement this function, properly! */ -Protocol *objc_getProtocol(char *name) -{ - if(strcmp(name,"NSTextInput") == 0) - return @protocol(NSTextInput); - else - return nil; +Protocol* objc_getProtocol(char* name) { + if (strcmp(name, "NSTextInput") == 0) + return @protocol(NSTextInput); + else + return nil; } -u64 nano_count() -{ - u64 time = mach_absolute_time(); - - static u64 scaling_factor = 0; - if(!scaling_factor) - { - mach_timebase_info_data_t info; - kern_return_t ret = mach_timebase_info(&info); - if(ret != 0) - fatal_error("mach_timebase_info failed",ret); - scaling_factor = info.numer/info.denom; - } - - return time * scaling_factor; +u64 nano_count() { + u64 time = mach_absolute_time(); + + static u64 scaling_factor = 0; + if (!scaling_factor) { + mach_timebase_info_data_t info; + kern_return_t ret = mach_timebase_info(&info); + if (ret != 0) + fatal_error("mach_timebase_info failed", ret); + scaling_factor = info.numer / info.denom; + } + + return time * scaling_factor; } } diff --git a/vm/os-unix.cpp b/vm/os-unix.cpp index fc996d1201..aff6af233f 100644 --- a/vm/os-unix.cpp +++ b/vm/os-unix.cpp @@ -1,560 +1,494 @@ #include "master.hpp" -namespace factor -{ +namespace factor { -THREADHANDLE start_thread(void *(*start_routine)(void *),void *args) -{ - pthread_attr_t attr; - pthread_t thread; - if (pthread_attr_init (&attr) != 0) - fatal_error("pthread_attr_init() failed",0); - if (pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE) != 0) - fatal_error("pthread_attr_setdetachstate() failed",0); - if (pthread_create (&thread, &attr, start_routine, args) != 0) - fatal_error("pthread_create() failed",0); - pthread_attr_destroy(&attr); - return thread; +THREADHANDLE start_thread(void* (*start_routine)(void*), void* args) { + pthread_attr_t attr; + pthread_t thread; + if (pthread_attr_init(&attr) != 0) + fatal_error("pthread_attr_init() failed", 0); + if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) != 0) + fatal_error("pthread_attr_setdetachstate() failed", 0); + if (pthread_create(&thread, &attr, start_routine, args) != 0) + fatal_error("pthread_create() failed", 0); + pthread_attr_destroy(&attr); + return thread; } -static void *null_dll; +static void* null_dll; -void sleep_nanos(u64 nsec) -{ - timespec ts; - timespec ts_rem; - int ret; - ts.tv_sec = nsec / 1000000000; - ts.tv_nsec = nsec % 1000000000; - ret = nanosleep(&ts,&ts_rem); - while(ret == -1 && errno == EINTR) - { - memcpy(&ts, &ts_rem, sizeof(ts)); - ret = nanosleep(&ts, &ts_rem); - } +void sleep_nanos(u64 nsec) { + timespec ts; + timespec ts_rem; + int ret; + ts.tv_sec = nsec / 1000000000; + ts.tv_nsec = nsec % 1000000000; + ret = nanosleep(&ts, &ts_rem); + while (ret == -1 && errno == EINTR) { + memcpy(&ts, &ts_rem, sizeof(ts)); + ret = nanosleep(&ts, &ts_rem); + } - if(ret == -1) - fatal_error("nanosleep failed", 0); + if (ret == -1) + fatal_error("nanosleep failed", 0); } -void factor_vm::init_ffi() -{ - null_dll = dlopen(NULL,RTLD_LAZY); -} +void factor_vm::init_ffi() { null_dll = dlopen(NULL, RTLD_LAZY); } -void factor_vm::ffi_dlopen(dll *dll) -{ - dll->handle = dlopen(alien_offset(dll->path), RTLD_LAZY); +void factor_vm::ffi_dlopen(dll* dll) { + dll->handle = dlopen(alien_offset(dll->path), RTLD_LAZY); } -void *factor_vm::ffi_dlsym_raw(dll *dll, symbol_char *symbol) -{ - return dlsym(dll ? dll->handle : null_dll, symbol); +void* factor_vm::ffi_dlsym_raw(dll* dll, symbol_char* symbol) { + return dlsym(dll ? dll->handle : null_dll, symbol); } -void *factor_vm::ffi_dlsym(dll *dll, symbol_char *symbol) -{ - return FUNCTION_CODE_POINTER(ffi_dlsym_raw(dll, symbol)); +void* factor_vm::ffi_dlsym(dll* dll, symbol_char* symbol) { + return FUNCTION_CODE_POINTER(ffi_dlsym_raw(dll, symbol)); } #ifdef FACTOR_PPC -void *factor_vm::ffi_dlsym_toc(dll *dll, symbol_char *symbol) -{ - return FUNCTION_TOC_POINTER(ffi_dlsym_raw(dll, symbol)); +void* factor_vm::ffi_dlsym_toc(dll* dll, symbol_char* symbol) { + return FUNCTION_TOC_POINTER(ffi_dlsym_raw(dll, symbol)); } #endif -void factor_vm::ffi_dlclose(dll *dll) -{ - if(dlclose(dll->handle)) - general_error(ERROR_FFI,false_object,false_object); - dll->handle = NULL; +void factor_vm::ffi_dlclose(dll* dll) { + if (dlclose(dll->handle)) + general_error(ERROR_FFI, false_object, false_object); + dll->handle = NULL; } -void factor_vm::primitive_existsp() -{ - struct stat sb; - char *path = (char *)(untag_check(ctx->pop()) + 1); - ctx->push(tag_boolean(stat(path,&sb) >= 0)); +void factor_vm::primitive_existsp() { + struct stat sb; + char* path = (char*)(untag_check(ctx->pop()) + 1); + ctx->push(tag_boolean(stat(path, &sb) >= 0)); } -void factor_vm::move_file(const vm_char *path1, const vm_char *path2) -{ - int ret = 0; - do - { - ret = rename((path1),(path2)); - } - while(ret < 0 && errno == EINTR); +void factor_vm::move_file(const vm_char* path1, const vm_char* path2) { + int ret = 0; + do { + ret = rename((path1), (path2)); + } while (ret < 0 && errno == EINTR); - if(ret < 0) - general_error(ERROR_IO,tag_fixnum(errno),false_object); + if (ret < 0) + general_error(ERROR_IO, tag_fixnum(errno), false_object); } -segment::segment(cell size_, bool executable_p) -{ - size = size_; +segment::segment(cell size_, bool executable_p) { + size = size_; - int pagesize = getpagesize(); + int pagesize = getpagesize(); - int prot; - if(executable_p) - prot = (PROT_READ | PROT_WRITE | PROT_EXEC); - else - prot = (PROT_READ | PROT_WRITE); + int prot; + if (executable_p) + prot = (PROT_READ | PROT_WRITE | PROT_EXEC); + else + prot = (PROT_READ | PROT_WRITE); - char *array = (char *)mmap(NULL,pagesize + size + pagesize,prot,MAP_ANON | MAP_PRIVATE,-1,0); - if(array == (char*)-1) out_of_memory(); + char* array = (char*)mmap(NULL, pagesize + size + pagesize, prot, + MAP_ANON | MAP_PRIVATE, -1, 0); + if (array == (char*)- 1) + out_of_memory(); - if(mprotect(array,pagesize,PROT_NONE) == -1) - fatal_error("Cannot protect low guard page",(cell)array); + if (mprotect(array, pagesize, PROT_NONE) == -1) + fatal_error("Cannot protect low guard page", (cell) array); - if(mprotect(array + pagesize + size,pagesize,PROT_NONE) == -1) - fatal_error("Cannot protect high guard page",(cell)array); + if (mprotect(array + pagesize + size, pagesize, PROT_NONE) == -1) + fatal_error("Cannot protect high guard page", (cell) array); - start = (cell)(array + pagesize); - end = start + size; + start = (cell)(array + pagesize); + end = start + size; } -segment::~segment() -{ - int pagesize = getpagesize(); - int retval = munmap((void*)(start - pagesize),pagesize + size + pagesize); - if(retval) - fatal_error("Segment deallocation failed",0); +segment::~segment() { + int pagesize = getpagesize(); + int retval = munmap((void*)(start - pagesize), pagesize + size + pagesize); + if (retval) + fatal_error("Segment deallocation failed", 0); } -void code_heap::guard_safepoint() -{ - if(mprotect(safepoint_page,getpagesize(),PROT_NONE) == -1) - fatal_error("Cannot protect safepoint guard page",(cell)safepoint_page); +void code_heap::guard_safepoint() { + if (mprotect(safepoint_page, getpagesize(), PROT_NONE) == -1) + fatal_error("Cannot protect safepoint guard page", (cell) safepoint_page); } -void code_heap::unguard_safepoint() -{ - if(mprotect(safepoint_page,getpagesize(),PROT_WRITE) == -1) - fatal_error("Cannot unprotect safepoint guard page",(cell)safepoint_page); +void code_heap::unguard_safepoint() { + if (mprotect(safepoint_page, getpagesize(), PROT_WRITE) == -1) + fatal_error("Cannot unprotect safepoint guard page", (cell) safepoint_page); } -void factor_vm::dispatch_signal(void *uap, void (handler)()) -{ - dispatch_signal_handler( - (cell*)&UAP_STACK_POINTER(uap), - (cell*)&UAP_PROGRAM_COUNTER(uap), - (cell)FUNCTION_CODE_POINTER(handler) - ); - UAP_SET_TOC_POINTER(uap, (cell)FUNCTION_TOC_POINTER(handler)); +void factor_vm::dispatch_signal(void* uap, void(handler)()) { + dispatch_signal_handler((cell*)&UAP_STACK_POINTER(uap), + (cell*)&UAP_PROGRAM_COUNTER(uap), + (cell) FUNCTION_CODE_POINTER(handler)); + UAP_SET_TOC_POINTER(uap, (cell) FUNCTION_TOC_POINTER(handler)); } -void factor_vm::start_sampling_profiler_timer() -{ - struct itimerval timer; - memset((void*)&timer, 0, sizeof(struct itimerval)); - timer.it_value.tv_usec = 1000000/samples_per_second; - timer.it_interval.tv_usec = 1000000/samples_per_second; - setitimer(ITIMER_REAL, &timer, NULL); +void factor_vm::start_sampling_profiler_timer() { + struct itimerval timer; + memset((void*)&timer, 0, sizeof(struct itimerval)); + timer.it_value.tv_usec = 1000000 / samples_per_second; + timer.it_interval.tv_usec = 1000000 / samples_per_second; + setitimer(ITIMER_REAL, &timer, NULL); } -void factor_vm::end_sampling_profiler_timer() -{ - struct itimerval timer; - memset((void*)&timer, 0, sizeof(struct itimerval)); - setitimer(ITIMER_REAL, &timer, NULL); +void factor_vm::end_sampling_profiler_timer() { + struct itimerval timer; + memset((void*)&timer, 0, sizeof(struct itimerval)); + setitimer(ITIMER_REAL, &timer, NULL); } -void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap) -{ - factor_vm *vm = current_vm(); - vm->verify_memory_protection_error((cell)siginfo->si_addr); - vm->signal_fault_addr = (cell)siginfo->si_addr; - vm->signal_fault_pc = (cell)UAP_PROGRAM_COUNTER(uap); - vm->dispatch_signal(uap,factor::memory_signal_handler_impl); +void memory_signal_handler(int signal, siginfo_t* siginfo, void* uap) { + factor_vm* vm = current_vm(); + vm->verify_memory_protection_error((cell) siginfo->si_addr); + vm->signal_fault_addr = (cell) siginfo->si_addr; + vm->signal_fault_pc = (cell) UAP_PROGRAM_COUNTER(uap); + vm->dispatch_signal(uap, factor::memory_signal_handler_impl); } -void synchronous_signal_handler(int signal, siginfo_t *siginfo, void *uap) -{ - if (factor_vm::fatal_erroring_p) - return; +void synchronous_signal_handler(int signal, siginfo_t* siginfo, void* uap) { + if (factor_vm::fatal_erroring_p) + return; - factor_vm *vm = current_vm_p(); - if (vm) - { - vm->signal_number = signal; - vm->dispatch_signal(uap,factor::synchronous_signal_handler_impl); - } - else - fatal_error("Foreign thread received signal", signal); + factor_vm* vm = current_vm_p(); + if (vm) { + vm->signal_number = signal; + vm->dispatch_signal(uap, factor::synchronous_signal_handler_impl); + } else + fatal_error("Foreign thread received signal", signal); } -void safe_write_nonblock(int fd, void *data, ssize_t size); +void safe_write_nonblock(int fd, void* data, ssize_t size); -static void enqueue_signal(factor_vm *vm, int signal) -{ - if (vm->signal_pipe_output != 0) - safe_write_nonblock(vm->signal_pipe_output, &signal, sizeof(int)); +static void enqueue_signal(factor_vm* vm, int signal) { + if (vm->signal_pipe_output != 0) + safe_write_nonblock(vm->signal_pipe_output, &signal, sizeof(int)); } -void enqueue_signal_handler(int signal, siginfo_t *siginfo, void *uap) -{ - if (factor_vm::fatal_erroring_p) - return; +void enqueue_signal_handler(int signal, siginfo_t* siginfo, void* uap) { + if (factor_vm::fatal_erroring_p) + return; - factor_vm *vm = current_vm_p(); - if (vm) - enqueue_signal(vm, signal); + factor_vm* vm = current_vm_p(); + if (vm) + enqueue_signal(vm, signal); } -void fep_signal_handler(int signal, siginfo_t *siginfo, void *uap) -{ - if (factor_vm::fatal_erroring_p) - return; +void fep_signal_handler(int signal, siginfo_t* siginfo, void* uap) { + if (factor_vm::fatal_erroring_p) + return; - factor_vm *vm = current_vm_p(); - if (vm) - { - vm->safepoint.enqueue_fep(vm); - enqueue_signal(vm, signal); - } - else - fatal_error("Foreign thread received signal", signal); + factor_vm* vm = current_vm_p(); + if (vm) { + vm->safepoint.enqueue_fep(vm); + enqueue_signal(vm, signal); + } else + fatal_error("Foreign thread received signal", signal); } -void sample_signal_handler(int signal, siginfo_t *siginfo, void *uap) -{ - factor_vm *vm = current_vm_p(); - bool foreign_thread = false; - if (vm == NULL) - { - foreign_thread = true; - vm = thread_vms.begin()->second; - } - if (atomic::load(&vm->sampling_profiler_p)) - vm->safepoint.enqueue_samples(vm, 1, (cell)UAP_PROGRAM_COUNTER(uap), foreign_thread); - else if (!foreign_thread) - enqueue_signal(vm, signal); +void sample_signal_handler(int signal, siginfo_t* siginfo, void* uap) { + factor_vm* vm = current_vm_p(); + bool foreign_thread = false; + if (vm == NULL) { + foreign_thread = true; + vm = thread_vms.begin()->second; + } + if (atomic::load(&vm->sampling_profiler_p)) + vm->safepoint.enqueue_samples(vm, 1, (cell) UAP_PROGRAM_COUNTER(uap), + foreign_thread); + else if (!foreign_thread) + enqueue_signal(vm, signal); } -void ignore_signal_handler(int signal, siginfo_t *siginfo, void *uap) -{ -} +void ignore_signal_handler(int signal, siginfo_t* siginfo, void* uap) {} -void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap) -{ - factor_vm *vm = current_vm(); - vm->signal_number = signal; - vm->signal_fpu_status = fpu_status(uap_fpu_status(uap)); - uap_clear_fpu_status(uap); +void fpe_signal_handler(int signal, siginfo_t* siginfo, void* uap) { + factor_vm* vm = current_vm(); + vm->signal_number = signal; + vm->signal_fpu_status = fpu_status(uap_fpu_status(uap)); + uap_clear_fpu_status(uap); - vm->dispatch_signal(uap, - (siginfo->si_code == FPE_INTDIV || siginfo->si_code == FPE_INTOVF) - ? factor::synchronous_signal_handler_impl - : factor::fp_signal_handler_impl); + vm->dispatch_signal( + uap, (siginfo->si_code == FPE_INTDIV || siginfo->si_code == FPE_INTOVF) + ? factor::synchronous_signal_handler_impl + : factor::fp_signal_handler_impl); } -static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact) -{ - int ret; - do - { - ret = sigaction(signum, act, oldact); - } - while(ret == -1 && errno == EINTR); +static void sigaction_safe(int signum, const struct sigaction* act, + struct sigaction* oldact) { + int ret; + do { + ret = sigaction(signum, act, oldact); + } while (ret == -1 && errno == EINTR); - if(ret == -1) - fatal_error("sigaction failed", errno); + if (ret == -1) + fatal_error("sigaction failed", errno); } -static void init_sigaction_with_handler(struct sigaction *act, - void (*handler)(int, siginfo_t*, void*)) -{ - memset(act, 0, sizeof(struct sigaction)); - sigemptyset(&act->sa_mask); - act->sa_sigaction = handler; - act->sa_flags = SA_SIGINFO | SA_ONSTACK; +static void init_sigaction_with_handler(struct sigaction* act, + void (*handler)(int, siginfo_t*, + void*)) { + memset(act, 0, sizeof(struct sigaction)); + sigemptyset(&act->sa_mask); + act->sa_sigaction = handler; + act->sa_flags = SA_SIGINFO | SA_ONSTACK; } -static void safe_pipe(int *in, int *out) -{ - int filedes[2]; +static void safe_pipe(int* in, int* out) { + int filedes[2]; - if(pipe(filedes) < 0) - fatal_error("Error opening pipe",errno); + if (pipe(filedes) < 0) + fatal_error("Error opening pipe", errno); - *in = filedes[0]; - *out = filedes[1]; + *in = filedes[0]; + *out = filedes[1]; - if(fcntl(*in,F_SETFD,FD_CLOEXEC) < 0) - fatal_error("Error with fcntl",errno); + if (fcntl(*in, F_SETFD, FD_CLOEXEC) < 0) + fatal_error("Error with fcntl", errno); - if(fcntl(*out,F_SETFD,FD_CLOEXEC) < 0) - fatal_error("Error with fcntl",errno); + if (fcntl(*out, F_SETFD, FD_CLOEXEC) < 0) + fatal_error("Error with fcntl", errno); } -static void init_signal_pipe(factor_vm *vm) -{ - safe_pipe(&vm->signal_pipe_input, &vm->signal_pipe_output); +static void init_signal_pipe(factor_vm* vm) { + safe_pipe(&vm->signal_pipe_input, &vm->signal_pipe_output); - if(fcntl(vm->signal_pipe_output,F_SETFL,O_NONBLOCK) < 0) - fatal_error("Error with fcntl",errno); + if (fcntl(vm->signal_pipe_output, F_SETFL, O_NONBLOCK) < 0) + fatal_error("Error with fcntl", errno); - vm->special_objects[OBJ_SIGNAL_PIPE] = tag_fixnum(vm->signal_pipe_input); + vm->special_objects[OBJ_SIGNAL_PIPE] = tag_fixnum(vm->signal_pipe_input); } -void factor_vm::unix_init_signals() -{ - init_signal_pipe(this); +void factor_vm::unix_init_signals() { + init_signal_pipe(this); - signal_callstack_seg = new segment(callstack_size,false); - - stack_t signal_callstack; - signal_callstack.ss_sp = (char *)signal_callstack_seg->start; - signal_callstack.ss_size = signal_callstack_seg->size; - signal_callstack.ss_flags = 0; + signal_callstack_seg = new segment(callstack_size, false); - if(sigaltstack(&signal_callstack,(stack_t *)NULL) < 0) - fatal_error("sigaltstack() failed",0); + stack_t signal_callstack; + signal_callstack.ss_sp = (char*)signal_callstack_seg->start; + signal_callstack.ss_size = signal_callstack_seg->size; + signal_callstack.ss_flags = 0; - struct sigaction memory_sigaction; - struct sigaction synchronous_sigaction; - struct sigaction enqueue_sigaction; - struct sigaction sample_sigaction; - struct sigaction fpe_sigaction; - struct sigaction ignore_sigaction; + if (sigaltstack(&signal_callstack, (stack_t*)NULL) < 0) + fatal_error("sigaltstack() failed", 0); - init_sigaction_with_handler(&memory_sigaction, memory_signal_handler); - sigaction_safe(SIGBUS,&memory_sigaction,NULL); - sigaction_safe(SIGSEGV,&memory_sigaction,NULL); - sigaction_safe(SIGTRAP,&memory_sigaction,NULL); + struct sigaction memory_sigaction; + struct sigaction synchronous_sigaction; + struct sigaction enqueue_sigaction; + struct sigaction sample_sigaction; + struct sigaction fpe_sigaction; + struct sigaction ignore_sigaction; - init_sigaction_with_handler(&fpe_sigaction, fpe_signal_handler); - sigaction_safe(SIGFPE,&fpe_sigaction,NULL); + init_sigaction_with_handler(&memory_sigaction, memory_signal_handler); + sigaction_safe(SIGBUS, &memory_sigaction, NULL); + sigaction_safe(SIGSEGV, &memory_sigaction, NULL); + sigaction_safe(SIGTRAP, &memory_sigaction, NULL); - init_sigaction_with_handler(&synchronous_sigaction, synchronous_signal_handler); - sigaction_safe(SIGILL,&synchronous_sigaction,NULL); - sigaction_safe(SIGABRT,&synchronous_sigaction,NULL); + init_sigaction_with_handler(&fpe_sigaction, fpe_signal_handler); + sigaction_safe(SIGFPE, &fpe_sigaction, NULL); - init_sigaction_with_handler(&enqueue_sigaction, enqueue_signal_handler); - sigaction_safe(SIGWINCH,&enqueue_sigaction,NULL); - sigaction_safe(SIGUSR1,&enqueue_sigaction,NULL); - sigaction_safe(SIGCONT,&enqueue_sigaction,NULL); - sigaction_safe(SIGURG,&enqueue_sigaction,NULL); - sigaction_safe(SIGIO,&enqueue_sigaction,NULL); - sigaction_safe(SIGPROF,&enqueue_sigaction,NULL); - sigaction_safe(SIGVTALRM,&enqueue_sigaction,NULL); + init_sigaction_with_handler(&synchronous_sigaction, + synchronous_signal_handler); + sigaction_safe(SIGILL, &synchronous_sigaction, NULL); + sigaction_safe(SIGABRT, &synchronous_sigaction, NULL); + + init_sigaction_with_handler(&enqueue_sigaction, enqueue_signal_handler); + sigaction_safe(SIGWINCH, &enqueue_sigaction, NULL); + sigaction_safe(SIGUSR1, &enqueue_sigaction, NULL); + sigaction_safe(SIGCONT, &enqueue_sigaction, NULL); + sigaction_safe(SIGURG, &enqueue_sigaction, NULL); + sigaction_safe(SIGIO, &enqueue_sigaction, NULL); + sigaction_safe(SIGPROF, &enqueue_sigaction, NULL); + sigaction_safe(SIGVTALRM, &enqueue_sigaction, NULL); #ifdef SIGINFO - sigaction_safe(SIGINFO,&enqueue_sigaction,NULL); + sigaction_safe(SIGINFO, &enqueue_sigaction, NULL); #endif - handle_ctrl_c(); + handle_ctrl_c(); - init_sigaction_with_handler(&sample_sigaction, sample_signal_handler); - sigaction_safe(SIGALRM,&sample_sigaction,NULL); + init_sigaction_with_handler(&sample_sigaction, sample_signal_handler); + sigaction_safe(SIGALRM, &sample_sigaction, NULL); - /* We don't use SA_IGN here because then the ignore action is inherited - by subprocesses, which we don't want. There is a unit test in - io.launcher.unix for this. */ - init_sigaction_with_handler(&ignore_sigaction, ignore_signal_handler); - sigaction_safe(SIGPIPE,&ignore_sigaction,NULL); - /* We send SIGUSR2 to the stdin_loop thread to interrupt it on FEP */ - sigaction_safe(SIGUSR2,&ignore_sigaction,NULL); + /* We don't use SA_IGN here because then the ignore action is inherited + by subprocesses, which we don't want. There is a unit test in + io.launcher.unix for this. */ + init_sigaction_with_handler(&ignore_sigaction, ignore_signal_handler); + sigaction_safe(SIGPIPE, &ignore_sigaction, NULL); + /* We send SIGUSR2 to the stdin_loop thread to interrupt it on FEP */ + sigaction_safe(SIGUSR2, &ignore_sigaction, NULL); } /* On Unix, shared fds such as stdin cannot be set to non-blocking mode -(http://homepages.tesco.net/J.deBoynePollard/FGA/dont-set-shared-file-descriptors-to-non-blocking-mode.html) -so we kludge around this by spawning a thread, which waits on a control pipe -for a signal, upon receiving this signal it reads one block of data from stdin -and writes it to a data pipe. Upon completion, it writes a 4-byte integer to -the size pipe, indicating how much data was written to the data pipe. - -The read end of the size pipe can be set to non-blocking. */ + (http://homepages.tesco.net/J.deBoynePollard/FGA/dont-set-shared-file-descriptors-to-non-blocking-mode.html) + so we kludge around this by spawning a thread, which waits on a control pipe + for a signal, upon receiving this signal it reads one block of data from + stdin and writes it to a data pipe. Upon completion, it writes a 4-byte + integer to the size pipe, indicating how much data was written to the data + pipe. + + The read end of the size pipe can be set to non-blocking. */ extern "C" { - int stdin_read; - int stdin_write; - - int control_read; - int control_write; - - int size_read; - int size_write; - - bool stdin_thread_initialized_p = false; - THREADHANDLE stdin_thread; - pthread_mutex_t stdin_mutex; -} - -void safe_close(int fd) -{ - if(close(fd) < 0) - fatal_error("error closing fd",errno); -} - -bool check_write(int fd, void *data, ssize_t size) -{ - if(write(fd,data,size) == size) - return true; - else - { - if(errno == EINTR) - return check_write(fd,data,size); - else - return false; - } -} - -void safe_write(int fd, void *data, ssize_t size) -{ - if(!check_write(fd,data,size)) - fatal_error("error writing fd",errno); -} - -void safe_write_nonblock(int fd, void *data, ssize_t size) -{ - if(!check_write(fd,data,size) && errno != EAGAIN) - fatal_error("error writing fd",errno); -} - -bool safe_read(int fd, void *data, ssize_t size) -{ - ssize_t bytes = read(fd,data,size); - if(bytes < 0) - { - if(errno == EINTR) - return safe_read(fd,data,size); - else - { - fatal_error("error reading fd",errno); - return false; - } - } - else - return (bytes == size); -} - -void *stdin_loop(void *arg) -{ - unsigned char buf[4096]; - bool loop_running = true; - - sigset_t mask; - sigfillset(&mask); - sigdelset(&mask, SIGUSR2); - sigdelset(&mask, SIGTTIN); - sigdelset(&mask, SIGTERM); - sigdelset(&mask, SIGQUIT); - pthread_sigmask(SIG_SETMASK, &mask, NULL); - - int unused; - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &unused); - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &unused); - - while(loop_running) - { - if(!safe_read(control_read,buf,1)) - break; - - if(buf[0] != 'X') - fatal_error("stdin_loop: bad data on control fd",buf[0]); - - for(;;) - { - /* If we fep, the parent thread will grab stdin_mutex and send us - SIGUSR2 to interrupt the read() call. */ - pthread_mutex_lock(&stdin_mutex); - pthread_mutex_unlock(&stdin_mutex); - ssize_t bytes = read(0,buf,sizeof(buf)); - if(bytes < 0) - { - if(errno == EINTR) - continue; - else - { - loop_running = false; - break; - } - } - else if(bytes >= 0) - { - safe_write(size_write,&bytes,sizeof(bytes)); - - if(!check_write(stdin_write,buf,bytes)) - loop_running = false; - break; - } - } - } - - safe_close(stdin_write); - safe_close(control_read); - - return NULL; -} - -void factor_vm::open_console() -{ - FACTOR_ASSERT(!stdin_thread_initialized_p); - safe_pipe(&control_read,&control_write); - safe_pipe(&size_read,&size_write); - safe_pipe(&stdin_read,&stdin_write); - stdin_thread = start_thread(stdin_loop,NULL); - stdin_thread_initialized_p = true; - pthread_mutex_init(&stdin_mutex, NULL); +int stdin_read; +int stdin_write; + +int control_read; +int control_write; + +int size_read; +int size_write; + +bool stdin_thread_initialized_p = false; +THREADHANDLE stdin_thread; +pthread_mutex_t stdin_mutex; +} + +void safe_close(int fd) { + if (close(fd) < 0) + fatal_error("error closing fd", errno); +} + +bool check_write(int fd, void* data, ssize_t size) { + if (write(fd, data, size) == size) + return true; + else { + if (errno == EINTR) + return check_write(fd, data, size); + else + return false; + } +} + +void safe_write(int fd, void* data, ssize_t size) { + if (!check_write(fd, data, size)) + fatal_error("error writing fd", errno); +} + +void safe_write_nonblock(int fd, void* data, ssize_t size) { + if (!check_write(fd, data, size) && errno != EAGAIN) + fatal_error("error writing fd", errno); +} + +bool safe_read(int fd, void* data, ssize_t size) { + ssize_t bytes = read(fd, data, size); + if (bytes < 0) { + if (errno == EINTR) + return safe_read(fd, data, size); + else { + fatal_error("error reading fd", errno); + return false; + } + } else + return (bytes == size); +} + +void* stdin_loop(void* arg) { + unsigned char buf[4096]; + bool loop_running = true; + + sigset_t mask; + sigfillset(&mask); + sigdelset(&mask, SIGUSR2); + sigdelset(&mask, SIGTTIN); + sigdelset(&mask, SIGTERM); + sigdelset(&mask, SIGQUIT); + pthread_sigmask(SIG_SETMASK, &mask, NULL); + + int unused; + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &unused); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &unused); + + while (loop_running) { + if (!safe_read(control_read, buf, 1)) + break; + + if (buf[0] != 'X') + fatal_error("stdin_loop: bad data on control fd", buf[0]); + + for (;;) { + /* If we fep, the parent thread will grab stdin_mutex and send us + SIGUSR2 to interrupt the read() call. */ + pthread_mutex_lock(&stdin_mutex); + pthread_mutex_unlock(&stdin_mutex); + ssize_t bytes = read(0, buf, sizeof(buf)); + if (bytes < 0) { + if (errno == EINTR) + continue; + else { + loop_running = false; + break; + } + } else if (bytes >= 0) { + safe_write(size_write, &bytes, sizeof(bytes)); + + if (!check_write(stdin_write, buf, bytes)) + loop_running = false; + break; + } + } + } + + safe_close(stdin_write); + safe_close(control_read); + + return NULL; +} + +void factor_vm::open_console() { + FACTOR_ASSERT(!stdin_thread_initialized_p); + safe_pipe(&control_read, &control_write); + safe_pipe(&size_read, &size_write); + safe_pipe(&stdin_read, &stdin_write); + stdin_thread = start_thread(stdin_loop, NULL); + stdin_thread_initialized_p = true; + pthread_mutex_init(&stdin_mutex, NULL); } /* This method is used to kill the stdin_loop before exiting from factor. -A Nvidia driver bug on Linux is the reason this has to be done, see: -http://www.nvnews.net/vbulletin/showthread.php?t=164619 */ -void factor_vm::close_console() -{ - if (stdin_thread_initialized_p) { - pthread_cancel(stdin_thread); - pthread_join(stdin_thread, 0); - } -} - -void factor_vm::lock_console() -{ - FACTOR_ASSERT(stdin_thread_initialized_p); - /* Lock the stdin_mutex and send the stdin_loop thread a signal to interrupt - any read() it has in progress. When the stdin loop iterates again, it will - try to lock the same mutex and wait until unlock_console() is called. */ - pthread_mutex_lock(&stdin_mutex); - pthread_kill(stdin_thread, SIGUSR2); -} - -void factor_vm::unlock_console() -{ - FACTOR_ASSERT(stdin_thread_initialized_p); - pthread_mutex_unlock(&stdin_mutex); -} - -void factor_vm::ignore_ctrl_c() -{ - sig_t ret; - do - { - ret = signal(SIGINT, SIG_DFL); - } - while(ret == SIG_ERR && errno == EINTR); -} - -void factor_vm::handle_ctrl_c() -{ - struct sigaction fep_sigaction; - init_sigaction_with_handler(&fep_sigaction, fep_signal_handler); - sigaction_safe(SIGINT,&fep_sigaction,NULL); -} - -void abort() -{ - sig_t ret; - do - { - ret = signal(SIGABRT, SIG_DFL); - } - while(ret == SIG_ERR && errno == EINTR); - - factor_vm::close_console(); - ::abort(); + A Nvidia driver bug on Linux is the reason this has to be done, see: + http://www.nvnews.net/vbulletin/showthread.php?t=164619 */ +void factor_vm::close_console() { + if (stdin_thread_initialized_p) { + pthread_cancel(stdin_thread); + pthread_join(stdin_thread, 0); + } +} + +void factor_vm::lock_console() { + FACTOR_ASSERT(stdin_thread_initialized_p); + /* Lock the stdin_mutex and send the stdin_loop thread a signal to interrupt + any read() it has in progress. When the stdin loop iterates again, it will + try to lock the same mutex and wait until unlock_console() is called. */ + pthread_mutex_lock(&stdin_mutex); + pthread_kill(stdin_thread, SIGUSR2); +} + +void factor_vm::unlock_console() { + FACTOR_ASSERT(stdin_thread_initialized_p); + pthread_mutex_unlock(&stdin_mutex); +} + +void factor_vm::ignore_ctrl_c() { + sig_t ret; + do { + ret = signal(SIGINT, SIG_DFL); + } while (ret == SIG_ERR && errno == EINTR); +} + +void factor_vm::handle_ctrl_c() { + struct sigaction fep_sigaction; + init_sigaction_with_handler(&fep_sigaction, fep_signal_handler); + sigaction_safe(SIGINT, &fep_sigaction, NULL); +} + +void abort() { + sig_t ret; + do { + ret = signal(SIGABRT, SIG_DFL); + } while (ret == SIG_ERR && errno == EINTR); + + factor_vm::close_console(); + ::abort(); } } diff --git a/vm/os-unix.hpp b/vm/os-unix.hpp index e8008bf5eb..35ffcd5d08 100644 --- a/vm/os-unix.hpp +++ b/vm/os-unix.hpp @@ -13,8 +13,7 @@ #include "atomic-gcc.hpp" -namespace factor -{ +namespace factor { typedef char vm_char; typedef char symbol_char; @@ -30,24 +29,21 @@ typedef char symbol_char; #define FTELL ftello #define FSEEK fseeko -#define OPEN_READ(path) fopen(path,"rb") -#define OPEN_WRITE(path) fopen(path,"wb") +#define OPEN_READ(path) fopen(path, "rb") +#define OPEN_WRITE(path) fopen(path, "wb") #define print_native_string(string) print_string(string) typedef pthread_t THREADHANDLE; -THREADHANDLE start_thread(void *(*start_routine)(void *),void *args); +THREADHANDLE start_thread(void* (*start_routine)(void*), void* args); inline static THREADHANDLE thread_id() { return pthread_self(); } u64 nano_count(); void sleep_nanos(u64 nsec); -void move_file(const vm_char *path1, const vm_char *path2); +void move_file(const vm_char* path1, const vm_char* path2); -static inline void breakpoint() -{ - __builtin_trap(); -} +static inline void breakpoint() { __builtin_trap(); } } diff --git a/vm/os-windows-x86.32.cpp b/vm/os-windows-x86.32.cpp index 61d38b5900..c564e13958 100644 --- a/vm/os-windows-x86.32.cpp +++ b/vm/os-windows-x86.32.cpp @@ -1,12 +1,10 @@ #include "master.hpp" -namespace factor -{ +namespace factor { -void factor_vm::c_to_factor_toplevel(cell quot) -{ - /* 32-bit Windows SEH is set up in basis/cpu/x86/32/windows/bootstrap.factor */ - c_to_factor(quot); +void factor_vm::c_to_factor_toplevel(cell quot) { + /* 32-bit Windows SEH set up in basis/cpu/x86/32/windows/bootstrap.factor */ + c_to_factor(quot); } } diff --git a/vm/os-windows-x86.64.cpp b/vm/os-windows-x86.64.cpp index 876d0c5771..6533287ce8 100644 --- a/vm/os-windows-x86.64.cpp +++ b/vm/os-windows-x86.64.cpp @@ -7,79 +7,78 @@ typedef unsigned char UBYTE; const UBYTE UNW_FLAG_EHANDLER = 0x1; struct UNWIND_INFO { - UBYTE Version:3; - UBYTE Flags:5; - UBYTE SizeOfProlog; - UBYTE CountOfCodes; - UBYTE FrameRegister:4; - UBYTE FrameOffset:4; - ULONG ExceptionHandler; - ULONG ExceptionData[1]; + UBYTE Version : 3; + UBYTE Flags : 5; + UBYTE SizeOfProlog; + UBYTE CountOfCodes; + UBYTE FrameRegister : 4; + UBYTE FrameOffset : 4; + ULONG ExceptionHandler; + ULONG ExceptionData[1]; }; struct seh_data { - UNWIND_INFO unwind_info; - RUNTIME_FUNCTION func; - UBYTE handler[32]; + UNWIND_INFO unwind_info; + RUNTIME_FUNCTION func; + UBYTE handler[32]; }; -void factor_vm::c_to_factor_toplevel(cell quot) -{ - /* The annoying thing about Win64 SEH is that the offsets in - * function tables are 32-bit integers, and the exception handler - * itself must reside between the start and end pointers, so - * we stick everything at the beginning of the code heap and - * generate a small trampoline that jumps to the real - * exception handler. */ - - seh_data *seh_area = (seh_data *)code->seh_area; - cell base = code->seg->start; - - /* Should look at generating this with the Factor assembler */ - - /* mov rax,0 */ - seh_area->handler[0] = 0x48; - seh_area->handler[1] = 0xb8; - seh_area->handler[2] = 0x0; - seh_area->handler[3] = 0x0; - seh_area->handler[4] = 0x0; - seh_area->handler[5] = 0x0; - seh_area->handler[6] = 0x0; - seh_area->handler[7] = 0x0; - seh_area->handler[8] = 0x0; - seh_area->handler[9] = 0x0; - - /* jmp rax */ - seh_area->handler[10] = 0x48; - seh_area->handler[11] = 0xff; - seh_area->handler[12] = 0xe0; - - /* Store address of exception handler in the operand of the 'mov' */ - cell handler = (cell)&factor::exception_handler; - memcpy(&seh_area->handler[2],&handler,sizeof(cell)); - - UNWIND_INFO *unwind_info = &seh_area->unwind_info; - unwind_info->Version = 1; - unwind_info->Flags = UNW_FLAG_EHANDLER; - unwind_info->SizeOfProlog = 0; - unwind_info->CountOfCodes = 0; - unwind_info->FrameRegister = 0; - unwind_info->FrameOffset = 0; - unwind_info->ExceptionHandler = (DWORD)((cell)&seh_area->handler[0] - base); - unwind_info->ExceptionData[0] = 0; - - RUNTIME_FUNCTION *func = &seh_area->func; - func->BeginAddress = 0; - func->EndAddress = (DWORD)(code->seg->end - base); - func->UnwindData = (DWORD)((cell)&seh_area->unwind_info - base); - - if(!RtlAddFunctionTable(func,1,base)) - fatal_error("RtlAddFunctionTable() failed",0); - - c_to_factor(quot); - - if(!RtlDeleteFunctionTable(func)) - fatal_error("RtlDeleteFunctionTable() failed",0); +void factor_vm::c_to_factor_toplevel(cell quot) { + /* The annoying thing about Win64 SEH is that the offsets in + * function tables are 32-bit integers, and the exception handler + * itself must reside between the start and end pointers, so + * we stick everything at the beginning of the code heap and + * generate a small trampoline that jumps to the real + * exception handler. */ + + seh_data* seh_area = (seh_data*)code->seh_area; + cell base = code->seg->start; + + /* Should look at generating this with the Factor assembler */ + + /* mov rax,0 */ + seh_area->handler[0] = 0x48; + seh_area->handler[1] = 0xb8; + seh_area->handler[2] = 0x0; + seh_area->handler[3] = 0x0; + seh_area->handler[4] = 0x0; + seh_area->handler[5] = 0x0; + seh_area->handler[6] = 0x0; + seh_area->handler[7] = 0x0; + seh_area->handler[8] = 0x0; + seh_area->handler[9] = 0x0; + + /* jmp rax */ + seh_area->handler[10] = 0x48; + seh_area->handler[11] = 0xff; + seh_area->handler[12] = 0xe0; + + /* Store address of exception handler in the operand of the 'mov' */ + cell handler = (cell) & factor::exception_handler; + memcpy(&seh_area->handler[2], &handler, sizeof(cell)); + + UNWIND_INFO* unwind_info = &seh_area->unwind_info; + unwind_info->Version = 1; + unwind_info->Flags = UNW_FLAG_EHANDLER; + unwind_info->SizeOfProlog = 0; + unwind_info->CountOfCodes = 0; + unwind_info->FrameRegister = 0; + unwind_info->FrameOffset = 0; + unwind_info->ExceptionHandler = (DWORD)((cell) & seh_area->handler[0] - base); + unwind_info->ExceptionData[0] = 0; + + RUNTIME_FUNCTION* func = &seh_area->func; + func->BeginAddress = 0; + func->EndAddress = (DWORD)(code->seg->end - base); + func->UnwindData = (DWORD)((cell) & seh_area->unwind_info - base); + + if (!RtlAddFunctionTable(func, 1, base)) + fatal_error("RtlAddFunctionTable() failed", 0); + + c_to_factor(quot); + + if (!RtlDeleteFunctionTable(func)) + fatal_error("RtlDeleteFunctionTable() failed", 0); } } diff --git a/vm/os-windows.32.hpp b/vm/os-windows.32.hpp index c6e4c8b7b3..e6e369a95c 100644 --- a/vm/os-windows.32.hpp +++ b/vm/os-windows.32.hpp @@ -1,35 +1,34 @@ #include "atomic-cl-32.hpp" -namespace factor -{ +namespace factor { #define ESP Esp #define EIP Eip typedef struct DECLSPEC_ALIGN(16) _M128A { - ULONGLONG Low; - LONGLONG High; + ULONGLONG Low; + LONGLONG High; } M128A, *PM128A; -/* The ExtendedRegisters field of the x86.32 CONTEXT structure uses this layout; however, - * this structure is only made available from winnt.h on x86.64 */ +/* The ExtendedRegisters field of the x86.32 CONTEXT structure uses this layout; + * however, this structure is only made available from winnt.h on x86.64 */ typedef struct _XMM_SAVE_AREA32 { - WORD ControlWord; /* 000 */ - WORD StatusWord; /* 002 */ - BYTE TagWord; /* 004 */ - BYTE Reserved1; /* 005 */ - WORD ErrorOpcode; /* 006 */ - DWORD ErrorOffset; /* 008 */ - WORD ErrorSelector; /* 00c */ - WORD Reserved2; /* 00e */ - DWORD DataOffset; /* 010 */ - WORD DataSelector; /* 014 */ - WORD Reserved3; /* 016 */ - DWORD MxCsr; /* 018 */ - DWORD MxCsr_Mask; /* 01c */ - M128A FloatRegisters[8]; /* 020 */ - M128A XmmRegisters[16]; /* 0a0 */ - BYTE Reserved4[96]; /* 1a0 */ + WORD ControlWord; /* 000 */ + WORD StatusWord; /* 002 */ + BYTE TagWord; /* 004 */ + BYTE Reserved1; /* 005 */ + WORD ErrorOpcode; /* 006 */ + DWORD ErrorOffset; /* 008 */ + WORD ErrorSelector; /* 00c */ + WORD Reserved2; /* 00e */ + DWORD DataOffset; /* 010 */ + WORD DataSelector; /* 014 */ + WORD Reserved3; /* 016 */ + DWORD MxCsr; /* 018 */ + DWORD MxCsr_Mask; /* 01c */ + M128A FloatRegisters[8]; /* 020 */ + M128A XmmRegisters[16]; /* 0a0 */ + BYTE Reserved4[96]; /* 1a0 */ } XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; #define X87SW(ctx) (ctx)->FloatSave.StatusWord diff --git a/vm/os-windows.64.hpp b/vm/os-windows.64.hpp index 7dad29c6d2..ef4c8cae41 100644 --- a/vm/os-windows.64.hpp +++ b/vm/os-windows.64.hpp @@ -1,7 +1,6 @@ #include "atomic-cl-64.hpp" -namespace factor -{ +namespace factor { #define ESP Rsp #define EIP Rip diff --git a/vm/os-windows.cpp b/vm/os-windows.cpp index e48bdca8c0..3182fca2c3 100644 --- a/vm/os-windows.cpp +++ b/vm/os-windows.cpp @@ -1,411 +1,347 @@ #include "master.hpp" -namespace factor -{ +namespace factor { HMODULE hFactorDll; -void factor_vm::init_ffi() -{ - hFactorDll = GetModuleHandle(FACTOR_DLL); - if(!hFactorDll) - fatal_error("GetModuleHandle() failed", 0); +void factor_vm::init_ffi() { + hFactorDll = GetModuleHandle(FACTOR_DLL); + if (!hFactorDll) + fatal_error("GetModuleHandle() failed", 0); } -void factor_vm::ffi_dlopen(dll *dll) -{ - dll->handle = LoadLibraryEx((WCHAR *)alien_offset(dll->path), NULL, 0); +void factor_vm::ffi_dlopen(dll* dll) { + dll->handle = LoadLibraryEx((WCHAR*)alien_offset(dll->path), NULL, 0); } -void *factor_vm::ffi_dlsym(dll *dll, symbol_char *symbol) -{ - return (void *)GetProcAddress(dll ? (HMODULE)dll->handle : hFactorDll, symbol); +void* factor_vm::ffi_dlsym(dll* dll, symbol_char* symbol) { + return (void*)GetProcAddress(dll ? (HMODULE) dll->handle : hFactorDll, + symbol); } -void *factor_vm::ffi_dlsym_raw(dll *dll, symbol_char *symbol) -{ - return ffi_dlsym(dll, symbol); +void* factor_vm::ffi_dlsym_raw(dll* dll, symbol_char* symbol) { + return ffi_dlsym(dll, symbol); } -void factor_vm::ffi_dlclose(dll *dll) -{ - FreeLibrary((HMODULE)dll->handle); - dll->handle = NULL; +void factor_vm::ffi_dlclose(dll* dll) { + FreeLibrary((HMODULE) dll->handle); + dll->handle = NULL; } -BOOL factor_vm::windows_stat(vm_char *path) -{ - BY_HANDLE_FILE_INFORMATION bhfi; - HANDLE h = CreateFileW(path, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if(h == INVALID_HANDLE_VALUE) - { - // FindFirstFile is the only call that can stat c:\pagefile.sys - WIN32_FIND_DATA st; - HANDLE h; - - if(INVALID_HANDLE_VALUE == (h = FindFirstFile(path, &st))) - return false; - FindClose(h); - return true; - } - BOOL ret = GetFileInformationByHandle(h, &bhfi); - CloseHandle(h); - return ret; +BOOL factor_vm::windows_stat(vm_char* path) { + BY_HANDLE_FILE_INFORMATION bhfi; + HANDLE h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + + if (h == INVALID_HANDLE_VALUE) { + // FindFirstFile is the only call that can stat c:\pagefile.sys + WIN32_FIND_DATA st; + HANDLE h; + + if (INVALID_HANDLE_VALUE == (h = FindFirstFile(path, &st))) + return false; + FindClose(h); + return true; + } + BOOL ret = GetFileInformationByHandle(h, &bhfi); + CloseHandle(h); + return ret; } -void factor_vm::windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int length) -{ - wcsncpy(temp_path, full_path, length - 1); - size_t full_path_len = wcslen(full_path); - if (full_path_len < length - 1) - wcsncat(temp_path, L".image", length - full_path_len - 1); - temp_path[length - 1] = 0; +void factor_vm::windows_image_path(vm_char* full_path, vm_char* temp_path, + unsigned int length) { + wcsncpy(temp_path, full_path, length - 1); + size_t full_path_len = wcslen(full_path); + if (full_path_len < length - 1) + wcsncat(temp_path, L".image", length - full_path_len - 1); + temp_path[length - 1] = 0; } /* You must free() this yourself. */ -const vm_char *factor_vm::default_image_path() -{ - vm_char full_path[MAX_UNICODE_PATH]; - vm_char *ptr; - vm_char temp_path[MAX_UNICODE_PATH]; +const vm_char* factor_vm::default_image_path() { + vm_char full_path[MAX_UNICODE_PATH]; + vm_char* ptr; + vm_char temp_path[MAX_UNICODE_PATH]; - if(!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH)) - fatal_error("GetModuleFileName() failed", 0); + if (!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH)) + fatal_error("GetModuleFileName() failed", 0); - if((ptr = wcsrchr(full_path, '.'))) - *ptr = 0; + if ((ptr = wcsrchr(full_path, '.'))) + *ptr = 0; - wcsncpy(temp_path, full_path, MAX_UNICODE_PATH - 1); - size_t full_path_len = wcslen(full_path); - if (full_path_len < MAX_UNICODE_PATH - 1) - wcsncat(temp_path, L".image", MAX_UNICODE_PATH - full_path_len - 1); - temp_path[MAX_UNICODE_PATH - 1] = 0; + wcsncpy(temp_path, full_path, MAX_UNICODE_PATH - 1); + size_t full_path_len = wcslen(full_path); + if (full_path_len < MAX_UNICODE_PATH - 1) + wcsncat(temp_path, L".image", MAX_UNICODE_PATH - full_path_len - 1); + temp_path[MAX_UNICODE_PATH - 1] = 0; - return safe_strdup(temp_path); + return safe_strdup(temp_path); } /* You must free() this yourself. */ -const vm_char *factor_vm::vm_executable_path() -{ - vm_char full_path[MAX_UNICODE_PATH]; - if(!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH)) - fatal_error("GetModuleFileName() failed", 0); - return safe_strdup(full_path); +const vm_char* factor_vm::vm_executable_path() { + vm_char full_path[MAX_UNICODE_PATH]; + if (!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH)) + fatal_error("GetModuleFileName() failed", 0); + return safe_strdup(full_path); } -void factor_vm::primitive_existsp() -{ - vm_char *path = untag_check(ctx->pop())->data(); - ctx->push(tag_boolean(windows_stat(path))); +void factor_vm::primitive_existsp() { + vm_char* path = untag_check(ctx->pop())->data(); + ctx->push(tag_boolean(windows_stat(path))); } -segment::segment(cell size_, bool executable_p) -{ - size = size_; +segment::segment(cell size_, bool executable_p) { + size = size_; - char *mem; - DWORD ignore; + char* mem; + DWORD ignore; - if((mem = (char *)VirtualAlloc(NULL, getpagesize() * 2 + size, - MEM_COMMIT, executable_p ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE)) == 0) - out_of_memory(); + if ((mem = (char*)VirtualAlloc( + NULL, getpagesize() * 2 + size, MEM_COMMIT, + executable_p ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE)) == + 0) + out_of_memory(); - if (!VirtualProtect(mem, getpagesize(), PAGE_NOACCESS, &ignore)) - fatal_error("Cannot allocate low guard page", (cell)mem); + if (!VirtualProtect(mem, getpagesize(), PAGE_NOACCESS, &ignore)) + fatal_error("Cannot allocate low guard page", (cell) mem); - if (!VirtualProtect(mem + size + getpagesize(), - getpagesize(), PAGE_NOACCESS, &ignore)) - fatal_error("Cannot allocate high guard page", (cell)mem); + if (!VirtualProtect(mem + size + getpagesize(), getpagesize(), PAGE_NOACCESS, + &ignore)) + fatal_error("Cannot allocate high guard page", (cell) mem); - start = (cell)mem + getpagesize(); - end = start + size; + start = (cell) mem + getpagesize(); + end = start + size; } -segment::~segment() -{ - SYSTEM_INFO si; - GetSystemInfo(&si); - if(!VirtualFree((void*)(start - si.dwPageSize), 0, MEM_RELEASE)) - fatal_error("Segment deallocation failed",0); +segment::~segment() { + SYSTEM_INFO si; + GetSystemInfo(&si); + if (!VirtualFree((void*)(start - si.dwPageSize), 0, MEM_RELEASE)) + fatal_error("Segment deallocation failed", 0); } -long getpagesize() -{ - static long g_pagesize = 0; - if(!g_pagesize) - { - SYSTEM_INFO system_info; - GetSystemInfo (&system_info); - g_pagesize = system_info.dwPageSize; - } - return g_pagesize; +long getpagesize() { + static long g_pagesize = 0; + if (!g_pagesize) { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + g_pagesize = system_info.dwPageSize; + } + return g_pagesize; } -void code_heap::guard_safepoint() -{ - DWORD ignore; - if (!VirtualProtect(safepoint_page, getpagesize(), PAGE_NOACCESS, &ignore)) - fatal_error("Cannot protect safepoint guard page", (cell)safepoint_page); +void code_heap::guard_safepoint() { + DWORD ignore; + if (!VirtualProtect(safepoint_page, getpagesize(), PAGE_NOACCESS, &ignore)) + fatal_error("Cannot protect safepoint guard page", (cell) safepoint_page); } -void code_heap::unguard_safepoint() -{ - DWORD ignore; - if (!VirtualProtect(safepoint_page, getpagesize(), PAGE_READWRITE, &ignore)) - fatal_error("Cannot unprotect safepoint guard page", (cell)safepoint_page); +void code_heap::unguard_safepoint() { + DWORD ignore; + if (!VirtualProtect(safepoint_page, getpagesize(), PAGE_READWRITE, &ignore)) + fatal_error("Cannot unprotect safepoint guard page", (cell) safepoint_page); } -void factor_vm::move_file(const vm_char *path1, const vm_char *path2) -{ - if(MoveFileEx((path1),(path2),MOVEFILE_REPLACE_EXISTING) == false) - general_error(ERROR_IO,tag_fixnum(GetLastError()),false_object); +void factor_vm::move_file(const vm_char* path1, const vm_char* path2) { + if (MoveFileEx((path1), (path2), MOVEFILE_REPLACE_EXISTING) == false) + general_error(ERROR_IO, tag_fixnum(GetLastError()), false_object); } void factor_vm::init_signals() {} -THREADHANDLE start_thread(void *(*start_routine)(void *), void *args) -{ - return (void *)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, args, 0, 0); +THREADHANDLE start_thread(void* (*start_routine)(void*), void* args) { + return (void*)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) start_routine, + args, 0, 0); } -u64 nano_count() -{ - static double scale_factor; +u64 nano_count() { + static double scale_factor; - static u32 hi = 0; - static u32 lo = 0; + static u32 hi = 0; + static u32 lo = 0; - LARGE_INTEGER count; - BOOL ret = QueryPerformanceCounter(&count); - if(ret == 0) - fatal_error("QueryPerformanceCounter", 0); + LARGE_INTEGER count; + BOOL ret = QueryPerformanceCounter(&count); + if (ret == 0) + fatal_error("QueryPerformanceCounter", 0); - if(scale_factor == 0.0) - { - LARGE_INTEGER frequency; - BOOL ret = QueryPerformanceFrequency(&frequency); - if(ret == 0) - fatal_error("QueryPerformanceFrequency", 0); - scale_factor = (1000000000.0 / frequency.QuadPart); - } + if (scale_factor == 0.0) { + LARGE_INTEGER frequency; + BOOL ret = QueryPerformanceFrequency(&frequency); + if (ret == 0) + fatal_error("QueryPerformanceFrequency", 0); + scale_factor = (1000000000.0 / frequency.QuadPart); + } #ifdef FACTOR_64 - hi = count.HighPart; + hi = count.HighPart; #else - /* On VirtualBox, QueryPerformanceCounter does not increment + /* On VirtualBox, QueryPerformanceCounter does not increment the high part every time the low part overflows. Workaround. */ - if(lo > count.LowPart) - hi++; + if (lo > count.LowPart) + hi++; #endif - lo = count.LowPart; + lo = count.LowPart; - return (u64)((((u64)hi << 32) | (u64)lo) * scale_factor); + return (u64)((((u64) hi << 32) | (u64) lo) * scale_factor); } -void sleep_nanos(u64 nsec) -{ - Sleep((DWORD)(nsec/1000000)); -} +void sleep_nanos(u64 nsec) { Sleep((DWORD)(nsec / 1000000)); } -typedef enum _EXCEPTION_DISPOSITION -{ - ExceptionContinueExecution = 0, - ExceptionContinueSearch = 1, - ExceptionNestedException = 2, - ExceptionCollidedUnwind = 3 +typedef enum _EXCEPTION_DISPOSITION { + ExceptionContinueExecution = 0, + ExceptionContinueSearch = 1, + ExceptionNestedException = 2, + ExceptionCollidedUnwind = 3 } EXCEPTION_DISPOSITION; -LONG factor_vm::exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch) -{ - switch (e->ExceptionCode) - { - case EXCEPTION_ACCESS_VIOLATION: - signal_fault_addr = e->ExceptionInformation[1]; - verify_memory_protection_error(signal_fault_addr); - dispatch_signal_handler( - (cell*)&c->ESP, - (cell*)&c->EIP, - (cell)factor::memory_signal_handler_impl - ); - break; - - case STATUS_FLOAT_DENORMAL_OPERAND: - case STATUS_FLOAT_DIVIDE_BY_ZERO: - case STATUS_FLOAT_INEXACT_RESULT: - case STATUS_FLOAT_INVALID_OPERATION: - case STATUS_FLOAT_OVERFLOW: - case STATUS_FLOAT_STACK_CHECK: - case STATUS_FLOAT_UNDERFLOW: - case STATUS_FLOAT_MULTIPLE_FAULTS: - case STATUS_FLOAT_MULTIPLE_TRAPS: +LONG factor_vm::exception_handler(PEXCEPTION_RECORD e, void* frame, PCONTEXT c, + void* dispatch) { + switch (e->ExceptionCode) { + case EXCEPTION_ACCESS_VIOLATION: + signal_fault_addr = e->ExceptionInformation[1]; + verify_memory_protection_error(signal_fault_addr); + dispatch_signal_handler((cell*)&c->ESP, (cell*)&c->EIP, + (cell) factor::memory_signal_handler_impl); + break; + + case STATUS_FLOAT_DENORMAL_OPERAND: + case STATUS_FLOAT_DIVIDE_BY_ZERO: + case STATUS_FLOAT_INEXACT_RESULT: + case STATUS_FLOAT_INVALID_OPERATION: + case STATUS_FLOAT_OVERFLOW: + case STATUS_FLOAT_STACK_CHECK: + case STATUS_FLOAT_UNDERFLOW: + case STATUS_FLOAT_MULTIPLE_FAULTS: + case STATUS_FLOAT_MULTIPLE_TRAPS: #ifdef FACTOR_64 - signal_fpu_status = fpu_status(MXCSR(c)); + signal_fpu_status = fpu_status(MXCSR(c)); #else - signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c)); + signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c)); - /* This seems to have no effect */ - X87SW(c) = 0; + /* This seems to have no effect */ + X87SW(c) = 0; #endif - MXCSR(c) &= 0xffffffc0; - dispatch_signal_handler( - (cell*)&c->ESP, - (cell*)&c->EIP, - (cell)factor::fp_signal_handler_impl - ); - break; - default: - signal_number = e->ExceptionCode; - dispatch_signal_handler( - (cell*)&c->ESP, - (cell*)&c->EIP, - (cell)factor::synchronous_signal_handler_impl - ); - break; - } - - return ExceptionContinueExecution; + MXCSR(c) &= 0xffffffc0; + dispatch_signal_handler((cell*)&c->ESP, (cell*)&c->EIP, + (cell) factor::fp_signal_handler_impl); + break; + default: + signal_number = e->ExceptionCode; + dispatch_signal_handler((cell*)&c->ESP, (cell*)&c->EIP, + (cell) factor::synchronous_signal_handler_impl); + break; + } + + return ExceptionContinueExecution; } -VM_C_API LONG exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch) -{ - if (factor_vm::fatal_erroring_p) - return ExceptionContinueSearch; +VM_C_API LONG exception_handler(PEXCEPTION_RECORD e, void* frame, PCONTEXT c, + void* dispatch) { + if (factor_vm::fatal_erroring_p) + return ExceptionContinueSearch; - factor_vm *vm = current_vm_p(); - if (vm) - return vm->exception_handler(e,frame,c,dispatch); - else - return ExceptionContinueSearch; + factor_vm* vm = current_vm_p(); + if (vm) + return vm->exception_handler(e, frame, c, dispatch); + else + return ExceptionContinueSearch; } -static BOOL WINAPI ctrl_handler(DWORD dwCtrlType) -{ - switch (dwCtrlType) { - case CTRL_C_EVENT: - { - /* The CtrlHandler runs in its own thread without stopping the main thread. - Since in practice nobody uses the multi-VM stuff yet, we just grab the first - VM we can get. This will not be a good idea when we actually support native - threads. */ - FACTOR_ASSERT(thread_vms.size() == 1); - factor_vm *vm = thread_vms.begin()->second; - vm->safepoint.enqueue_fep(vm); - return TRUE; - } - default: - return FALSE; - } +static BOOL WINAPI ctrl_handler(DWORD dwCtrlType) { + switch (dwCtrlType) { + case CTRL_C_EVENT: { + /* The CtrlHandler runs in its own thread without stopping the main + thread. Since in practice nobody uses the multi-VM stuff yet, we just + grab the first VM we can get. This will not be a good idea when we + actually support native threads. */ + FACTOR_ASSERT(thread_vms.size() == 1); + factor_vm* vm = thread_vms.begin()->second; + vm->safepoint.enqueue_fep(vm); + return TRUE; + } + default: + return FALSE; + } } -void factor_vm::open_console() -{ - handle_ctrl_c(); -} +void factor_vm::open_console() { handle_ctrl_c(); } -void factor_vm::ignore_ctrl_c() -{ - SetConsoleCtrlHandler(factor::ctrl_handler, FALSE); +void factor_vm::ignore_ctrl_c() { + SetConsoleCtrlHandler(factor::ctrl_handler, FALSE); } -void factor_vm::handle_ctrl_c() -{ - SetConsoleCtrlHandler(factor::ctrl_handler, TRUE); +void factor_vm::handle_ctrl_c() { + SetConsoleCtrlHandler(factor::ctrl_handler, TRUE); } -void factor_vm::lock_console() -{ -} +void factor_vm::lock_console() {} -void factor_vm::unlock_console() -{ -} +void factor_vm::unlock_console() {} -void factor_vm::close_console() -{ -} +void factor_vm::close_console() {} -void factor_vm::sampler_thread_loop() -{ - LARGE_INTEGER counter, new_counter, units_per_second; - DWORD ok; - - ok = QueryPerformanceFrequency(&units_per_second); - FACTOR_ASSERT(ok); - - ok = QueryPerformanceCounter(&counter); - FACTOR_ASSERT(ok); - - counter.QuadPart *= samples_per_second; - while (atomic::load(&sampling_profiler_p)) - { - SwitchToThread(); - ok = QueryPerformanceCounter(&new_counter); - FACTOR_ASSERT(ok); - new_counter.QuadPart *= samples_per_second; - cell samples = 0; - while (new_counter.QuadPart - counter.QuadPart > units_per_second.QuadPart) - { - ++samples; - counter.QuadPart += units_per_second.QuadPart; - } - - if (samples > 0) - { - DWORD suscount = SuspendThread(thread); - FACTOR_ASSERT(suscount == 0); - - CONTEXT context; - memset((void*)&context, 0, sizeof(CONTEXT)); - context.ContextFlags = CONTEXT_CONTROL; - BOOL context_ok = GetThreadContext(thread, &context); - FACTOR_ASSERT(context_ok); - - suscount = ResumeThread(thread); - FACTOR_ASSERT(suscount == 1); - - safepoint.enqueue_samples(this, samples, context.EIP, false); - } - } -} +void factor_vm::sampler_thread_loop() { + LARGE_INTEGER counter, new_counter, units_per_second; + DWORD ok; + + ok = QueryPerformanceFrequency(&units_per_second); + FACTOR_ASSERT(ok); + + ok = QueryPerformanceCounter(&counter); + FACTOR_ASSERT(ok); + + counter.QuadPart *= samples_per_second; + while (atomic::load(&sampling_profiler_p)) { + SwitchToThread(); + ok = QueryPerformanceCounter(&new_counter); + FACTOR_ASSERT(ok); + new_counter.QuadPart *= samples_per_second; + cell samples = 0; + while (new_counter.QuadPart - counter.QuadPart > + units_per_second.QuadPart) { + ++samples; + counter.QuadPart += units_per_second.QuadPart; + } -static DWORD WINAPI sampler_thread_entry(LPVOID parent_vm) -{ - static_cast(parent_vm)->sampler_thread_loop(); - return 0; + if (samples > 0) { + DWORD suscount = SuspendThread(thread); + FACTOR_ASSERT(suscount == 0); + + CONTEXT context; + memset((void*)&context, 0, sizeof(CONTEXT)); + context.ContextFlags = CONTEXT_CONTROL; + BOOL context_ok = GetThreadContext(thread, &context); + FACTOR_ASSERT(context_ok); + + suscount = ResumeThread(thread); + FACTOR_ASSERT(suscount == 1); + + safepoint.enqueue_samples(this, samples, context.EIP, false); + } + } } -void factor_vm::start_sampling_profiler_timer() -{ - sampler_thread = CreateThread( - NULL, - 0, - &sampler_thread_entry, - static_cast(this), - 0, - NULL - ); +static DWORD WINAPI sampler_thread_entry(LPVOID parent_vm) { + static_cast(parent_vm)->sampler_thread_loop(); + return 0; } -void factor_vm::end_sampling_profiler_timer() -{ - atomic::store(&sampling_profiler_p, false); - DWORD wait_result = WaitForSingleObject(sampler_thread, - 3000*(DWORD)samples_per_second); - if (wait_result != WAIT_OBJECT_0) - TerminateThread(sampler_thread, 0); - sampler_thread = NULL; +void factor_vm::start_sampling_profiler_timer() { + sampler_thread = CreateThread(NULL, 0, &sampler_thread_entry, + static_cast(this), 0, NULL); } -void abort() -{ - ::abort(); +void factor_vm::end_sampling_profiler_timer() { + atomic::store(&sampling_profiler_p, false); + DWORD wait_result = + WaitForSingleObject(sampler_thread, 3000 * (DWORD) samples_per_second); + if (wait_result != WAIT_OBJECT_0) + TerminateThread(sampler_thread, 0); + sampler_thread = NULL; } +void abort() { ::abort(); } + } diff --git a/vm/os-windows.hpp b/vm/os-windows.hpp index 30352c13c2..f4c3897833 100644 --- a/vm/os-windows.hpp +++ b/vm/os-windows.hpp @@ -1,8 +1,8 @@ #include #ifndef wcslen - /* for cygwin */ - #include +/* for cygwin */ +#include #endif #undef _WIN32_WINNT @@ -16,15 +16,14 @@ #include #ifdef _MSC_VER - #undef min - #undef max +#undef min +#undef max #endif /* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */ #define EPOCH_OFFSET 0x019db1ded53e8000LL -namespace factor -{ +namespace factor { typedef wchar_t vm_char; typedef char symbol_char; @@ -40,59 +39,55 @@ typedef HANDLE THREADHANDLE; #define STRDUP _wcsdup #ifdef _MSC_VER - #define FTELL ftell - #define FSEEK fseek - #define SNPRINTF _snprintf +#define FTELL ftell +#define FSEEK fseek +#define SNPRINTF _snprintf #else - #define FTELL ftello64 - #define FSEEK fseeko64 - #define SNPRINTF snprintf +#define FTELL ftello64 +#define FSEEK fseeko64 +#define SNPRINTF snprintf #endif #define FACTOR_OS_STRING "windows" #define FACTOR_DLL NULL -// SSE traps raise these exception codes, which are defined in internal NT headers +// SSE traps raise these exception codes, which are defined in internal NT +// headers // but not winbase.h #ifndef STATUS_FLOAT_MULTIPLE_FAULTS #define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4 #endif #ifndef STATUS_FLOAT_MULTIPLE_TRAPS -#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5 +#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5 #endif -#define OPEN_READ(path) _wfopen((path),L"rb") -#define OPEN_WRITE(path) _wfopen((path),L"wb") +#define OPEN_READ(path) _wfopen((path), L"rb") +#define OPEN_WRITE(path) _wfopen((path), L"wb") inline static void early_init() {} u64 nano_count(); void sleep_nanos(u64 nsec); long getpagesize(); -void move_file(const vm_char *path1, const vm_char *path2); -VM_C_API LONG exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch); -THREADHANDLE start_thread(void *(*start_routine)(void *),void *args); - -inline static THREADHANDLE thread_id() -{ - DWORD id = GetCurrentThreadId(); - HANDLE threadHandle = OpenThread( - THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, - FALSE, - id - ); - FACTOR_ASSERT(threadHandle != NULL); - return threadHandle; +void move_file(const vm_char* path1, const vm_char* path2); +VM_C_API LONG exception_handler(PEXCEPTION_RECORD e, void* frame, PCONTEXT c, + void* dispatch); +THREADHANDLE start_thread(void* (*start_routine)(void*), void* args); + +inline static THREADHANDLE thread_id() { + DWORD id = GetCurrentThreadId(); + HANDLE threadHandle = OpenThread( + THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, FALSE, + id); + FACTOR_ASSERT(threadHandle != NULL); + return threadHandle; } -inline static void breakpoint() -{ - DebugBreak(); -} +inline static void breakpoint() { DebugBreak(); } -#define CODE_TO_FUNCTION_POINTER(code) (void)0 -#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void)0 +#define CODE_TO_FUNCTION_POINTER(code) (void) 0 +#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void) 0 #define FUNCTION_CODE_POINTER(ptr) ptr #define FUNCTION_TOC_POINTER(ptr) ptr } -- 2.34.1