#include "moar.h" #include "platform/mmap.h" #include #include static int page_mode_to_prot_mode(int page_mode) { switch (page_mode) { case MVM_PAGE_READ: return PAGE_READONLY; case MVM_PAGE_WRITE: case (MVM_PAGE_WRITE | MVM_PAGE_READ): return PAGE_READWRITE; case MVM_PAGE_EXEC: return PAGE_EXECUTE; case (MVM_PAGE_READ|MVM_PAGE_EXEC): return PAGE_EXECUTE_READ; case (MVM_PAGE_WRITE|MVM_PAGE_EXEC): case (MVM_PAGE_READ|MVM_PAGE_WRITE|MVM_PAGE_EXEC): return PAGE_EXECUTE_READWRITE; } /* I pity the fools that enter an invalid mode */ return PAGE_NOACCESS; } void *MVM_platform_alloc_pages(size_t size, int page_mode) { int prot_mode = page_mode_to_prot_mode(page_mode); void * allocd = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, prot_mode); if (!allocd) MVM_panic(1, "MVM_platform_alloc_pages failed: %lu", GetLastError()); return allocd; } int MVM_platform_set_page_mode(void * pages, size_t size, int page_mode) { int prot_mode = page_mode_to_prot_mode(page_mode); DWORD oldMode; return VirtualProtect(pages, size, prot_mode, &oldMode); } int MVM_platform_free_pages(void *pages, size_t size) { (void)size; return VirtualFree(pages, 0, MEM_RELEASE); } void *MVM_platform_map_file(int fd, void **handle, size_t size, int writable) { HANDLE fh, mapping; LARGE_INTEGER li; void *block; fh = (HANDLE)_get_osfhandle(fd); if (fh == INVALID_HANDLE_VALUE) return NULL; li.QuadPart = size; mapping = CreateFileMapping(fh, NULL, writable ? PAGE_READWRITE : PAGE_READONLY, li.HighPart, li.LowPart, NULL); if(mapping == NULL) return NULL; block = MapViewOfFile(mapping, writable ? FILE_MAP_READ | FILE_MAP_WRITE : FILE_MAP_READ, 0, 0, size); if (block == NULL) { CloseHandle(mapping); return NULL; } if (handle) *handle = mapping; return block; } int MVM_platform_unmap_file(void *block, void *handle, size_t size) { BOOL unmapped = UnmapViewOfFile(block); BOOL closed = !handle || CloseHandle(handle); (void)size; return unmapped && closed; }