3 /* frees memory allocated by win32 api calls */
4 char *buffer_to_char_string(char *buffer)
6 int capacity = strlen(buffer);
7 F_STRING *_c_str = allot_string(capacity / CHARS + 1);
8 u8 *c_str = (u8*)(_c_str + 1);
14 F_STRING *get_error_message()
16 DWORD id = GetLastError();
17 return from_char_string(error_message(id));
20 char *error_message(DWORD id)
26 FORMAT_MESSAGE_ALLOCATE_BUFFER |
27 FORMAT_MESSAGE_FROM_SYSTEM,
30 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
34 /* strip whitespace from end */
35 index = strlen(buffer) - 1;
36 while(index >= 0 && isspace(buffer[index]))
39 return buffer_to_char_string(buffer);
42 s64 current_millis(void)
45 GetSystemTimeAsFileTime(&t);
46 return (((s64)t.dwLowDateTime | (s64)t.dwHighDateTime<<32) - EPOCH_OFFSET)
50 void ffi_dlopen (DLL *dll, bool error)
53 char *path = to_char_string(untag_string(dll->path),true);
55 module = LoadLibrary(path);
61 general_error(ERROR_FFI, tag_object(get_error_message()),F,true);
69 void *ffi_dlsym (DLL *dll, F_STRING *symbol, bool error)
71 void *sym = GetProcAddress(dll ? (HMODULE)dll->dll : GetModuleHandle(NULL),
72 to_char_string(symbol,true));
77 general_error(ERROR_FFI, tag_object(get_error_message()),F,true);
85 void ffi_dlclose (DLL *dll)
87 FreeLibrary((HMODULE)dll->dll);
91 void primitive_stat(void)
94 WIN32_FILE_ATTRIBUTE_DATA st;
97 path = untag_string(dpop());
99 if(!GetFileAttributesEx(to_char_string(path,true), GetFileExInfoStandard, &st))
105 CELL dirp = tag_boolean(st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
106 CELL size = tag_bignum(s48_long_long_to_bignum(
107 (s64)st.nFileSizeLow | (s64)st.nFileSizeHigh << 32));
108 CELL mtime = tag_integer((int)
109 ((*(s64*)&st.ftLastWriteTime - EPOCH_OFFSET) / 10000000));
110 dpush(make_array_4(dirp,tag_fixnum(0),size,mtime));
114 void primitive_read_dir(void)
118 WIN32_FIND_DATA find_data;
120 CELL result_count = 0;
124 result = array(ARRAY_TYPE,100,F);
126 path = untag_string(dpop());
127 if (INVALID_HANDLE_VALUE != (dir = FindFirstFile(".\\*", &find_data)))
131 CELL name = tag_object(from_char_string(
132 find_data.cFileName));
134 if(result_count == array_capacity(result))
136 result = resize_array(result,
140 put(AREF(result,result_count),name);
143 while (FindNextFile(dir, &find_data));
147 result = resize_array(result,result_count,F);
149 dpush(tag_object(result));
152 void primitive_cwd(void)
157 if(!GetCurrentDirectory(MAX_PATH, buf))
160 box_char_string(buf);
163 void primitive_cd(void)
166 SetCurrentDirectory(unbox_char_string());
169 BOUNDED_BLOCK *alloc_bounded_block(CELL size)
176 if((mem = (char *)VirtualAlloc(NULL, si.dwPageSize*2 + size, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == 0)
177 fatal_error("VirtualAlloc() failed in alloc_bounded_block()",0);
179 if (!VirtualProtect(mem, si.dwPageSize, PAGE_NOACCESS, &ignore))
180 fatal_error("Cannot allocate low guard page", (CELL)mem);
182 if (!VirtualProtect(mem+size+si.dwPageSize, si.dwPageSize, PAGE_NOACCESS, &ignore))
183 fatal_error("Cannot allocate high guard page", (CELL)mem);
185 BOUNDED_BLOCK *block = safe_malloc(sizeof(BOUNDED_BLOCK));
187 block->start = (int)mem + si.dwPageSize;
193 void dealloc_bounded_block(BOUNDED_BLOCK *block)
197 if(!VirtualFree((void*)(block->start - si.dwPageSize), 0, MEM_RELEASE))
198 fatal_error("VirtualFree() failed",0);
202 long getpagesize (void)
204 static long g_pagesize = 0;
207 SYSTEM_INFO system_info;
208 GetSystemInfo (&system_info);
209 g_pagesize = system_info.dwPageSize;
214 const char *default_image_path(void)
216 return "factor.image";
219 /* SEH support. Proceed with caution. */
220 typedef long exception_handler_t(
221 PEXCEPTION_RECORD rec, void *frame, void *context, void *dispatch);
223 typedef struct exception_record
225 struct exception_record *next_handler;
227 } exception_record_t;
229 void seh_call(void (*func)(), exception_handler_t *handler)
231 exception_record_t record;
232 asm("mov %%fs:0, %0" : "=r" (record.next_handler));
233 asm("mov %0, %%fs:0" : : "r" (&record));
234 record.handler_func = handler;
236 asm("mov %0, %%fs:0" : "=r" (record.next_handler));
239 static long exception_handler(PEXCEPTION_RECORD rec, void *frame, void *ctx, void *dispatch)
241 memory_protection_error((void*)rec->ExceptionInformation[1], SIGSEGV);
242 return -1; /* unreachable */
250 void run_toplevel(void)
252 seh_call(run, exception_handler);