diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ca87aeb..927a7ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,10 +8,8 @@ on: schedule: - cron: "0 0 * * *" -env: - TIMEOUT_MINUTES: 15 jobs: - build_and_test: + linux_build_and_test: runs-on: ubuntu-24.04 timeout-minutes: 15 steps: @@ -19,5 +17,13 @@ jobs: uses: actions/checkout@v4 - name: Build and test run: | - set -ex + ./run_tests.sh + macos_build_and_test: + runs-on: macos-latest + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build and test + run: | ./run_tests.sh diff --git a/bootstrap/main.cpp b/bootstrap/main.cpp index 0143ef3..57224aa 100644 --- a/bootstrap/main.cpp +++ b/bootstrap/main.cpp @@ -81,6 +81,19 @@ forceinline fn u8 mem_equal_range(T* a, T* b, u64 count) return memcmp(a, b, count * sizeof(T)) == 0; } +fn u8 memeq(u8* a, u8* b, u64 size) +{ + for (u64 i = 0; i < size; i += 1) + { + if (a[i] != b[i]) + { + return 0; + } + } + + return 1; +} + template struct Slice { @@ -241,6 +254,7 @@ struct StaticList // return (Hash)result; // } +#ifdef __linux__ // fn forceinline long syscall0(long n) // { // unsigned long ret; @@ -301,18 +315,6 @@ fn forceinline long syscall6(long n, long a1, long a2, long a3, long a4, long a5 return ret; } -fn u8 memeq(u8* a, u8* b, u64 size) -{ - for (u64 i = 0; i < size; i += 1) - { - if (a[i] != b[i]) - { - return 0; - } - } - - return 1; -} enum class SyscallX86_64 : u64 { read = 0, @@ -685,40 +687,69 @@ enum class SyscallX86_64 : u64 { futex_requeue = 456, }; -fn void* syscall_mmap(void* address, size_t length, int protection_flags, int map_flags, int fd, __off_t offset) +#endif + +fn void* syscall_mmap(void* address, size_t length, int protection_flags, int map_flags, int fd, signed long offset) { +#ifdef __linux__ return (void*) syscall6(static_cast(SyscallX86_64::mmap), (unsigned long)address, length, protection_flags, map_flags, fd, offset); +#else + return mmap(address, length, protection_flags, map_flags, fd, offset); +#endif } fn int syscall_mprotect(void *address, size_t length, int protection_flags) { +#ifdef __linux__ return syscall3(static_cast(SyscallX86_64::mprotect), (unsigned long)address, length, protection_flags); +#else + return mprotect(address, length, protection_flags); +#endif } fn int syscall_open(const char *file_path, int flags, int mode) { +#ifdef __linux__ return syscall3(static_cast(SyscallX86_64::open), (unsigned long)file_path, flags, mode); +#else + return open(file_path, flags, mode); +#endif } fn int syscall_fstat(int fd, struct stat *buffer) { +#ifdef __linux__ return syscall2(static_cast(SyscallX86_64::fstat), fd, (unsigned long)buffer); +#else + return fstat(fd, buffer); +#endif } fn ssize_t syscall_read(int fd, void* buffer, size_t bytes) { +#ifdef __linux__ return syscall3(static_cast(SyscallX86_64::read), fd, (unsigned long)buffer, bytes); +#else + return read(fd, buffer, bytes); +#endif } fn ssize_t syscall_write(int fd, const void *buffer, size_t bytes) { +#ifdef __linux__ return syscall3(static_cast(SyscallX86_64::write), fd, (unsigned long)buffer, bytes); +#else + return write(fd, buffer, bytes); +#endif } [[noreturn]] [[gnu::cold]] fn void syscall_exit(int status) { +#ifdef __linux__ (void)syscall1(231, status); - trap(); +#else + _exit(status); +#endif } [[noreturn]] [[gnu::cold]] fn void fail() @@ -3779,7 +3810,11 @@ String test_file_paths[] = { strlit("tests/simple_variable_declaration/main.nat"), }; +#ifdef __linux__ extern "C" void entry_point() +#else +int main() +#endif { instance.arena = Arena::init(Arena::default_size, Arena::minimum_granularity, KB(4)); diff --git a/compile.sh b/compile.sh index c667d8b..367b704 100755 --- a/compile.sh +++ b/compile.sh @@ -1,27 +1,23 @@ #!/bin/bash -NEST_BUILD_DIR=build -NEST_EXE_NAME=nest -set -ex -mkdir -p $NEST_BUILD_DIR -time clang++ \ --o $NEST_BUILD_DIR/$NEST_EXE_NAME \ -bootstrap/main.cpp \ -bootstrap/entry.S \ -`# -Oz` \ -`# -march=native` \ -`# -Wl,-strip-all` \ --g \ --std=gnu++23 \ --Wall \ --Wextra \ --Wpedantic \ --Wno-nested-anon-types \ --pedantic \ --ffreestanding \ --nostdlib \ --static \ --fno-exceptions \ --fno-stack-protector \ --ferror-limit=1 \ -`#-ftime-report` \ --MJ $NEST_BUILD_DIR/compile_commands.json + +function compile() +{ + build_dir=$1 + exe_name=$2 + debug_info=$3 + optimizations=$4 + + mkdir -p $build_dir + + compile_command="time clang++ -o $build_dir/$exe_name $debug_info $optimizations -std=gnu++20 -Wall -Wextra -Wpedantic -Wno-nested-anon-types -pedantic -fno-exceptions -fno-stack-protector -ferror-limit=1 -MJ $build_dir/compile_commands.json" + + case "$OSTYPE" in + darwin*) ;; + linux*) compile_command="$compile_command -ffreestanding -nostdlib -static bootstrap/entry.S" ;; + *) echo "unknown: $OSTYPE" ;; + esac + + compile_command="$compile_command bootstrap/main.cpp" + echo $compile_command + eval $compile_command +} diff --git a/debug.sh b/debug.sh index 384a76f..49db25f 100755 --- a/debug.sh +++ b/debug.sh @@ -1,4 +1,16 @@ #!/bin/bash -set -ex + +set -e + source ./compile.sh -gf2 -ex r $NEST_BUILD_DIR/$NEST_EXE_NAME +build_dir="build" +exe_name="nest" +exe_path=$build_dir/$exe_name + +compile $build_dir $exe_name "-g" ""; + +case "$OSTYPE" in + darwin*) lldb $exe_path ;; + linux*) gf2 -ex r $exe_path ;; + *) echo "unknown: $OSTYPE" ;; +esac diff --git a/run_tests.sh b/run_tests.sh index 041aa62..3e60860 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -1,4 +1,6 @@ #!/bin/bash + set -ex source ./compile.sh +compile "build" "nest" "-g" ""; build/nest