From a501beddb6b64428dab93ab16fdb558b9585defc Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 27 Nov 2023 11:18:42 +0100 Subject: [PATCH] Do not link with debug libc on win32 when using cross compile libs. Add delete methods to dstring. Fixes to macOS aarch64 codegen. Use glibc backtrace when available. Add load_* methods to file. The cast `(int[8])int_slice[:8]` now works. --- .github/workflows/main.yml | 4 +-- lib/std/core/dstring.c3 | 31 ++++++++++++++++ lib/std/core/string.c3 | 40 +++++++++++++++++++++ lib/std/core/string_iterator.c3 | 2 +- lib/std/io/file.c3 | 44 +++++++++++++++++++++++ lib/std/io/io.c3 | 2 +- lib/std/libc/os/posix.c3 | 10 ++++++ lib/std/os/posix/process.c3 | 15 ++++++-- releasenotes.md | 22 ++++++++++++ src/build/build.h | 2 ++ src/build/build_options.c | 7 ++++ src/build/builder.c | 1 + src/compiler/compiler.c | 23 ++++++++++-- src/compiler/enums.h | 1 + src/compiler/expr.c | 2 ++ src/compiler/linker.c | 19 ++++++++-- src/compiler/llvm_codegen.c | 2 +- src/compiler/llvm_codegen_expr.c | 19 ++++++++++ src/compiler/llvm_codegen_internal.h | 2 ++ src/compiler/llvm_codegen_module.c | 4 +-- src/compiler/sema_casts.c | 20 +++++++++-- src/compiler/sema_expr.c | 10 ++++-- src/compiler/target.c | 11 ++++++ src/version.h | 2 +- test/unit/regression/cast_slice_to_arr.c3 | 17 +++++++++ test/unit/stdlib/core/dstring.c3 | 22 ++++++++++++ 26 files changed, 313 insertions(+), 21 deletions(-) create mode 100644 test/unit/regression/cast_slice_to_arr.c3 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7d72646b2..73c2dfa1e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -99,8 +99,8 @@ jobs: install: git binutils mingw-w64-x86_64-clang mingw-w64-x86_64-ninja mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain mingw-w64-x86_64-python - shell: msys2 {0} run: | - pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-llvm-17.0.4-1-any.pkg.tar.zst - pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-lld-17.0.4-1-any.pkg.tar.zst + pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-llvm-17.0.6-1-any.pkg.tar.zst + pacman --noconfirm -U https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-lld-17.0.6-1-any.pkg.tar.zst - name: CMake run: | cmake -B build -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} diff --git a/lib/std/core/dstring.c3 b/lib/std/core/dstring.c3 index 14e406356..45cbbb92b 100644 --- a/lib/std/core/dstring.c3 +++ b/lib/std/core/dstring.c3 @@ -280,6 +280,37 @@ fn void DString.append_char(&self, char c) data.chars[data.len++] = c; } +/** + * @require start < self.len() + * @require end < self.len() + * @require end >= start "End must be same or equal to the start" + **/ +fn void DString.delete_range(&self, usz start, usz end) +{ + self.delete(start, end - start + 1); +} + +/** + * @require start < self.len() + * @require start + len <= self.len() + **/ +fn void DString.delete(&self, usz start, usz len = 1) +{ + if (!len) return; + StringData* data = self.data(); + usz new_len = data.len - len; + if (new_len == 0) + { + data.len = 0; + return; + } + usz len_after = data.len - start - len; + if (len_after > 0) + { + data.chars[start:len_after] = data.chars[start + len:len_after]; + } + data.len = new_len; +} macro void DString.append(&self, value) { diff --git a/lib/std/core/string.c3 b/lib/std/core/string.c3 index aa8ea42f5..33130f9c2 100644 --- a/lib/std/core/string.c3 +++ b/lib/std/core/string.c3 @@ -444,6 +444,11 @@ fn String String.new_ascii_to_upper(s, Allocator* allocator = mem::heap()) return copy; } +fn StringIterator String.iterator(s) +{ + return { s, 0 }; +} + fn String String.temp_ascii_to_upper(s) { return s.new_ascii_to_upper(mem::temp()); @@ -575,3 +580,38 @@ fn char! String.to_uchar(s) => s.to_integer(char); fn double! String.to_double(s) => s.to_real(double); fn float! String.to_float(s) => s.to_real(float); + +fn Splitter String.splitter(self, String split) +{ + return Splitter { self, split, 0 }; +} + +struct Splitter +{ + String string; + String split; + usz current; +} + +fn void Splitter.reset(&self) +{ + self.current = 0; +} + +fn String! Splitter.next(&self) +{ + usz len = self.string.len; + usz current = self.current; + if (current >= len) return IteratorResult.NO_MORE_ELEMENT?; + String remaining = self.string[current..]; + usz! next = remaining.index_of(self.split); + if (try next) + { + defer self.current = current + next + self.split.len; + return remaining[:next]; + } + self.current = len; + return remaining; +} + + diff --git a/lib/std/core/string_iterator.c3 b/lib/std/core/string_iterator.c3 index 246626508..299e0fd4d 100644 --- a/lib/std/core/string_iterator.c3 +++ b/lib/std/core/string_iterator.c3 @@ -20,4 +20,4 @@ fn Char32! StringIterator.next(&self) Char32 res = conv::utf8_to_char32(&self.utf8[current], &read)!; self.current += read; return res; -} \ No newline at end of file +} diff --git a/lib/std/io/file.c3 b/lib/std/io/file.c3 index ad00a8cff..d2339b34f 100644 --- a/lib/std/io/file.c3 +++ b/lib/std/io/file.c3 @@ -138,6 +138,50 @@ fn char! File.read_byte(&self) @dynamic return (char)c; } +/** + * Load up to buffer.len characters. Returns IoError.OVERFLOW if the file is longer + * than the buffer. + * + * @param filename "The path to the file to read" + * @param [in] buffer "The buffer to read to" + **/ +fn char[]! load_buffer(String filename, char[] buffer) +{ + File file = open(filename, "rb")!; + defer (void)file.close(); + usz len = file.seek(0, END)!; + if (len > buffer.len) return IoError.OVERFLOW?; + file.seek(0, SET)!; + usz read = 0; + while (read < len) + { + read += file.read(buffer[read:len - read])!; + } + return buffer[:len]; + +} + +fn char[]! load_new(String filename, Allocator* allocator = mem::heap()) +{ + File file = open(filename, "rb")!; + defer (void)file.close(); + usz len = file.seek(0, END)!; + file.seek(0, SET)!; + char* data = allocator.alloc_checked(len)!; + defer catch allocator.free(data); + usz read = 0; + while (read < len) + { + read += file.read(data[read:len - read])!; + } + return data[:len]; +} + +fn char[]! load_temp(String filename) +{ + return load_new(filename, mem::temp()); +} + /** * @require self.file `File must be initialized` */ diff --git a/lib/std/io/io.c3 b/lib/std/io/io.c3 index 3b033ff34..5f9260a50 100644 --- a/lib/std/io/io.c3 +++ b/lib/std/io/io.c3 @@ -49,7 +49,7 @@ fault IoError * @param stream * @require @is_instream(stream) **/ -macro String! readline(stream = io::stdin(), Allocator* allocator = mem::heap()) +macro String! readline(stream = io::stdin(), Allocator* allocator = mem::heap()) { bool $is_stream = @typeid(stream) == InStream*.typeid; $if $is_stream: diff --git a/lib/std/libc/os/posix.c3 b/lib/std/libc/os/posix.c3 index aaf32bd82..37f28e8c7 100644 --- a/lib/std/libc/os/posix.c3 +++ b/lib/std/libc/os/posix.c3 @@ -1,5 +1,15 @@ module libc @if(env::POSIX); + +extern fn void* dlopen(ZString path, int flags); +extern fn CInt dlclose(void*); +extern fn void* dlsym(void* handle, ZString symbol); + +const int RTLD_LAZY = 0x1; +const int RTLD_NOW = 0x2; +const int RTLD_LOCAL = 0x4; +const int RTLD_GLOBAL = 0x8; + def Pid_t = int; def Uid_t = uint; def Gid_t = uint; diff --git a/lib/std/os/posix/process.c3 b/lib/std/os/posix/process.c3 index fdc0e5d51..564a3beca 100644 --- a/lib/std/os/posix/process.c3 +++ b/lib/std/os/posix/process.c3 @@ -56,10 +56,21 @@ const CInt WNOHANG = 1; const CInt WUNTRACES = 2; JmpBuf backtrace_jmpbuf @local; -fn CInt backtrace(void** buffer, CInt size) @extern("backtrace") @weak +def BacktraceFn = fn CInt(void** buffer, CInt size); + +fn CInt backtrace(void** buffer, CInt size) { if (size < 1) return 0; - + void* handle = libc::dlopen("libc.so.6", libc::RTLD_LAZY); + if (handle) + { + BacktraceFn backtrace_fn = libc::dlsym(handle, "backtrace"); + libc::dlclose(handle); + if (backtrace_fn) + { + return backtrace_fn(buffer, size); + } + } // Loop through the return addresses until we hit a signal. // This avoids using the frame address. SignalFunction restore_backtrace = fn void(CInt) { diff --git a/releasenotes.md b/releasenotes.md index 67cee2ca9..99a0a882f 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -1,5 +1,27 @@ # C3C Release Notes +## 0.5.1 Change list + +### Changes / improvements +- Improved error messages for const errors. +- Do not link with debug libraries unless using static libraries. +- Add 'print-linking' build option. +- System linker may be used even if the target arch is different from current. +- Slice -> array/vector works for constant slice lenghts. + +### Fixes +- On Aarch64 use the correct frame pointer type. +- On Aarch64 macOS, ensure the minimum version is 11.0 (Big Sur) +- Fixes to the yacc grammar. +- Dsym generation on macOS will correctly emit -arch. +- Stacktrace on signals on Linux when backtrace is available. + +### Stdlib changes +- `delete` and `delete_range` added to DString. +- `Splitter` iterator added. +- `splitter` and `iterator` String methods. +- `load_new`, `load_buffer` and `load_temp` std::io::file functions. + ## 0.5.0 Change List ### Changes / improvements diff --git a/src/build/build.h b/src/build/build.h index cbf444bf4..7a332f5fb 100644 --- a/src/build/build.h +++ b/src/build/build.h @@ -379,6 +379,7 @@ typedef struct BuildOptions_ bool print_project_properties; bool print_precedence; bool print_build_settings; + bool print_linking; bool benchmarking; bool testing; } BuildOptions; @@ -450,6 +451,7 @@ typedef struct bool testing; bool read_stdin; bool print_output; + bool print_linking; bool no_entry; int build_threads; TrustLevel trust_level; diff --git a/src/build/build_options.c b/src/build/build_options.c index 482c62d22..5b39e8158 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -123,6 +123,7 @@ static void usage(void) OUTPUT(" -L - Append the directory to the linker search paths."); OUTPUT(" -z - Send the as a parameter to the linker."); OUTPUT(" --system-linker= - Use the system linker (default: no for cross compilation, yes otherwise)."); + OUTPUT(" --cc - Set C compiler (for C files in projects and use as system linker)."); OUTPUT(""); OUTPUT(" --use-stdlib= - Include the standard library (default: yes)."); OUTPUT(" --link-libc= - Link libc other default libraries (default: yes)."); @@ -140,6 +141,7 @@ static void usage(void) OUTPUT(" --fp-math=