115 lines
2.9 KiB
Plaintext
115 lines
2.9 KiB
Plaintext
#import "kernel32.kl"
|
|
#import "base.kl"
|
|
|
|
PAGE_SIZE :: 4096
|
|
Memory :: struct
|
|
commit : SizeU
|
|
reserve: SizeU
|
|
data : *U8
|
|
|
|
process_heap: HANDLE
|
|
allocate :: (size: U64): *void
|
|
if process_heap == 0
|
|
process_heap = GetProcessHeap()
|
|
return HeapAlloc(process_heap, 0, size)
|
|
|
|
reserve :: (size: SizeU): Memory
|
|
result := Memory{reserve=align_up(size, PAGE_SIZE)}
|
|
result.data = VirtualAlloc(
|
|
flProtect = PAGE_READWRITE,
|
|
dwSize = result.reserve,
|
|
flAllocationType = MEM_RESERVE,
|
|
lpAddress = 0)->*U8
|
|
return result
|
|
|
|
commit :: (m: *Memory, size: SizeU): Bool
|
|
commit_size := align_up(size, PAGE_SIZE)
|
|
total_commit := m.commit + commit_size
|
|
clamped_commit := clamp_top_sizeu(total_commit, m.reserve)
|
|
adjusted_commit := clamped_commit - m.commit
|
|
if adjusted_commit != 0
|
|
result := VirtualAlloc(
|
|
lpAddress = (m.data + m.commit)->*void,
|
|
dwSize = adjusted_commit,
|
|
flAllocationType = MEM_COMMIT,
|
|
flProtect = PAGE_READWRITE,
|
|
)
|
|
m.commit += adjusted_commit
|
|
return true
|
|
return false
|
|
|
|
release :: (m: *Memory)
|
|
result := VirtualFree(m.data->*void, 0, MEM_RELEASE)
|
|
if result != 0
|
|
m.data = 0
|
|
m.commit = 0
|
|
m.reserve = 0
|
|
|
|
write_console :: (string: String16)
|
|
handle := GetStdHandle(STD_OUTPUT_HANDLE)
|
|
WriteConsoleW(handle, string.str->*void, string.len->DWORD, 0, 0)
|
|
|
|
performance_frequency: F64
|
|
time :: (): F64
|
|
query: LARGE_INTEGER
|
|
if !performance_frequency
|
|
err := QueryPerformanceFrequency(&query)
|
|
assert(err != 0)
|
|
performance_frequency = query->F64
|
|
|
|
err := QueryPerformanceCounter(&query)
|
|
assert(err != 0)
|
|
result := query->F64 / performance_frequency
|
|
return result
|
|
|
|
/**
|
|
* C++ version 0.4 char* style "itoa":
|
|
* Written by Lukás Chmela
|
|
* Released under GPLv3.
|
|
*/
|
|
itoa :: (value: S64, result: *U8, base: S64): *U8
|
|
// check that the base if valid
|
|
if (base < 2) || (base > 36)
|
|
*result = 0 // '
|
|
return result
|
|
|
|
ptr := result
|
|
ptr1 := result
|
|
tmp_char: U8
|
|
tmp_value: S64
|
|
|
|
for value != 0
|
|
tmp_value = value
|
|
value /= base
|
|
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)]
|
|
|
|
// Apply negative sign
|
|
if tmp_value < 0
|
|
*ptr++ = '- // '
|
|
*ptr-- = 0
|
|
for ptr1 < ptr
|
|
tmp_char = *ptr
|
|
*ptr-- = *ptr1
|
|
*ptr1++ = tmp_char
|
|
return result
|
|
|
|
|
|
print :: (string: String, args: ..)
|
|
buffer: [1024]U8
|
|
buffer_len: S64
|
|
|
|
arg_counter := 0
|
|
for i := 0, i < length_of(string), i+=1
|
|
if string[i] == '% // '
|
|
assert(arg_counter < length_of(args), "Passing too many [%] to a print lambda")
|
|
arg := args[arg_counter++]
|
|
|
|
if arg.type == S64
|
|
value := *(arg.data->*S64)
|
|
itoa_buff: [64]U8
|
|
p := itoa(value, &itoa_buff[0], 10)
|
|
for *p != 0
|
|
buffer[buffer_len++] = *p++
|
|
else;; assert(false)
|
|
else
|
|
buffer[buffer_len++] = string[i] |