]> gitweb.factorcode.org Git - factor.git/blob - vm/os-windows.cpp
VM: use better abstractions for tagged pointers, eliminate get()/set() stuff, clean...
[factor.git] / vm / os-windows.cpp
1 #include "master.hpp"
2
3 HMODULE hFactorDll;
4
5 void init_ffi(void)
6 {
7         hFactorDll = GetModuleHandle(FACTOR_DLL);
8         if(!hFactorDll)
9                 fatal_error("GetModuleHandle(\"" FACTOR_DLL_NAME "\") failed", 0);
10 }
11
12 void ffi_dlopen(F_DLL *dll)
13 {
14         dll->dll = LoadLibraryEx(alien_offset(dll->path), NULL, 0);
15 }
16
17 void *ffi_dlsym(F_DLL *dll, F_SYMBOL *symbol)
18 {
19         return GetProcAddress(dll ? (HMODULE)dll->dll : hFactorDll, symbol);
20 }
21
22 void ffi_dlclose(F_DLL *dll)
23 {
24         FreeLibrary((HMODULE)dll->dll);
25         dll->dll = NULL;
26 }
27
28 bool windows_stat(F_CHAR *path)
29 {
30         BY_HANDLE_FILE_INFORMATION bhfi;
31         HANDLE h = CreateFileW(path,
32                         GENERIC_READ,
33                         FILE_SHARE_READ,
34                         NULL,
35                         OPEN_EXISTING,
36                         FILE_FLAG_BACKUP_SEMANTICS,
37                         NULL);
38
39         if(h == INVALID_HANDLE_VALUE)
40         {
41                 // FindFirstFile is the only call that can stat c:\pagefile.sys
42                 WIN32_FIND_DATA st;
43                 HANDLE h;
44
45                 if(INVALID_HANDLE_VALUE == (h = FindFirstFile(path, &st)))
46                         return false;
47                 FindClose(h);
48                 return true;
49         }
50         bool ret;
51         ret = GetFileInformationByHandle(h, &bhfi);
52         CloseHandle(h);
53         return ret;
54 }
55
56 void windows_image_path(F_CHAR *full_path, F_CHAR *temp_path, unsigned int length)
57 {
58         snwprintf(temp_path, length-1, L"%s.image", full_path); 
59         temp_path[sizeof(temp_path) - 1] = 0;
60 }
61
62 /* You must free() this yourself. */
63 const F_CHAR *default_image_path(void)
64 {
65         F_CHAR full_path[MAX_UNICODE_PATH];
66         F_CHAR *ptr;
67         F_CHAR temp_path[MAX_UNICODE_PATH];
68
69         if(!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH))
70                 fatal_error("GetModuleFileName() failed", 0);
71
72         if((ptr = wcsrchr(full_path, '.')))
73                 *ptr = 0;
74
75         snwprintf(temp_path, sizeof(temp_path)-1, L"%s.image", full_path); 
76         temp_path[sizeof(temp_path) - 1] = 0;
77
78         return safe_strdup(temp_path);
79 }
80
81 /* You must free() this yourself. */
82 const F_CHAR *vm_executable_path(void)
83 {
84         F_CHAR full_path[MAX_UNICODE_PATH];
85         if(!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH))
86                 fatal_error("GetModuleFileName() failed", 0);
87         return safe_strdup(full_path);
88 }
89
90
91 PRIMITIVE(existsp)
92 {
93         F_CHAR *path = (F_CHAR *)(untag_check<F_BYTE_ARRAY>(dpop()) + 1);
94         box_boolean(windows_stat(path));
95 }
96
97 F_SEGMENT *alloc_segment(CELL size)
98 {
99         char *mem;
100         DWORD ignore;
101
102         if((mem = (char *)VirtualAlloc(NULL, getpagesize() * 2 + size,
103                 MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == 0)
104                 out_of_memory();
105
106         if (!VirtualProtect(mem, getpagesize(), PAGE_NOACCESS, &ignore))
107                 fatal_error("Cannot allocate low guard page", (CELL)mem);
108
109         if (!VirtualProtect(mem + size + getpagesize(),
110                 getpagesize(), PAGE_NOACCESS, &ignore))
111                 fatal_error("Cannot allocate high guard page", (CELL)mem);
112
113         F_SEGMENT *block = safe_malloc(sizeof(F_SEGMENT));
114
115         block->start = (CELL)mem + getpagesize();
116         block->size = size;
117         block->end = block->start + size;
118
119         return block;
120 }
121
122 void dealloc_segment(F_SEGMENT *block)
123 {
124         SYSTEM_INFO si;
125         GetSystemInfo(&si);
126         if(!VirtualFree((void*)(block->start - si.dwPageSize), 0, MEM_RELEASE))
127                 fatal_error("dealloc_segment failed",0);
128         free(block);
129 }
130
131 long getpagesize(void)
132 {
133         static long g_pagesize = 0;
134         if (! g_pagesize)
135         {
136                 SYSTEM_INFO system_info;
137                 GetSystemInfo (&system_info);
138                 g_pagesize = system_info.dwPageSize;
139         }
140         return g_pagesize;
141 }
142
143 void sleep_micros(u64 usec)
144 {
145         Sleep((DWORD)(usec / 1000));
146 }