#include <ctype.h>
#ifndef wcslen
- /* for cygwin */
- #include <wchar.h>
+// for cygwin
+#include <wchar.h>
#endif
-namespace factor
-{
+#if _WIN32_WINNT != 0x0600
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0501 // For AddVectoredExceptionHandler, WinXP support
+//#define _WIN32_WINNT 0x0600 // For CancelSynchronousIo
+#endif
+
+#ifndef UNICODE
+#define UNICODE
+#endif
+
+#include <windows.h>
+#include <shellapi.h>
+
+#ifdef _MSC_VER
+#undef min
+#undef max
+#endif
+
+// Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970
+#define EPOCH_OFFSET 0x019db1ded53e8000LL
+
+namespace factor {
typedef wchar_t vm_char;
+typedef char symbol_char;
+typedef HANDLE THREADHANDLE;
#define STRING_LITERAL(string) L##string
#define STRDUP _wcsdup
#ifdef _MSC_VER
- #define FTELL ftell
- #define FSEEK fseek
- #define SNPRINTF _snprintf
- #define SNWPRINTF _snwprintf
+#define FTELL ftell
+#define FSEEK fseek
#else
- #define FTELL ftello64
- #define FSEEK fseeko64
- #define SNPRINTF snprintf
- #define SNWPRINTF snwprintf
+#define FTELL ftello64
+#define FSEEK fseeko64
#endif
-#ifdef WIN64
- #define CELL_HEX_FORMAT "%Ix"
-#else
- #define CELL_HEX_FORMAT "%lx"
+#define FACTOR_OS_STRING "windows"
+
+// SSE traps raise these exception codes, which are defined in internal NT
+// headers
+// but not winbase.h
+#ifndef STATUS_FLOAT_MULTIPLE_FAULTS
+#define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4
#endif
-#define OPEN_READ(path) _wfopen((path),L"rb")
-#define OPEN_WRITE(path) _wfopen((path),L"wb")
-#define MOVE_FILE(path1,path2)\
-do {\
- if(MoveFileEx((path1),(path2),MOVEFILE_REPLACE_EXISTING) == false)\
- std::cout << "MoveFile() failed: error " << GetLastError() << std::endl;\
-} while(0)
+#ifndef STATUS_FLOAT_MULTIPLE_TRAPS
+#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5
+#endif
-/* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */
-#define EPOCH_OFFSET 0x019db1ded53e8000LL
+#define OPEN_READ(path) _wfopen((path), L"rb")
+#define OPEN_WRITE(path) _wfopen((path), L"wb")
+#define THREADSAFE_STRERROR(errnum, buf, buflen) strerror_s(buf, buflen, errnum)
-inline static void init_signals() {}
inline static void early_init() {}
-
-u64 system_micros();
-u64 nano_count();
-void sleep_nanos(u64 nsec);
+uint64_t nano_count();
+void sleep_nanos(uint64_t nsec);
long getpagesize();
+VM_C_API LONG exception_handler(PEXCEPTION_RECORD e, void* frame, PCONTEXT c,
+ void* dispatch);
+THREADHANDLE start_thread(void* (*start_routine)(void*), void* args);
+
+inline static THREADHANDLE thread_id() {
+ DWORD id = GetCurrentThreadId();
+ HANDLE threadHandle = OpenThread(
+ THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, FALSE,
+ id);
+ FACTOR_ASSERT(threadHandle != NULL);
+ return threadHandle;
+}
+
+inline static void breakpoint() { DebugBreak(); }
+
+#define CODE_TO_FUNCTION_POINTER(code) (void)0
+#define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void)0
+#define FUNCTION_CODE_POINTER(ptr) ptr
+#define FUNCTION_TOC_POINTER(ptr) ptr
+
+extern HANDLE boot_thread;
+
+inline static std::string to_utf8(const wchar_t* buffer, int len) {
+ int nChars = ::WideCharToMultiByte(
+ CP_UTF8,
+ 0,
+ buffer,
+ len,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ if (nChars == 0) return "";
+
+ std::string newbuffer;
+ newbuffer.resize(nChars) ;
+ ::WideCharToMultiByte(
+ CP_UTF8,
+ 0,
+ buffer,
+ len,
+ const_cast<char*>(newbuffer.c_str()),
+ nChars,
+ NULL,
+ NULL);
+ return newbuffer;
+}
+
+inline static std::string to_utf8(const std::wstring& str) {
+ return to_utf8(str.c_str(), (int)str.size());
+}
+
+#define AS_UTF8(ptr) to_utf8(ptr)
}