]> gitweb.factorcode.org Git - factor.git/blob - vm/os-windows.cpp
Dev checkpoint
[factor.git] / vm / os-windows.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 HMODULE hFactorDll;
7
8 void factorvm::init_ffi()
9 {
10         hFactorDll = GetModuleHandle(FACTOR_DLL);
11         if(!hFactorDll)
12                 fatal_error("GetModuleHandle(\"" FACTOR_DLL_NAME "\") failed", 0);
13 }
14
15 void init_ffi()
16 {
17         return vm->init_ffi();
18 }
19
20 void factorvm::ffi_dlopen(dll *dll)
21 {
22         dll->dll = LoadLibraryEx((WCHAR *)alien_offset(dll->path), NULL, 0);
23 }
24
25 void ffi_dlopen(dll *dll)
26 {
27         return vm->ffi_dlopen(dll);
28 }
29
30 void *factorvm::ffi_dlsym(dll *dll, symbol_char *symbol)
31 {
32         return (void *)GetProcAddress(dll ? (HMODULE)dll->dll : hFactorDll, symbol);
33 }
34
35 void *ffi_dlsym(dll *dll, symbol_char *symbol)
36 {
37         return vm->ffi_dlsym(dll,symbol);
38 }
39
40 void factorvm::ffi_dlclose(dll *dll)
41 {
42         FreeLibrary((HMODULE)dll->dll);
43         dll->dll = NULL;
44 }
45
46 void ffi_dlclose(dll *dll)
47 {
48         return vm->ffi_dlclose(dll);
49 }
50
51 bool windows_stat(vm_char *path)
52 {
53         BY_HANDLE_FILE_INFORMATION bhfi;
54         HANDLE h = CreateFileW(path,
55                         GENERIC_READ,
56                         FILE_SHARE_READ,
57                         NULL,
58                         OPEN_EXISTING,
59                         FILE_FLAG_BACKUP_SEMANTICS,
60                         NULL);
61
62         if(h == INVALID_HANDLE_VALUE)
63         {
64                 // FindFirstFile is the only call that can stat c:\pagefile.sys
65                 WIN32_FIND_DATA st;
66                 HANDLE h;
67
68                 if(INVALID_HANDLE_VALUE == (h = FindFirstFile(path, &st)))
69                         return false;
70                 FindClose(h);
71                 return true;
72         }
73         bool ret;
74         ret = GetFileInformationByHandle(h, &bhfi);
75         CloseHandle(h);
76         return ret;
77 }
78
79 void windows_image_path(vm_char *full_path, vm_char *temp_path, unsigned int length)
80 {
81         snwprintf(temp_path, length-1, L"%s.image", full_path); 
82         temp_path[sizeof(temp_path) - 1] = 0;
83 }
84
85 /* You must free() this yourself. */
86 const vm_char *default_image_path()
87 {
88         vm_char full_path[MAX_UNICODE_PATH];
89         vm_char *ptr;
90         vm_char temp_path[MAX_UNICODE_PATH];
91
92         if(!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH))
93                 fatal_error("GetModuleFileName() failed", 0);
94
95         if((ptr = wcsrchr(full_path, '.')))
96                 *ptr = 0;
97
98         snwprintf(temp_path, sizeof(temp_path)-1, L"%s.image", full_path); 
99         temp_path[sizeof(temp_path) - 1] = 0;
100
101         return safe_strdup(temp_path);
102 }
103
104 /* You must free() this yourself. */
105 const vm_char *factorvm::vm_executable_path()
106 {
107         vm_char full_path[MAX_UNICODE_PATH];
108         if(!GetModuleFileName(NULL, full_path, MAX_UNICODE_PATH))
109                 fatal_error("GetModuleFileName() failed", 0);
110         return safe_strdup(full_path);
111 }
112
113 const vm_char *vm_executable_path()
114 {
115         return vm->vm_executable_path();
116 }
117
118
119 inline void factorvm::vmprim_existsp()
120 {
121         vm_char *path = untag_check<byte_array>(dpop())->data<vm_char>();
122         box_boolean(windows_stat(path));
123 }
124
125 PRIMITIVE(existsp)
126 {
127         PRIMITIVE_GETVM()->vmprim_existsp();
128 }
129
130 segment *factorvm::alloc_segment(cell size)
131 {
132         char *mem;
133         DWORD ignore;
134
135         if((mem = (char *)VirtualAlloc(NULL, getpagesize() * 2 + size,
136                 MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == 0)
137                 out_of_memory();
138
139         if (!VirtualProtect(mem, getpagesize(), PAGE_NOACCESS, &ignore))
140                 fatal_error("Cannot allocate low guard page", (cell)mem);
141
142         if (!VirtualProtect(mem + size + getpagesize(),
143                 getpagesize(), PAGE_NOACCESS, &ignore))
144                 fatal_error("Cannot allocate high guard page", (cell)mem);
145
146         segment *block = (segment *)safe_malloc(sizeof(segment));
147
148         block->start = (cell)mem + getpagesize();
149         block->size = size;
150         block->end = block->start + size;
151
152         return block;
153 }
154
155 segment *alloc_segment(cell size)
156 {
157         return vm->alloc_segment(size);
158 }
159
160 void factorvm::dealloc_segment(segment *block)
161 {
162         SYSTEM_INFO si;
163         GetSystemInfo(&si);
164         if(!VirtualFree((void*)(block->start - si.dwPageSize), 0, MEM_RELEASE))
165                 fatal_error("dealloc_segment failed",0);
166         free(block);
167 }
168
169 void dealloc_segment(segment *block)
170 {
171         return vm->dealloc_segment(block);
172 }
173
174 long factorvm::getpagesize()
175 {
176         static long g_pagesize = 0;
177         if (! g_pagesize)
178         {
179                 SYSTEM_INFO system_info;
180                 GetSystemInfo (&system_info);
181                 g_pagesize = system_info.dwPageSize;
182         }
183         return g_pagesize;
184 }
185
186 long getpagesize()
187 {
188         return vm->getpagesize();
189 }
190
191 void factorvm::sleep_micros(u64 usec)
192 {
193         Sleep((DWORD)(usec / 1000));
194 }
195
196 void sleep_micros(u64 usec)
197 {
198         return vm->sleep_micros(usec);
199 }
200
201 }