3 F_STRING *get_error_message()
5 DWORD id = GetLastError();
6 char *msg = error_message(id);
7 F_STRING *string = from_char_string(msg);
12 /* You must LocalFree() the return value! */
13 char *error_message(DWORD id)
19 FORMAT_MESSAGE_ALLOCATE_BUFFER |
20 FORMAT_MESSAGE_FROM_SYSTEM,
23 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
27 /* strip whitespace from end */
28 index = strlen(buffer) - 1;
29 while(index >= 0 && isspace(buffer[index]))
35 s64 current_millis(void)
38 GetSystemTimeAsFileTime(&t);
39 return (((s64)t.dwLowDateTime | (s64)t.dwHighDateTime<<32)
40 - EPOCH_OFFSET) / 10000;
43 void ffi_dlopen (F_DLL *dll, bool error)
45 HMODULE module = LoadLibrary(alien_offset(dll->path));
51 simple_error(ERROR_FFI,F,
52 tag_object(get_error_message()));
60 void *ffi_dlsym (F_DLL *dll, char *symbol, bool error)
62 void *sym = GetProcAddress(
63 dll ? (HMODULE)dll->dll : GetModuleHandle(NULL),
69 simple_error(ERROR_FFI,
70 tag_object(from_char_string(symbol)),
71 tag_object(get_error_message()));
79 void ffi_dlclose (F_DLL *dll)
81 FreeLibrary((HMODULE)dll->dll);
85 void primitive_stat(void)
87 WIN32_FILE_ATTRIBUTE_DATA st;
89 if(!GetFileAttributesEx(
91 GetFileExInfoStandard,
101 box_boolean(st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
104 (s64)st.nFileSizeLow | (s64)st.nFileSizeHigh << 32);
106 ((*(s64*)&st.ftLastWriteTime - EPOCH_OFFSET) / 10000000));
110 void primitive_read_dir(void)
113 WIN32_FIND_DATA find_data;
114 char path[MAX_PATH + 4];
116 sprintf(path, "%s\\*", unbox_char_string());
118 GROWABLE_ARRAY(result);
120 if(INVALID_HANDLE_VALUE != (dir = FindFirstFile(path, &find_data)))
124 REGISTER_ARRAY(result);
125 CELL name = tag_object(from_char_string(
126 find_data.cFileName));
127 UNREGISTER_ARRAY(result);
128 GROWABLE_ADD(result,name);
130 while (FindNextFile(dir, &find_data));
134 GROWABLE_TRIM(result);
136 dpush(tag_object(result));
139 void primitive_cwd(void)
143 if(!GetCurrentDirectory(MAX_PATH, buf))
146 box_char_string(buf);
149 void primitive_cd(void)
151 SetCurrentDirectory(unbox_char_string());
154 F_SEGMENT *alloc_segment(CELL size)
161 if((mem = (char *)VirtualAlloc(NULL, si.dwPageSize*2 + size, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == 0)
162 fatal_error("VirtualAlloc() failed in alloc_segment()",0);
164 if (!VirtualProtect(mem, si.dwPageSize, PAGE_NOACCESS, &ignore))
165 fatal_error("Cannot allocate low guard page", (CELL)mem);
167 if (!VirtualProtect(mem+size+si.dwPageSize, si.dwPageSize, PAGE_NOACCESS, &ignore))
168 fatal_error("Cannot allocate high guard page", (CELL)mem);
170 F_SEGMENT *block = safe_malloc(sizeof(F_SEGMENT));
172 block->start = (int)mem + si.dwPageSize;
178 void dealloc_segment(F_SEGMENT *block)
182 if(!VirtualFree((void*)(block->start - si.dwPageSize), 0, MEM_RELEASE))
183 fatal_error("VirtualFree() failed",0);
187 long getpagesize(void)
189 static long g_pagesize = 0;
192 SYSTEM_INFO system_info;
193 GetSystemInfo (&system_info);
194 g_pagesize = system_info.dwPageSize;
199 const char *default_image_path(void)
201 return "factor.image";
204 /* SEH support. Proceed with caution. */
205 typedef long exception_handler_t(
206 PEXCEPTION_RECORD rec, void *frame, void *context, void *dispatch);
208 typedef struct exception_record
210 struct exception_record *next_handler;
212 } exception_record_t;
214 void seh_call(void (*func)(), exception_handler_t *handler)
216 exception_record_t record;
217 asm("mov %%fs:0, %0" : "=r" (record.next_handler));
218 asm("mov %0, %%fs:0" : : "r" (&record));
219 record.handler_func = handler;
221 asm("mov %0, %%fs:0" : "=r" (record.next_handler));
224 static long exception_handler(PEXCEPTION_RECORD rec, void *frame, void *ctx, void *dispatch)
226 memory_protection_error(rec->ExceptionInformation[1],
227 SIGSEGV,native_stack_pointer());
228 return -1; /* unreachable */
236 void run_toplevel(void)
238 seh_call(run, exception_handler);