]> gitweb.factorcode.org Git - factor.git/blob - vm/os-windows-nt.cpp
Safe SEH is better than abstinence
[factor.git] / vm / os-windows-nt.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 THREADHANDLE start_thread(void *(*start_routine)(void *), void *args)
7 {
8         return (void *)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, args, 0, 0);
9 }
10
11 u64 system_micros()
12 {
13         FILETIME t;
14         GetSystemTimeAsFileTime(&t);
15         return (((u64)t.dwLowDateTime | (u64)t.dwHighDateTime<<32)
16                 - EPOCH_OFFSET) / 10;
17 }
18
19 u64 nano_count()
20 {
21         LARGE_INTEGER count;
22         LARGE_INTEGER frequency;
23         static u32 hi = 0;
24         static u32 lo = 0;
25         BOOL ret;
26         ret = QueryPerformanceCounter(&count);
27         if(ret == 0)
28                 fatal_error("QueryPerformanceCounter", 0);
29         ret = QueryPerformanceFrequency(&frequency);
30         if(ret == 0)
31                 fatal_error("QueryPerformanceFrequency", 0);
32
33 #ifdef FACTOR_64
34         hi = count.HighPart;
35 #else
36         /* On VirtualBox, QueryPerformanceCounter does not increment
37         the high part every time the low part overflows.  Workaround. */
38         if(lo > count.LowPart)
39                 hi++;
40 #endif
41         lo = count.LowPart;
42
43         return (u64)((((u64)hi << 32) | (u64)lo)*(1000000000.0/frequency.QuadPart));
44 }
45
46 void sleep_nanos(u64 nsec)
47 {
48         Sleep((DWORD)(nsec/1000000));
49 }
50
51 LONG factor_vm::exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch)
52 {
53         c->ESP = (cell)fix_callstack_top((stack_frame *)c->ESP);
54         signal_callstack_top = (stack_frame *)c->ESP;
55
56         switch (e->ExceptionCode)
57         {
58         case EXCEPTION_ACCESS_VIOLATION:
59                 signal_fault_addr = e->ExceptionInformation[1];
60                 c->EIP = (cell)factor::memory_signal_handler_impl;
61                 break;
62
63         case STATUS_FLOAT_DENORMAL_OPERAND:
64         case STATUS_FLOAT_DIVIDE_BY_ZERO:
65         case STATUS_FLOAT_INEXACT_RESULT:
66         case STATUS_FLOAT_INVALID_OPERATION:
67         case STATUS_FLOAT_OVERFLOW:
68         case STATUS_FLOAT_STACK_CHECK:
69         case STATUS_FLOAT_UNDERFLOW:
70         case STATUS_FLOAT_MULTIPLE_FAULTS:
71         case STATUS_FLOAT_MULTIPLE_TRAPS:
72 #ifdef FACTOR_64
73                 signal_fpu_status = fpu_status(MXCSR(c));
74 #else
75                 signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));
76                 X87SW(c) = 0;
77 #endif
78                 MXCSR(c) &= 0xffffffc0;
79                 c->EIP = (cell)factor::fp_signal_handler_impl;
80                 break;
81         default:
82                 signal_number = e->ExceptionCode;
83                 c->EIP = (cell)factor::misc_signal_handler_impl;
84                 break;
85         }
86
87         return ExceptionContinueExecution;
88 }
89
90 extern "C" LONG exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch)
91 {
92         return current_vm()->exception_handler(e,frame,c,dispatch);
93 }
94
95 void factor_vm::c_to_factor_toplevel(cell quot)
96 {
97         c_to_factor(quot);
98 }
99
100 void factor_vm::open_console()
101 {
102 }
103
104 }