]> gitweb.factorcode.org Git - factor.git/blob - vm/os-windows-nt.cpp
2d5881252a10872e4ab6b123de9260c8cc0cdfb5
[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_POINTERS pe)
52 {
53         PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
54         CONTEXT *c = (CONTEXT*)pe->ContextRecord;
55
56         c->ESP = (cell)fix_callstack_top((stack_frame *)c->ESP);
57         signal_callstack_top = (stack_frame *)c->ESP;
58
59         switch (e->ExceptionCode)
60         {
61         case EXCEPTION_ACCESS_VIOLATION:
62                 signal_fault_addr = e->ExceptionInformation[1];
63                 c->EIP = (cell)factor::memory_signal_handler_impl;
64                 break;
65
66         case STATUS_FLOAT_DENORMAL_OPERAND:
67         case STATUS_FLOAT_DIVIDE_BY_ZERO:
68         case STATUS_FLOAT_INEXACT_RESULT:
69         case STATUS_FLOAT_INVALID_OPERATION:
70         case STATUS_FLOAT_OVERFLOW:
71         case STATUS_FLOAT_STACK_CHECK:
72         case STATUS_FLOAT_UNDERFLOW:
73         case STATUS_FLOAT_MULTIPLE_FAULTS:
74         case STATUS_FLOAT_MULTIPLE_TRAPS:
75 #ifdef FACTOR_64
76                 signal_fpu_status = fpu_status(MXCSR(c));
77 #else
78                 signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));
79                 X87SW(c) = 0;
80 #endif
81                 MXCSR(c) &= 0xffffffc0;
82                 c->EIP = (cell)factor::fp_signal_handler_impl;
83                 break;
84         case 0x40010006:
85                 /* If the Widcomm bluetooth stack is installed, the BTTray.exe
86                 process injects code into running programs. For some reason this
87                 results in random SEH exceptions with this (undocumented)
88                 exception code being raised. The workaround seems to be ignoring
89                 this altogether, since that is what happens if SEH is not
90                 enabled. Don't really have any idea what this exception means. */
91                 break;
92         default:
93                 signal_number = e->ExceptionCode;
94                 c->EIP = (cell)factor::misc_signal_handler_impl;
95                 break;
96         }
97         return EXCEPTION_CONTINUE_EXECUTION;
98 }
99
100 FACTOR_STDCALL(LONG) exception_handler(PEXCEPTION_POINTERS pe)
101 {
102         return current_vm()->exception_handler(pe);
103 }
104
105 void factor_vm::c_to_factor_toplevel(cell quot)
106 {
107         if(!AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)factor::exception_handler))
108                 fatal_error("AddVectoredExceptionHandler failed", 0);
109
110         c_to_factor(quot);
111
112         RemoveVectoredExceptionHandler((void *)factor::exception_handler);
113 }
114
115 void factor_vm::open_console()
116 {
117 }
118
119 }