diff --git a/lib/std/core/builtin.c3 b/lib/std/core/builtin.c3 index d751c360f..0fe540b09 100644 --- a/lib/std/core/builtin.c3 +++ b/lib/std/core/builtin.c3 @@ -98,41 +98,34 @@ macro anycast(any v, $Type) @builtin fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::NATIVE_STACKTRACE) => @stack_mem(0x1100; Allocator smem) { - Allocator t = allocator::current_temp; - TempAllocator* t2 = allocator::top_temp; - TempAllocator* new_t = allocator::new_temp_allocator(smem, 0x1000)!!; - allocator::current_temp = allocator::top_temp = new_t; - defer - { - allocator::current_temp = t; - allocator::top_temp = t2; - new_t.free(); - } void*[256] buffer; void*[] backtraces = backtrace::capture_current(&buffer); backtraces_to_ignore++; - BacktraceList? backtrace = backtrace::symbolize_backtrace(tmem, backtraces); - if (catch backtrace) return false; - if (backtrace.len() <= backtraces_to_ignore) return false; - io::eprint("\nERROR: '"); - io::eprint(message); - io::eprintn("'"); - foreach (i, &trace : backtrace) + @stack_mem(2048; Allocator mem) { - if (i < backtraces_to_ignore) continue; - String inline_suffix = trace.is_inline ? " [inline]" : ""; - if (trace.is_unknown()) + BacktraceList? backtrace = backtrace::symbolize_backtrace(mem, backtraces); + if (catch backtrace) return false; + if (backtrace.len() <= backtraces_to_ignore) return false; + io::eprint("\nERROR: '"); + io::eprint(message); + io::eprintn("'"); + foreach (i, &trace : backtrace) { - io::eprintfn(" in ???%s", inline_suffix); - continue; + if (i < backtraces_to_ignore) continue; + String inline_suffix = trace.is_inline ? " [inline]" : ""; + if (trace.is_unknown()) + { + io::eprintfn(" in ???%s", inline_suffix); + continue; + } + if (trace.has_file()) + { + io::eprintfn(" in %s (%s:%d) [%s]%s", trace.function, trace.file, trace.line, trace.object_file, inline_suffix); + continue; + } + io::eprintfn(" in %s (source unavailable) [%s]%s", trace.function, trace.object_file, inline_suffix); } - if (trace.has_file()) - { - io::eprintfn(" in %s (%s:%d) [%s]%s", trace.function, trace.file, trace.line, trace.object_file, inline_suffix); - continue; - } - io::eprintfn(" in %s (source unavailable) [%s]%s", trace.function, trace.object_file, inline_suffix); - } + }; return true; } diff --git a/lib/std/core/mem.c3 b/lib/std/core/mem.c3 index c05835eb1..350fd7d8e 100644 --- a/lib/std/core/mem.c3 +++ b/lib/std/core/mem.c3 @@ -7,6 +7,10 @@ import std::math; const MAX_MEMORY_ALIGNMENT = 0x1000_0000; const DEFAULT_MEM_ALIGNMENT = (void*.alignof) * 2; +const ulong KB = 1024; +const ulong MB = KB * 1024; +const ulong GB = MB * 1024; +const ulong TB = GB * 1024; faultdef OUT_OF_MEMORY, INVALID_ALLOC_SIZE; diff --git a/lib/std/core/string.c3 b/lib/std/core/string.c3 index 6aeaf49cf..83100d3fb 100644 --- a/lib/std/core/string.c3 +++ b/lib/std/core/string.c3 @@ -107,6 +107,19 @@ fn String format(Allocator allocator, String fmt, args...) @format(1) => @pool() return str.copy_str(allocator); } +<* + Return a new String created using the formatting function. + + @param [inout] buffer : `The buffer to use` + @param [in] fmt : `The formatting string` +*> +fn String bformat(char[] buffer, String fmt, args...) @format(1) +{ + DString str = dstring::new_with_capacity(allocator::wrap(buffer), fmt.len + args.len * 8); + str.appendf(fmt, ...args); + return str.str_view(); +} + <* Return a temporary String created using the formatting function. diff --git a/lib/std/os/env.c3 b/lib/std/os/env.c3 index 525d09049..e2875a4b9 100644 --- a/lib/std/os/env.c3 +++ b/lib/std/os/env.c3 @@ -115,10 +115,10 @@ fn bool clear_var(String name) => @pool() $endswitch } -fn String? executable_path(Allocator allocator) +fn String? executable_path() { $if env::DARWIN: - return darwin::executable_path(allocator); + return darwin::executable_path(); $else return NOT_FOUND?; $endif diff --git a/lib/std/os/linux/linux.c3 b/lib/std/os/linux/linux.c3 index b16aa8286..fbbb67f54 100644 --- a/lib/std/os/linux/linux.c3 +++ b/lib/std/os/linux/linux.c3 @@ -130,70 +130,76 @@ fn ulong? elf_module_image_base(String path) @local fn void? backtrace_add_from_exec(Allocator allocator, BacktraceList* list, void* addr) @local { - char[] buf = mem::talloc_array(char, 1024); - - String exec_path = process::execute_stdout_to_buffer(buf, {"realpath", "-e", string::tformat("/proc/%d/exe", posix::getpid())})!; + char[1024] buf @noinit; + String exec_path = process::execute_stdout_to_buffer(&buf, {"realpath", "-e", string::bformat(&&(char[64]){}, "/proc/%d/exe", posix::getpid())})!; String obj_name = exec_path.copy(allocator); - String addr2line = process::execute_stdout_to_buffer(buf, {"addr2line", "-p", "-i", "-C", "-f", "-e", exec_path, string::tformat("0x%x", addr)})!; + String addr2line = process::execute_stdout_to_buffer(&buf, {"addr2line", "-p", "-i", "-C", "-f", "-e", exec_path, string::bformat(&&(char[64]){}, "0x%x", addr)})!; return backtrace_add_addr2line(allocator, list, addr, addr2line, obj_name, "???"); } fn void? backtrace_add_from_dlinfo(Allocator allocator, BacktraceList* list, void* addr, Linux_Dl_info* info) @local { - char[] buf = mem::talloc_array(char, 1024); + char[1024] buf @noinit; void* obj_addr = addr - (uptr)info.dli_fbase + (uptr)elf_module_image_base(info.dli_fname.str_view())!; ZString obj_path = info.dli_fname; String sname = info.dli_sname ? info.dli_sname.str_view() : "???"; - String addr2line = process::execute_stdout_to_buffer(buf, {"addr2line", "-p", "-i", "-C", "-f", "-e", obj_path.str_view(), string::tformat("0x%x", obj_addr - 1)})!; + String addr2line = process::execute_stdout_to_buffer(&buf, {"addr2line", "-p", "-i", "-C", "-f", "-e", obj_path.str_view(), string::bformat(&&(char[64]){}, "0x%x", obj_addr - 1)})!; return backtrace_add_addr2line(allocator, list, addr, addr2line, info.dli_fname.str_view(), sname); } fn Backtrace? backtrace_line_parse(Allocator allocator, String string, String obj_name, String func_name, bool is_inlined) { - String[] parts = string.trim().tsplit(" at "); - if (parts.len != 2) return NOT_FOUND?; - - uint line = 0; - String source = ""; - if (!parts[1].contains("?") && parts[1].contains(":")) + @stack_mem(256; Allocator mem) { - usz index = parts[1].rindex_of_char(':')!; - source = parts[1][:index]; - line = parts[1][index + 1..].to_uint()!; - } - return { - .function = parts[0].copy(allocator), - .object_file = obj_name.copy(allocator), - .file = source.copy(allocator), - .line = line, - .allocator = allocator, - .is_inline = is_inlined + String[] parts = string.trim().split(mem, " at "); + if (parts.len != 2) return NOT_FOUND?; + + uint line = 0; + String source = ""; + if (!parts[1].contains("?") && parts[1].contains(":")) + { + usz index = parts[1].rindex_of_char(':')!; + source = parts[1][:index]; + line = parts[1][index + 1..].to_uint()!; + } + return { + .function = parts[0].copy(allocator), + .object_file = obj_name.copy(allocator), + .file = source.copy(allocator), + .line = line, + .allocator = allocator, + .is_inline = is_inlined + }; }; + } fn void? backtrace_add_addr2line(Allocator allocator, BacktraceList* list, void* addr, String addr2line, String obj_name, String func_name) @local { - String[] inline_parts = addr2line.tsplit("(inlined by)"); - usz last = inline_parts.len - 1; - foreach (i, part : inline_parts) + @stack_mem(1024; Allocator mem) { - bool is_inline = i != last; - Backtrace? trace = backtrace_line_parse(allocator, part, obj_name, func_name, is_inline); - if (catch trace) + String[] inline_parts = addr2line.split(mem, "(inlined by)"); + usz last = inline_parts.len - 1; + foreach (i, part : inline_parts) { - list.push({ - .function = func_name.copy(allocator), - .object_file = obj_name.copy(allocator), - .offset = (uptr)addr, - .file = "".copy(allocator), - .line = 0, - .allocator = allocator, - .is_inline = is_inline - }); - continue; + bool is_inline = i != last; + Backtrace? trace = backtrace_line_parse(allocator, part, obj_name, func_name, is_inline); + if (catch trace) + { + list.push({ + .function = func_name.copy(allocator), + .object_file = obj_name.copy(allocator), + .offset = (uptr)addr, + .file = "".copy(allocator), + .line = 0, + .allocator = allocator, + .is_inline = is_inline + }); + continue; + } + list.push(trace); } - list.push(trace); - } + }; } fn void? backtrace_add_element(Allocator allocator, BacktraceList *list, void* addr) @local @@ -204,15 +210,12 @@ fn void? backtrace_add_element(Allocator allocator, BacktraceList *list, void* a return; } - @pool() + Linux_Dl_info info; + if (dladdr(addr, &info) == 0) { - Linux_Dl_info info; - if (dladdr(addr, &info) == 0) - { - return backtrace_add_from_exec(allocator, list, addr); - } - return backtrace_add_from_dlinfo(allocator, list, addr, &info); - }; + return backtrace_add_from_exec(allocator, list, addr); + } + return backtrace_add_from_dlinfo(allocator, list, addr, &info); } fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace) @@ -227,12 +230,9 @@ fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace) } list.free(); } - @pool() + foreach (addr : backtrace) { - foreach (addr : backtrace) - { - backtrace_add_element(allocator, &list, addr)!; - } - }; + backtrace_add_element(allocator, &list, addr)!; + } return list; } diff --git a/lib/std/os/macos/darwin.c3 b/lib/std/os/macos/darwin.c3 index af87101c6..0ca2f97b2 100644 --- a/lib/std/os/macos/darwin.c3 +++ b/lib/std/os/macos/darwin.c3 @@ -79,19 +79,26 @@ alias Darwin_mach_timebase_info_data_t = Darwin_mach_timebase_info; extern fn void mach_timebase_info(Darwin_mach_timebase_info_data_t* timebase); extern fn ulong mach_absolute_time(); -fn String? executable_path(Allocator allocator) +fn String? executable_path() { - char[4096] path; - uint len = path.len; - if (darwin_NSGetExecutablePath(&path, &len) < 0) return NOT_FOUND?; - return ((ZString)&path).copy(allocator); + static char[4096] path; + static uint len = 0; + if (!len) + { + char[4096] buf; + uint temp_len = buf.len; + if (darwin_NSGetExecutablePath(&buf, &temp_len) < 0) return NOT_FOUND?; + path[:temp_len] = buf[:temp_len]; + len = temp_len; + } + return (String)path[:len]; } fn uptr? load_address() @local { Darwin_segment_command_64* cmd = darwin::getsegbyname("__TEXT"); if (!cmd) return backtrace::SEGMENT_NOT_FOUND?; - String path = env::executable_path(tmem) ?? backtrace::EXECUTABLE_PATH_NOT_FOUND?!; + String path = env::executable_path() ?? backtrace::EXECUTABLE_PATH_NOT_FOUND?!; uint dyld_count = darwin::_dyld_image_count(); for (uint i = 0; i < dyld_count; i++) { @@ -103,23 +110,22 @@ fn uptr? load_address() @local return backtrace::IMAGE_NOT_FOUND?; } - fn Backtrace? backtrace_load_element(Allocator allocator, String execpath, void* buffer, void* load_address) @local { - @pool() + if (buffer) { - if (buffer) - { - char* buf = tmalloc(1024); - String s = process::execute_stdout_to_buffer(buf[:1024], - { "atos", "-o", execpath, "-arch", env::AARCH64 ? "arm64" : "x86_64", "-l", - string::tformat("%p", load_address), - string::tformat("%p", buffer - 1), - "-fullPath" })!; - String[] parts = s.tsplit(" "); + char[1024] buf; + String s = process::execute_stdout_to_buffer(&buf, + { "atos", "-o", execpath, "-arch", env::AARCH64 ? "arm64" : "x86_64", "-l", + string::bformat(&&(char[64]){}, "%p", load_address), + string::bformat(&&(char[64]){}, "%p", buffer - 1), + "-fullPath" })!; + @stack_mem(512; Allocator mem) + { + String[] parts = s.split(mem, " ", 5); if (parts.len == 4) { - String[] path_parts = parts[3].tsplit(":"); + String[] path_parts = parts[3].split(mem, ":"); return { .offset = (uptr)buffer, .function = parts[0].copy(allocator), @@ -129,17 +135,17 @@ fn Backtrace? backtrace_load_element(Allocator allocator, String execpath, void* .allocator = allocator }; } - } - Darwin_Dl_info info; - if (!buffer || !darwin::dladdr(buffer, &info)) return backtrace::BACKTRACE_UNKNOWN; - return { - .offset = (uptr)buffer, - .function = info.dli_sname ? info.dli_sname.copy(allocator) : "???".copy(allocator), - .object_file = info.dli_fname.copy(allocator), - .file = "".copy(allocator), - .line = 0, - .allocator = allocator }; + } + Darwin_Dl_info info; + if (!buffer || !darwin::dladdr(buffer, &info)) return backtrace::BACKTRACE_UNKNOWN; + return { + .offset = (uptr)buffer, + .function = info.dli_sname ? info.dli_sname.copy(allocator) : "???".copy(allocator), + .object_file = info.dli_fname.copy(allocator), + .file = "".copy(allocator), + .line = 0, + .allocator = allocator }; } @@ -156,14 +162,11 @@ fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace) } list.free(); } - @pool() + String execpath = executable_path()!; + foreach (addr : backtrace) { - String execpath = executable_path(tmem)!; - foreach (addr : backtrace) - { - list.push(backtrace_load_element(allocator, execpath, addr, load_addr) ?? backtrace::BACKTRACE_UNKNOWN); - } - }; + list.push(backtrace_load_element(allocator, execpath, addr, load_addr) ?? backtrace::BACKTRACE_UNKNOWN); + } return list; } diff --git a/lib/std/os/posix/general.c3 b/lib/std/os/posix/general.c3 index 8a83951c3..573d750c4 100644 --- a/lib/std/os/posix/general.c3 +++ b/lib/std/os/posix/general.c3 @@ -1,3 +1,8 @@ module std::os::posix @if(env::POSIX); extern ZString* environ; + +extern fn CLong sysconf(CInt name); + +const CInt _SC_PAGESIZE @if(env::LINUX) = 30; +const CInt _SC_PAGESIZE @if(env::DARWIN) = 29; diff --git a/lib/std/os/posix/mman.c3 b/lib/std/os/posix/mman.c3 new file mode 100644 index 000000000..53cdf43cf --- /dev/null +++ b/lib/std/os/posix/mman.c3 @@ -0,0 +1,28 @@ +module std::os::posix @if(env::POSIX); +import libc; + + +const PROT_NONE = 0x00; // no permissions +const PROT_READ = 0x01; // pages can be read +const PROT_WRITE = 0x02; // pages can be written +const PROT_EXEC = 0x04; // pages can be executed + +const MAP_SHARED = 0x0001; // share changes +const MAP_PRIVATE = 0x0002; // changes are private + +const MAP_FILE = 0x0000; // map from file (default) +const MAP_ANONYMOUS = 0x1000; // allocated from memory, swap space + +const void* MAP_FAILED = (void *)(uptr)-1; // mmap failed +const MADV_NORMAL = 0; // no further special treatment +const MADV_RANDOM = 1; // expect random page refs +const MADV_SEQUENTIAL = 2; // expect sequential page refs +const MADV_WILLNEED = 3; // will need these pages +const MADV_DONTNEED = 4; // dont need these pages + +extern fn void* mmap(void*, usz, CInt, CInt, CInt, Off_t); +extern fn CInt munmap(void*, usz); +extern fn CInt mprotect(void*, usz, CInt); +extern fn int madvise(void*, usz, CInt); + +extern fn CInt getpagesize(); \ No newline at end of file diff --git a/lib/std/os/subprocess.c3 b/lib/std/os/subprocess.c3 index 715e65718..24aa4b21e 100644 --- a/lib/std/os/subprocess.c3 +++ b/lib/std/os/subprocess.c3 @@ -55,21 +55,18 @@ fn void? create_named_pipe_helper(void** rd, void **wr) @local @if(env::WIN32) tlocal long index = 0; long unique = index++; - @pool() - { - String s = string::tformat(`\\.\pipe\c3_subprocess.%08x.%08x.%d`, win32::getCurrentProcessId(), win32::getCurrentThreadId(), unique); - Win32_LPCSTR str = (Win32_LPCSTR)s.ptr; - *rd = win32::createNamedPipeA( - str, - win32::PIPE_ACCESS_INBOUND | win32::FILE_FLAG_OVERLAPPED, - win32::PIPE_TYPE_BYTE | win32::PIPE_WAIT, - 1, 4096, 4096, 0, &sa_attr); - if (win32::INVALID_HANDLE_VALUE == *rd) return FAILED_TO_CREATE_PIPE?; - *wr = win32::createFileA( - str, win32::GENERIC_WRITE, 0, &sa_attr, - win32::OPEN_EXISTING, win32::FILE_ATTRIBUTE_NORMAL, null); - if (win32::INVALID_HANDLE_VALUE == *wr) return FAILED_TO_CREATE_PIPE?; - }; + String s = string::bformat(&&(char[128]){}, `\\.\pipe\c3_subprocess.%08x.%08x.%d`, win32::getCurrentProcessId(), win32::getCurrentThreadId(), unique); + Win32_LPCSTR str = (Win32_LPCSTR)s.ptr; + *rd = win32::createNamedPipeA( + str, + win32::PIPE_ACCESS_INBOUND | win32::FILE_FLAG_OVERLAPPED, + win32::PIPE_TYPE_BYTE | win32::PIPE_WAIT, + 1, 4096, 4096, 0, &sa_attr); + if (win32::INVALID_HANDLE_VALUE == *rd) return FAILED_TO_CREATE_PIPE?; + *wr = win32::createFileA( + str, win32::GENERIC_WRITE, 0, &sa_attr, + win32::OPEN_EXISTING, win32::FILE_ATTRIBUTE_NORMAL, null); + if (win32::INVALID_HANDLE_VALUE == *wr) return FAILED_TO_CREATE_PIPE?; } fn WString convert_command_line_win32(String[] command_line) @inline @if(env::WIN32) @local @@ -143,12 +140,12 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str if (!win32::setHandleInformation(wr, win32::HANDLE_FLAG_INHERIT, 0)) return FAILED_TO_CREATE_PIPE?; } - @pool() + @stack_mem(2048; Allocator mem) { WString used_environment = null; if (!options.inherit_environment) { - DString env = dstring::temp_with_capacity(64); + DString env = dstring::new_with_capacity(mem, 64); if (!environment.len) { env.append("\0"); @@ -159,7 +156,7 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str env.append("\0"); } env.append("\0"); - used_environment = env.str_view().to_temp_wstring()!; + used_environment = env.str_view().to_wstring(mem)!; } // Handle stdin pipe if not inheriting @@ -266,26 +263,26 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str <* @require command_line.len > 0 *> -fn ZString* tcopy_command_line(String[] command_line) @local @inline @if(env::POSIX) +fn ZString* copy_command_line(Allocator mem, String[] command_line) @local @inline @if(env::POSIX) { - ZString* copy = mem::talloc_array(ZString, command_line.len + 1); + ZString* copy = allocator::alloc_array(mem, ZString, command_line.len + 1); foreach (i, str : command_line) { - copy[i] = str.zstr_tcopy(); + copy[i] = str.zstr_copy(mem); } copy[command_line.len] = null; return copy; } const ZString[1] EMPTY_ENVIRONMENT @if(env::POSIX) = { null }; -fn ZString* tcopy_env(String[] environment) @local @inline @if(env::POSIX) +fn ZString* copy_env(Allocator mem, String[] environment) @local @inline @if(env::POSIX) { if (!environment.len) return &EMPTY_ENVIRONMENT; - ZString* copy = mem::talloc_array(ZString, environment.len + 1); + ZString* copy = allocator::alloc_array(mem, ZString, environment.len + 1); copy[environment.len] = null; foreach (i, str : environment) { - copy[i] = str.zstr_tcopy(); + copy[i] = str.zstr_copy(mem); } return copy; } @@ -338,10 +335,10 @@ fn SubProcess? create(String[] command_line, SubProcessOptions options = {}, Str } Pid_t child; - @pool() + @stack_mem(2048; Allocator mem) { - ZString* command_line_copy = tcopy_command_line(command_line); - ZString* used_environment = options.inherit_environment ? posix::environ : tcopy_env(environment); + ZString* command_line_copy = copy_command_line(mem, command_line); + ZString* used_environment = options.inherit_environment ? posix::environ : copy_env(mem, environment); if (options.search_user_path) { if (posix::spawnp(&child, command_line_copy[0], &actions, null, command_line_copy, used_environment)) return FAILED_TO_START_PROCESS?; diff --git a/lib/std/os/win32/memoryapi.c3 b/lib/std/os/win32/memoryapi.c3 new file mode 100644 index 000000000..1919a0eda --- /dev/null +++ b/lib/std/os/win32/memoryapi.c3 @@ -0,0 +1,41 @@ +module std::os::win32 @if(env::WIN32); + +enum Win32_AllocationType : const Win32_DWORD +{ + MEM_COMMIT = 0x00001000, + MEM_RESERVE = 0x00002000, + MEM_RESET = 0x00080000, + MEM_RESET_UNDO = 0x01000000, + MEM_LARGE_PAGES = 0x20000000, + MEM_PHYSICAL = 0x00400000, + MEM_TOP_DOWN = 0x00100000, + MEM_WRITE_WATCH = 0x00200000 +} + +enum Win32_Protect : const Win32_DWORD +{ + PAGE_EXECUTE = 0x10, + PAGE_EXECUTE_READ = 0x20, + PAGE_EXECUTE_READWRITE = 0x40, + PAGE_EXECUTE_WRITECOPY = 0x80, + PAGE_NOACCESS = 0x01, + PAGE_READONLY = 0x02, + PAGE_READWRITE = 0x04, + PAGE_WRITECOPY = 0x08, + PAGE_TARGETS_INVALID = 0x40000000, + PAGE_TARGETS_NO_UPDATE = 0x40000000, + PAGE_GUARD = 0x100, + PAGE_NOCACHE = 0x200, + PAGE_WRITECOMBINE = 0x400, +} + +enum Win32_FreeType : const Win32_DWORD +{ + MEM_DECOMMIT = 0x00004000, + MEM_RELEASE = 0x00008000, + MEM_COALESCE_PLACEHOLDERS = 0x00000001, + MEM_PRESERVE_PLACEHOLDER = 0x00000002, +} +extern fn Win32_LPVOID virtualAlloc(Win32_LPVOID lpAddres, Win32_SIZE_T dwSize, Win32_AllocationType flAllocationType, Win32_DWORD flProtect) @extern("VirtualAlloc"); +extern fn Win32_PVOID virtualAlloc2(Win32_HANDLE process, Win32_PVOID baseAddress, Win32_SIZE_T size, Win32_AllocationType allocationType, Win32_ULONG pageProtection, Win32_MEM_EXTENDED_PARAMETER* extendedParameters, Win32_ULONG parameterCount) @extern("VirtualAlloc2"); +extern fn Win32_BOOL virtualFree(Win32_LPVOID lpAddress, Win32_SIZE_T dwSize, Win32_FreeType dwFreeType) @extern("VirtualFree"); diff --git a/lib/std/os/win32/winnt.c3 b/lib/std/os/win32/winnt.c3 new file mode 100644 index 000000000..8f1cf86c8 --- /dev/null +++ b/lib/std/os/win32/winnt.c3 @@ -0,0 +1,37 @@ +module std::os::win32 @if(env::WIN32); + +enum Win32_MEM_EXTENDED_PARAMETER_TYPE : CInt +{ + INVALID_TYPE, + ADDRESS_REQUIREMENTS, + NUMA_NODE, + PARTITION_HANDLE, + USER_PHYSICAL_HANDLE, + ATTRIBUTE_FLAGS, + IMAGE_MACHINE, + MAX +} +alias Win32_PMEM_EXTENDED_PARAMETER_TYPE = Win32_MEM_EXTENDED_PARAMETER_TYPE; + +enum Win32_MEM_EXTENDED_PARAMETER_ATTRIBUTE : const Win32_DWORD64 +{ + NONPAGED = 0x02, // The allocation is non-pageable. + NONPAGED_LARGE = 0x08, // The allocation is mapped using large pages. + NONPAGED_HUGE = 0x10, // The allocation is mapped using huge pages. + EC_CODE = 0x40, // The allocation will contain emulation-compatible (EC) code. +} + +struct Win32_MEM_EXTENDED_PARAMETER +{ + Win32_MEM_EXTENDED_PARAMETER_TYPE type; + union + { + Win32_MEM_EXTENDED_PARAMETER_ATTRIBUTE attribute; // If type is ATTRIBUTE_FLAGS + Win32_DWORD64 nodeNumber; // If type is NUMA_NODE + Win32_PVOID pointer; // If type is ADDRESS_REQUIREMENTS + Win32_SIZE_T size; + Win32_HANDLE handle; + Win32_DWORD uLong; + } +} +alias Win32_PMEM_EXTENDED_PARAMETER = Win32_MEM_EXTENDED_PARAMETER*; \ No newline at end of file diff --git a/releasenotes.md b/releasenotes.md index 70238cfb2..b4af23b0f 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -17,6 +17,7 @@ - Update error message for struct initialization #2286 - `$is_const` is deprecated in favour of `@is_const` based on `$defined`. - Multiline contract comments #2113 +- Removed the use of temp allocator in backtrace printing. ### Fixes - mkdir/rmdir would not work properly with substring paths on non-windows platforms. @@ -52,6 +53,7 @@ ### Stdlib changes - Improve contract for readline. #2280 - Added Whirlpool hash. +- Added string::bformat. ## 0.7.3 Change list diff --git a/test/test_suite/debug_symbols/defer_macro.c3t b/test/test_suite/debug_symbols/defer_macro.c3t index 6e01f47d8..013eac22e 100644 --- a/test/test_suite/debug_symbols/defer_macro.c3t +++ b/test/test_suite/debug_symbols/defer_macro.c3t @@ -681,8 +681,7 @@ no_match: ; preds = %compare !72 = !DILocation(line: 35, column: 49, scope: !66) !73 = !DILocalVariable(name: "name", arg: 3, scope: !66, file: !7, line: 35, type: !39) !74 = !DILocation(line: 35, column: 63, scope: !66) -!75 = !DILocation(line: 709, column: 18, scope: !76, inlinedAt: !78) -!76 = distinct !DISubprogram(name: "new", linkageName: "new", scope: !77, file: !77, line: 706, scopeLine: 706, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6) +!76 = distinct !DISubprogram(name: "new", linkageName: "new", scope: !77, file: !77, line: 710, scopeLine: 710, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !6) !77 = !DIFile(filename: "mem.c3", directory: !78 = !DILocation(line: 37, column: 9, scope: !66) !79 = distinct !DISubprogram(name: "test", linkageName: "test.test", scope: !7, file: !7, line: 45, type: !80, scopeLine: 45, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !21)