Merge remote-tracking branch 'offical/master'

This commit is contained in:
ed
2024-10-19 15:06:25 -04:00
548 changed files with 21207 additions and 4272 deletions
+15 -5
View File
@@ -36,6 +36,8 @@ jobs:
./odin test tests/core/speed.odin -file -all-packages -vet -strict-style -disallow-do -o:speed -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true ./odin test tests/core/speed.odin -file -all-packages -vet -strict-style -disallow-do -o:speed -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true
./odin test tests/vendor -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true ./odin test tests/vendor -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true
(cd tests/issues; ./run.sh) (cd tests/issues; ./run.sh)
./odin check tests/benchmark -vet -strict-style -no-entry-point
build_freebsd: build_freebsd:
name: FreeBSD Build, Check, and Test name: FreeBSD Build, Check, and Test
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -64,6 +66,7 @@ jobs:
./odin test tests/core/speed.odin -file -all-packages -vet -strict-style -disallow-do -o:speed -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true ./odin test tests/core/speed.odin -file -all-packages -vet -strict-style -disallow-do -o:speed -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true
./odin test tests/vendor -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true ./odin test tests/vendor -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true
(cd tests/issues; ./run.sh) (cd tests/issues; ./run.sh)
./odin check tests/benchmark -vet -strict-style -no-entry-point
ci: ci:
strategy: strategy:
fail-fast: false fail-fast: false
@@ -128,6 +131,8 @@ jobs:
cd tests/issues cd tests/issues
./run.sh ./run.sh
- name: Check benchmarks
run: ./odin check tests/benchmark -vet -strict-style -no-entry-point
- name: Odin check examples/all for Linux i386 - name: Odin check examples/all for Linux i386
run: ./odin check examples/all -vet -strict-style -disallow-do -target:linux_i386 run: ./odin check examples/all -vet -strict-style -disallow-do -target:linux_i386
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
@@ -203,6 +208,11 @@ jobs:
run: | run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
odin test tests/internal -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true odin test tests/internal -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true
- name: Check benchmarks
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
odin check tests/benchmark -vet -strict-style -no-entry-point
- name: Odin documentation tests - name: Odin documentation tests
shell: cmd shell: cmd
run: | run: |
@@ -257,16 +267,16 @@ jobs:
run: sudo apt-get install -y qemu-user qemu-user-static gcc-12-riscv64-linux-gnu libc6-riscv64-cross run: sudo apt-get install -y qemu-user qemu-user-static gcc-12-riscv64-linux-gnu libc6-riscv64-cross
- name: Odin run - name: Odin run
run: ./odin run examples/demo -vet -strict-style -disallow-do -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" run: ./odin run examples/demo -vet -strict-style -disallow-do -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
- name: Odin run -debug - name: Odin run -debug
run: ./odin run examples/demo -debug -vet -strict-style -disallow-do -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" run: ./odin run examples/demo -debug -vet -strict-style -disallow-do -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
- name: Normal Core library tests - name: Normal Core library tests
run: ./odin test tests/core/normal.odin -file -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" run: ./odin test tests/core/normal.odin -file -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
- name: Optimized Core library tests - name: Optimized Core library tests
run: ./odin test tests/core/speed.odin -o:speed -file -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" run: ./odin test tests/core/speed.odin -o:speed -file -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
- name: Internals tests - name: Internals tests
run: ./odin test tests/internal -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" run: ./odin test tests/internal -all-packages -vet -strict-style -disallow-do -define:ODIN_TEST_FANCY=false -define:ODIN_TEST_FAIL_ON_BAD_MEMORY=true -target:linux_riscv64 -extra-linker-flags:"-fuse-ld=/usr/bin/riscv64-linux-gnu-gcc-12 -static -Wl,-static" -no-rpath
+87 -59
View File
@@ -36,43 +36,55 @@ jobs:
cp -r bin dist cp -r bin dist
cp -r examples dist cp -r examples dist
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v4
with: with:
include-hidden-files: true
name: windows_artifacts name: windows_artifacts
path: dist path: dist
build_ubuntu: build_linux:
name: Ubuntu Build name: Linux Build
if: github.repository == 'odin-lang/Odin' if: github.repository == 'odin-lang/Odin'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: jirutka/setup-alpine@v1
with:
branch: v3.20
- name: (Linux) Download LLVM - name: (Linux) Download LLVM
run: | run: |
wget https://apt.llvm.org/llvm.sh apk add --no-cache \
chmod +x llvm.sh musl-dev llvm18-dev clang18 git mold lz4 \
sudo ./llvm.sh 18 libxml2-static llvm18-static zlib-static zstd-static \
echo "/usr/lib/llvm-18/bin" >> $GITHUB_PATH make
shell: alpine.sh --root {0}
- name: build odin - name: build odin
run: make nightly # NOTE: this build does slow compile times because of musl
run: ci/build_linux_static.sh
shell: alpine.sh {0}
- name: Odin run - name: Odin run
run: ./odin run examples/demo run: ./odin run examples/demo
- name: Copy artifacts - name: Copy artifacts
run: | run: |
mkdir dist FILE="odin-linux-amd64-nightly+$(date -I)"
cp odin dist mkdir $FILE
cp LICENSE dist cp odin $FILE
cp -r shared dist cp LICENSE $FILE
cp -r base dist cp -r shared $FILE
cp -r core dist cp -r base $FILE
cp -r vendor dist cp -r core $FILE
cp -r examples dist cp -r vendor $FILE
# Zipping so executable permissions are retained, see https://github.com/actions/upload-artifact/issues/38 cp -r examples $FILE
zip -r dist.zip dist # Creating a tarball so executable permissions are retained, see https://github.com/actions/upload-artifact/issues/38
tar -czvf dist.tar.gz $FILE
- name: Odin run
run: |
FILE="odin-linux-amd64-nightly+$(date -I)"
$FILE/odin run examples/demo
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v4
with: with:
name: ubuntu_artifacts name: linux_artifacts
path: dist.zip path: dist.tar.gz
build_macos: build_macos:
name: MacOS Build name: MacOS Build
if: github.repository == 'odin-lang/Odin' if: github.repository == 'odin-lang/Odin'
@@ -89,24 +101,27 @@ jobs:
run: CXXFLAGS="-L/usr/lib/system -L/usr/lib" make nightly run: CXXFLAGS="-L/usr/lib/system -L/usr/lib" make nightly
- name: Bundle - name: Bundle
run: | run: |
mkdir dist FILE="odin-macos-amd64-nightly+$(date -I)"
cp odin dist mkdir $FILE
cp LICENSE dist cp odin $FILE
cp -r shared dist cp LICENSE $FILE
cp -r base dist cp -r shared $FILE
cp -r core dist cp -r base $FILE
cp -r vendor dist cp -r core $FILE
cp -r examples dist cp -r vendor $FILE
dylibbundler -b -x dist/odin -d dist/libs -od -p @executable_path/libs cp -r examples $FILE
# Zipping so executable permissions are retained, see https://github.com/actions/upload-artifact/issues/38 dylibbundler -b -x $FILE/odin -d $FILE/libs -od -p @executable_path/libs
zip -r dist.zip dist # Creating a tarball so executable permissions are retained, see https://github.com/actions/upload-artifact/issues/38
tar -czvf dist.tar.gz $FILE
- name: Odin run - name: Odin run
run: ./dist/odin run examples/demo run: |
FILE="odin-macos-amd64-nightly+$(date -I)"
$FILE/odin run examples/demo
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v4
with: with:
name: macos_artifacts name: macos_artifacts
path: dist.zip path: dist.tar.gz
build_macos_arm: build_macos_arm:
name: MacOS ARM Build name: MacOS ARM Build
if: github.repository == 'odin-lang/Odin' if: github.repository == 'odin-lang/Odin'
@@ -123,30 +138,33 @@ jobs:
run: CXXFLAGS="-L/usr/lib/system -L/usr/lib" make nightly run: CXXFLAGS="-L/usr/lib/system -L/usr/lib" make nightly
- name: Bundle - name: Bundle
run: | run: |
mkdir dist FILE="odin-macos-arm64-nightly+$(date -I)"
cp odin dist mkdir $FILE
cp LICENSE dist cp odin $FILE
cp -r shared dist cp LICENSE $FILE
cp -r base dist cp -r shared $FILE
cp -r core dist cp -r base $FILE
cp -r vendor dist cp -r core $FILE
cp -r examples dist cp -r vendor $FILE
dylibbundler -b -x dist/odin -d dist/libs -od -p @executable_path/libs cp -r examples $FILE
# Zipping so executable permissions are retained, see https://github.com/actions/upload-artifact/issues/38 dylibbundler -b -x $FILE/odin -d $FILE/libs -od -p @executable_path/libs
zip -r dist.zip dist # Creating a tarball so executable permissions are retained, see https://github.com/actions/upload-artifact/issues/38
tar -czvf dist.tar.gz $FILE
- name: Odin run - name: Odin run
run: ./dist/odin run examples/demo run: |
FILE="odin-macos-arm64-nightly+$(date -I)"
$FILE/odin run examples/demo
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v4
with: with:
name: macos_arm_artifacts name: macos_arm_artifacts
path: dist.zip path: dist.tar.gz
upload_b2: upload_b2:
runs-on: [ubuntu-latest] runs-on: [ubuntu-latest]
needs: [build_windows, build_macos, build_macos_arm, build_ubuntu] needs: [build_windows, build_macos, build_macos_arm, build_linux]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v2 - uses: actions/setup-python@v5
with: with:
python-version: '3.8.x' python-version: '3.8.x'
@@ -160,24 +178,33 @@ jobs:
run: python -c "import sys; print(sys.version)" run: python -c "import sys; print(sys.version)"
- name: Download Windows artifacts - name: Download Windows artifacts
uses: actions/download-artifact@v1
uses: actions/download-artifact@v4.1.7
with: with:
name: windows_artifacts name: windows_artifacts
path: windows_artifacts
- name: Download Ubuntu artifacts - name: Download Ubuntu artifacts
uses: actions/download-artifact@v1 uses: actions/download-artifact@v4.1.7
with: with:
name: ubuntu_artifacts name: linux_artifacts
path: linux_artifacts
- name: Download macOS artifacts - name: Download macOS artifacts
uses: actions/download-artifact@v1 uses: actions/download-artifact@v4.1.7
with: with:
name: macos_artifacts name: macos_artifacts
path: macos_artifacts
- name: Download macOS arm artifacts - name: Download macOS arm artifacts
uses: actions/download-artifact@v1 uses: actions/download-artifact@v4.1.7
with: with:
name: macos_arm_artifacts name: macos_arm_artifacts
path: macos_arm_artifacts
- name: Debug
run: |
tree -L 2
- name: Create archives and upload - name: Create archives and upload
shell: bash shell: bash
@@ -187,9 +214,10 @@ jobs:
BUCKET: ${{ secrets.B2_BUCKET }} BUCKET: ${{ secrets.B2_BUCKET }}
DAYS_TO_KEEP: ${{ secrets.B2_DAYS_TO_KEEP }} DAYS_TO_KEEP: ${{ secrets.B2_DAYS_TO_KEEP }}
run: | run: |
file linux_artifacts/dist.tar.gz
python3 ci/nightly.py artifact windows-amd64 windows_artifacts/ python3 ci/nightly.py artifact windows-amd64 windows_artifacts/
python3 ci/nightly.py artifact ubuntu-amd64 ubuntu_artifacts/dist.zip python3 ci/nightly.py artifact linux-amd64 linux_artifacts/dist.tar.gz
python3 ci/nightly.py artifact macos-amd64 macos_artifacts/dist.zip python3 ci/nightly.py artifact macos-amd64 macos_artifacts/dist.tar.gz
python3 ci/nightly.py artifact macos-arm64 macos_arm_artifacts/dist.zip python3 ci/nightly.py artifact macos-arm64 macos_arm_artifacts/dist.tar.gz
python3 ci/nightly.py prune python3 ci/nightly.py prune
python3 ci/nightly.py json python3 ci/nightly.py json
+3
View File
@@ -266,6 +266,9 @@ bin/
*.exe *.exe
*.obj *.obj
*.pdb *.pdb
*.res
desktop.ini
Thumbs.db
# - Linux/MacOS # - Linux/MacOS
odin odin
+1 -1
View File
@@ -1,5 +1,5 @@
// This is purely for documentation // This is purely for documentation
//+build ignore #+build ignore
package intrinsics package intrinsics
// Package-Related // Package-Related
+1 -1
View File
@@ -18,7 +18,7 @@
// This could change at a later date if the all these data structures are // This could change at a later date if the all these data structures are
// implemented within the compiler rather than in this "preload" file // implemented within the compiler rather than in this "preload" file
// //
//+no-instrumentation #+no-instrumentation
package runtime package runtime
import "base:intrinsics" import "base:intrinsics"
+49 -4
View File
@@ -6,6 +6,39 @@ import "base:intrinsics"
Maybe :: union($T: typeid) {T} Maybe :: union($T: typeid) {T}
/*
Recovers the containing/parent struct from a pointer to one of its fields.
Works by "walking back" to the struct's starting address using the offset between the field and the struct.
Inputs:
- ptr: Pointer to the field of a container struct
- T: The type of the container struct
- field_name: The name of the field in the `T` struct
Returns:
- A pointer to the container struct based on a pointer to a field in it
Example:
package container_of
import "base:runtime"
Node :: struct {
value: int,
prev: ^Node,
next: ^Node,
}
main :: proc() {
node: Node
field_ptr := &node.next
container_struct_ptr: ^Node = runtime.container_of(field_ptr, Node, "next")
assert(container_struct_ptr == &node)
assert(uintptr(field_ptr) - uintptr(container_struct_ptr) == size_of(node.value) + size_of(node.prev))
}
Output:
^Node
*/
@(builtin, require_results) @(builtin, require_results)
container_of :: #force_inline proc "contextless" (ptr: $P/^$Field_Type, $T: typeid, $field_name: string) -> ^T container_of :: #force_inline proc "contextless" (ptr: $P/^$Field_Type, $T: typeid, $field_name: string) -> ^T
where intrinsics.type_has_field(T, field_name), where intrinsics.type_has_field(T, field_name),
@@ -350,12 +383,23 @@ _make_dynamic_array_len_cap :: proc(array: ^Raw_Dynamic_Array, size_of_elem, ali
return return
} }
// `make_map` allocates and initializes a map. Like `new`, the first argument is a type, not a value. // `make_map` initializes a map with an allocator. Like `new`, the first argument is a type, not a value.
// Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it. // Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it.
// //
// Note: Prefer using the procedure group `make`. // Note: Prefer using the procedure group `make`.
@(builtin, require_results) @(builtin, require_results)
make_map :: proc($T: typeid/map[$K]$E, #any_int capacity: int = 1<<MAP_MIN_LOG2_CAPACITY, allocator := context.allocator, loc := #caller_location) -> (m: T, err: Allocator_Error) #optional_allocator_error { make_map :: proc($T: typeid/map[$K]$E, allocator := context.allocator) -> (m: T) {
m.allocator = allocator
return m
}
// `make_map_cap` initializes a map with an allocator and allocates space using `capacity`.
// Like `new`, the first argument is a type, not a value.
// Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it.
//
// Note: Prefer using the procedure group `make`.
@(builtin, require_results)
make_map_cap :: proc($T: typeid/map[$K]$E, #any_int capacity: int = 1<<MAP_MIN_LOG2_CAPACITY, allocator := context.allocator, loc := #caller_location) -> (m: T, err: Allocator_Error) #optional_allocator_error {
make_map_expr_error_loc(loc, capacity) make_map_expr_error_loc(loc, capacity)
context.allocator = allocator context.allocator = allocator
@@ -392,6 +436,7 @@ make :: proc{
make_dynamic_array_len, make_dynamic_array_len,
make_dynamic_array_len_cap, make_dynamic_array_len_cap,
make_map, make_map,
make_map_cap,
make_multi_pointer, make_multi_pointer,
make_soa_slice, make_soa_slice,
@@ -913,7 +958,7 @@ card :: proc "contextless" (s: $S/bit_set[$E; $U]) -> int {
@builtin @builtin
@(disabled=ODIN_DISABLE_ASSERT) @(disabled=ODIN_DISABLE_ASSERT)
assert :: proc(condition: bool, message := "", loc := #caller_location) { assert :: proc(condition: bool, message := #caller_expression(condition), loc := #caller_location) {
if !condition { if !condition {
// NOTE(bill): This is wrapped in a procedure call // NOTE(bill): This is wrapped in a procedure call
// to improve performance to make the CPU not // to improve performance to make the CPU not
@@ -952,7 +997,7 @@ unimplemented :: proc(message := "", loc := #caller_location) -> ! {
@builtin @builtin
@(disabled=ODIN_DISABLE_ASSERT) @(disabled=ODIN_DISABLE_ASSERT)
assert_contextless :: proc "contextless" (condition: bool, message := "", loc := #caller_location) { assert_contextless :: proc "contextless" (condition: bool, message := #caller_expression(condition), loc := #caller_location) {
if !condition { if !condition {
// NOTE(bill): This is wrapped in a procedure call // NOTE(bill): This is wrapped in a procedure call
// to improve performance to make the CPU not // to improve performance to make the CPU not
+3 -3
View File
@@ -1,6 +1,6 @@
//+private #+private
//+build linux, darwin, freebsd, openbsd, netbsd, haiku #+build linux, darwin, freebsd, openbsd, netbsd, haiku
//+no-instrumentation #+no-instrumentation
package runtime package runtime
import "base:intrinsics" import "base:intrinsics"
+3 -3
View File
@@ -1,6 +1,6 @@
//+private #+private
//+build wasm32, wasm64p32 #+build wasm32, wasm64p32
//+no-instrumentation #+no-instrumentation
package runtime package runtime
import "base:intrinsics" import "base:intrinsics"
+3 -3
View File
@@ -1,6 +1,6 @@
//+private #+private
//+build windows #+build windows
//+no-instrumentation #+no-instrumentation
package runtime package runtime
import "base:intrinsics" import "base:intrinsics"
+12 -10
View File
@@ -20,25 +20,27 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
// //
aligned_alloc :: proc(size, alignment: int, old_ptr: rawptr, old_size: int, zero_memory := true) -> ([]byte, Allocator_Error) { aligned_alloc :: proc(size, alignment: int, old_ptr: rawptr, old_size: int, zero_memory := true) -> ([]byte, Allocator_Error) {
// Not(flysand): We need to reserve enough space for alignment, which
// includes the user data itself, the space to store the pointer to
// allocation start, as well as the padding required to align both
// the user data and the pointer.
a := max(alignment, align_of(rawptr)) a := max(alignment, align_of(rawptr))
space := size + a - 1 space := a-1 + size_of(rawptr) + size
allocated_mem: rawptr allocated_mem: rawptr
force_copy := old_ptr != nil && a > align_of(rawptr) force_copy := old_ptr != nil && alignment > align_of(rawptr)
if !force_copy && old_ptr != nil { if old_ptr != nil && !force_copy {
original_old_ptr := ([^]rawptr)(old_ptr)[-1] original_old_ptr := ([^]rawptr)(old_ptr)[-1]
allocated_mem = heap_resize(original_old_ptr, space+size_of(rawptr)) allocated_mem = heap_resize(original_old_ptr, space)
} else { } else {
allocated_mem = heap_alloc(space+size_of(rawptr), zero_memory) allocated_mem = heap_alloc(space, zero_memory)
} }
aligned_mem := rawptr(([^]u8)(allocated_mem)[size_of(rawptr):]) aligned_mem := rawptr(([^]u8)(allocated_mem)[size_of(rawptr):])
ptr := uintptr(aligned_mem) ptr := uintptr(aligned_mem)
aligned_ptr := (ptr - 1 + uintptr(a)) & -uintptr(a) aligned_ptr := (ptr + uintptr(a)-1) & ~(uintptr(a)-1)
diff := int(aligned_ptr - ptr) if allocated_mem == nil {
if (size + diff) > space || allocated_mem == nil {
aligned_free(old_ptr) aligned_free(old_ptr)
aligned_free(allocated_mem) aligned_free(allocated_mem)
return nil, .Out_Of_Memory return nil, .Out_Of_Memory
@@ -48,7 +50,7 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
([^]rawptr)(aligned_mem)[-1] = allocated_mem ([^]rawptr)(aligned_mem)[-1] = allocated_mem
if force_copy { if force_copy {
mem_copy_non_overlapping(aligned_mem, old_ptr, old_size) mem_copy_non_overlapping(aligned_mem, old_ptr, min(old_size, size))
aligned_free(old_ptr) aligned_free(old_ptr)
} }
+2 -2
View File
@@ -1,5 +1,5 @@
//+build orca #+build orca
//+private #+private
package runtime package runtime
foreign { foreign {
+2 -2
View File
@@ -1,5 +1,5 @@
//+build js, wasi, freestanding, essence #+build js, wasi, freestanding, essence
//+private #+private
package runtime package runtime
_heap_alloc :: proc "contextless" (size: int, zero_memory := true) -> rawptr { _heap_alloc :: proc "contextless" (size: int, zero_memory := true) -> rawptr {
+2 -2
View File
@@ -1,5 +1,5 @@
//+build linux, darwin, freebsd, openbsd, netbsd, haiku #+build linux, darwin, freebsd, openbsd, netbsd, haiku
//+private #+private
package runtime package runtime
when ODIN_OS == .Darwin { when ODIN_OS == .Darwin {
+8 -5
View File
@@ -1,4 +1,4 @@
//+vet !cast #+vet !cast
package runtime package runtime
import "base:intrinsics" import "base:intrinsics"
@@ -118,16 +118,15 @@ mem_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> r
DEFAULT_ALIGNMENT :: 2*align_of(rawptr) DEFAULT_ALIGNMENT :: 2*align_of(rawptr)
mem_alloc_bytes :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) { mem_alloc_bytes :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
if size == 0 { assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
return nil, nil if size == 0 || allocator.procedure == nil{
}
if allocator.procedure == nil {
return nil, nil return nil, nil
} }
return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc) return allocator.procedure(allocator.data, .Alloc, size, alignment, nil, 0, loc)
} }
mem_alloc :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) { mem_alloc :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
if size == 0 || allocator.procedure == nil { if size == 0 || allocator.procedure == nil {
return nil, nil return nil, nil
} }
@@ -135,6 +134,7 @@ mem_alloc :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, a
} }
mem_alloc_non_zeroed :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) { mem_alloc_non_zeroed :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
if size == 0 || allocator.procedure == nil { if size == 0 || allocator.procedure == nil {
return nil, nil return nil, nil
} }
@@ -174,6 +174,7 @@ mem_free_all :: #force_inline proc(allocator := context.allocator, loc := #calle
} }
_mem_resize :: #force_inline proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, should_zero: bool, loc := #caller_location) -> (data: []byte, err: Allocator_Error) { _mem_resize :: #force_inline proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, should_zero: bool, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
if allocator.procedure == nil { if allocator.procedure == nil {
return nil, nil return nil, nil
} }
@@ -215,9 +216,11 @@ _mem_resize :: #force_inline proc(ptr: rawptr, old_size, new_size: int, alignmen
} }
mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) { mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
return _mem_resize(ptr, old_size, new_size, alignment, allocator, true, loc) return _mem_resize(ptr, old_size, new_size, alignment, allocator, true, loc)
} }
non_zero_mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) { non_zero_mem_resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
return _mem_resize(ptr, old_size, new_size, alignment, allocator, false, loc) return _mem_resize(ptr, old_size, new_size, alignment, allocator, false, loc)
} }
+2 -2
View File
@@ -1,5 +1,5 @@
//+build freebsd, openbsd, netbsd #+build freebsd, openbsd, netbsd
//+private #+private
package runtime package runtime
foreign import libc "system:c" foreign import libc "system:c"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build darwin #+build darwin
//+private #+private
package runtime package runtime
import "base:intrinsics" import "base:intrinsics"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build freestanding #+build freestanding
//+private #+private
package runtime package runtime
// TODO(bill): reimplement `os.write` // TODO(bill): reimplement `os.write`
+2 -2
View File
@@ -1,5 +1,5 @@
//+build haiku #+build haiku
//+private #+private
package runtime package runtime
foreign import libc "system:c" foreign import libc "system:c"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build js #+build js
//+private #+private
package runtime package runtime
foreign import "odin_env" foreign import "odin_env"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private #+private
package runtime package runtime
import "base:intrinsics" import "base:intrinsics"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build orca #+build orca
//+private #+private
package runtime package runtime
import "base:intrinsics" import "base:intrinsics"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build wasi #+build wasi
//+private #+private
package runtime package runtime
foreign import wasi "wasi_snapshot_preview1" foreign import wasi "wasi_snapshot_preview1"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build windows #+build windows
//+private #+private
package runtime package runtime
foreign import kernel32 "system:Kernel32.lib" foreign import kernel32 "system:Kernel32.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private #+private
package runtime package runtime
foreign import "system:Foundation.framework" foreign import "system:Foundation.framework"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js #+build js
package runtime package runtime
init_default_context_for_js: Context init_default_context_for_js: Context
+42 -20
View File
@@ -1,4 +1,4 @@
//+build wasm32, wasm64p32 #+build wasm32, wasm64p32
package runtime package runtime
@(private="file") @(private="file")
@@ -14,33 +14,57 @@ ti_uint :: struct #raw_union {
} }
@(link_name="__ashlti3", linkage="strong") @(link_name="__ashlti3", linkage="strong")
__ashlti3 :: proc "contextless" (la, ha: u64, b_: u32) -> i128 { __ashlti3 :: proc "contextless" (a: i128, b: u32) -> i128 {
bits_in_dword :: size_of(u32)*8 bits :: 64
b := u32(b_)
input, result: ti_int input: ti_int = ---
input.lo, input.hi = la, ha result: ti_int = ---
if b & bits_in_dword != 0 { input.all = a
if b & bits != 0 {
result.lo = 0 result.lo = 0
result.hi = input.lo << (b-bits_in_dword) result.hi = input.lo << (b-bits)
} else { } else {
if b == 0 { if b == 0 {
return input.all return a
} }
result.lo = input.lo<<b result.lo = input.lo<<b
result.hi = (input.hi<<b) | (input.lo>>(bits_in_dword-b)) result.hi = (input.hi<<b) | (input.lo>>(bits-b))
} }
return result.all return result.all
} }
__ashlti3_unsigned :: proc "contextless" (a: u128, b: u32) -> u128 {
return cast(u128)__ashlti3(cast(i128)a, b)
}
@(link_name="__mulddi3", linkage="strong")
__mulddi3 :: proc "contextless" (a, b: u64) -> i128 {
r: ti_int
bits :: 32
mask :: ~u64(0) >> bits
r.lo = (a & mask) * (b & mask)
t := r.lo >> bits
r.lo &= mask
t += (a >> bits) * (b & mask)
r.lo += (t & mask) << bits
r.hi = t >> bits
t = r.lo >> bits
r.lo &= mask
t += (b >> bits) * (a & mask)
r.lo += (t & mask) << bits
r.hi += t >> bits
r.hi += (a >> bits) * (b >> bits)
return r.all
}
@(link_name="__multi3", linkage="strong") @(link_name="__multi3", linkage="strong")
__multi3 :: proc "contextless" (la, ha, lb, hb: u64) -> i128 { __multi3 :: proc "contextless" (a, b: i128) -> i128 {
x, y, r: ti_int x, y, r: ti_int
x.lo, x.hi = la, ha x.all = a
y.lo, y.hi = lb, hb y.all = b
r.all = i128(x.lo * y.lo) // TODO this is incorrect r.all = __mulddi3(x.lo, y.lo)
r.hi += x.hi*y.lo + x.lo*y.hi r.hi += x.hi*y.lo + x.lo*y.hi
return r.all return r.all
} }
@@ -54,18 +78,16 @@ udivti3 :: proc "c" (la, ha, lb, hb: u64) -> u128 {
} }
@(link_name="__lshrti3", linkage="strong") @(link_name="__lshrti3", linkage="strong")
__lshrti3 :: proc "c" (la, ha: u64, b: u32) -> i128 { __lshrti3 :: proc "c" (a: i128, b: u32) -> i128 {
bits :: size_of(u32)*8 bits :: 64
input, result: ti_int input, result: ti_int
input.lo = la input.all = a
input.hi = ha
if b & bits != 0 { if b & bits != 0 {
result.hi = 0 result.hi = 0
result.lo = input.hi >> (b - bits) result.lo = input.hi >> (b - bits)
} else if b == 0 { } else if b == 0 {
return input.all return a
} else { } else {
result.hi = input.hi >> b result.hi = input.hi >> b
result.lo = (input.hi << (bits - b)) | (input.lo >> b) result.lo = (input.hi << (bits - b)) | (input.lo >> b)
+2 -2
View File
@@ -1,5 +1,5 @@
//+private #+private
//+no-instrumentation #+no-instrumentation
package runtime package runtime
foreign import kernel32 "system:Kernel32.lib" foreign import kernel32 "system:Kernel32.lib"
+2 -2
View File
@@ -1,5 +1,5 @@
//+private #+private
//+no-instrumentation #+no-instrumentation
package runtime package runtime
@require foreign import "system:int64.lib" @require foreign import "system:int64.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build wasm32, wasm64p32 #+build wasm32, wasm64p32
package runtime package runtime
import "base:intrinsics" import "base:intrinsics"
+36 -8
View File
@@ -19,12 +19,12 @@ if "%VSCMD_ARG_TGT_ARCH%" neq "x64" (
) )
) )
for /f "usebackq tokens=1,2 delims=,=- " %%i in (`wmic os get LocalDateTime /value`) do @if %%i==LocalDateTime ( for /f %%i in ('powershell get-date -format "{yyyyMMdd}"') do (
set CURR_DATE_TIME=%%j set CURR_DATE_TIME=%%i
) )
set curr_year=%CURR_DATE_TIME:~0,4% set curr_year=%CURR_DATE_TIME:~0,4%
set curr_month=%CURR_DATE_TIME:~4,2% set curr_month=%CURR_DATE_TIME:~4,2%
set curr_day=%CURR_DATE_TIME:~6,2%
:: Make sure this is a decent name and not generic :: Make sure this is a decent name and not generic
set exe_name=odin.exe set exe_name=odin.exe
@@ -45,7 +45,19 @@ if "%2" == "1" (
set nightly=0 set nightly=0
) )
set odin_version_raw="dev-%curr_year%-%curr_month%" if %release_mode% equ 0 (
set V1=%curr_year%
set V2=%curr_month%
set V3=%curr_day%
) else (
set V1=%curr_year%
set V2=%curr_month%
set V3=0
)
set V4=0
set odin_version_full="%V1%.%V2%.%V3%.%V4%"
set odin_version_raw="dev-%V1%-%V2%"
set compiler_flags= -nologo -Oi -TP -fp:precise -Gm- -MP -FC -EHsc- -GR- -GF set compiler_flags= -nologo -Oi -TP -fp:precise -Gm- -MP -FC -EHsc- -GR- -GF
rem Parse source code as utf-8 even on shift-jis and other codepages rem Parse source code as utf-8 even on shift-jis and other codepages
@@ -53,18 +65,30 @@ rem See https://learn.microsoft.com/en-us/cpp/build/reference/utf-8-set-source-a
set compiler_flags= %compiler_flags% /utf-8 set compiler_flags= %compiler_flags% /utf-8
set compiler_defines= -DODIN_VERSION_RAW=\"%odin_version_raw%\" set compiler_defines= -DODIN_VERSION_RAW=\"%odin_version_raw%\"
rem fileversion is defined as {Major,Minor,Build,Private: u16} so a bit limited
set rc_flags=-nologo ^
-DV1=%V1% -DV2=%V2% -DV3=%V3% -DV4=%V4% ^
-DVF=%odin_version_full% -DNIGHTLY=%nightly%
where /Q git.exe || goto skip_git_hash
if not exist .git\ goto skip_git_hash if not exist .git\ goto skip_git_hash
for /f "tokens=1,2" %%i IN ('git show "--pretty=%%cd %%h" "--date=format:%%Y-%%m" --no-patch --no-notes HEAD') do ( for /f "tokens=1,2" %%i IN ('git show "--pretty=%%cd %%h" "--date=format:%%Y-%%m" --no-patch --no-notes HEAD') do (
set odin_version_raw=dev-%%i set odin_version_raw=dev-%%i
set GIT_SHA=%%j set GIT_SHA=%%j
) )
if %ERRORLEVEL% equ 0 set compiler_defines=%compiler_defines% -DGIT_SHA=\"%GIT_SHA%\" if %ERRORLEVEL% equ 0 (
set compiler_defines=%compiler_defines% -DGIT_SHA=\"%GIT_SHA%\"
set rc_flags=%rc_flags% -DGIT_SHA=%GIT_SHA% -DVP=%odin_version_raw%:%GIT_SHA%
) else (
set rc_flags=%rc_flags% -DVP=%odin_version_raw%
)
:skip_git_hash :skip_git_hash
if %nightly% equ 1 set compiler_defines=%compiler_defines% -DNIGHTLY if %nightly% equ 1 set compiler_defines=%compiler_defines% -DNIGHTLY
if %release_mode% EQU 0 ( rem Debug if %release_mode% EQU 0 ( rem Debug
set compiler_flags=%compiler_flags% -Od -MDd -Z7 set compiler_flags=%compiler_flags% -Od -MDd -Z7
set rc_flags=%rc_flags% -D_DEBUG
) else ( rem Release ) else ( rem Release
set compiler_flags=%compiler_flags% -O2 -MT -Z7 set compiler_flags=%compiler_flags% -O2 -MT -Z7
set compiler_defines=%compiler_defines% -DNO_ARRAY_BOUNDS_CHECK set compiler_defines=%compiler_defines% -DNO_ARRAY_BOUNDS_CHECK
@@ -82,6 +106,8 @@ set libs= ^
kernel32.lib ^ kernel32.lib ^
Synchronization.lib ^ Synchronization.lib ^
bin\llvm\windows\LLVM-C.lib bin\llvm\windows\LLVM-C.lib
set odin_res=misc\odin.res
set odin_rc=misc\odin.rc
rem DO NOT TOUCH! rem DO NOT TOUCH!
rem THIS TILDE STUFF IS FOR DEVELOPMENT ONLY! rem THIS TILDE STUFF IS FOR DEVELOPMENT ONLY!
@@ -93,7 +119,7 @@ if %tilde_backend% EQU 1 (
rem DO NOT TOUCH! rem DO NOT TOUCH!
set linker_flags= -incremental:no -opt:ref -subsystem:console set linker_flags= -incremental:no -opt:ref -subsystem:console -MANIFEST:EMBED
if %release_mode% EQU 0 ( rem Debug if %release_mode% EQU 0 ( rem Debug
set linker_flags=%linker_flags% -debug /NATVIS:src\odin_compiler.natvis set linker_flags=%linker_flags% -debug /NATVIS:src\odin_compiler.natvis
@@ -102,19 +128,21 @@ if %release_mode% EQU 0 ( rem Debug
) )
set compiler_settings=%compiler_includes% %compiler_flags% %compiler_warnings% %compiler_defines% set compiler_settings=%compiler_includes% %compiler_flags% %compiler_warnings% %compiler_defines%
set linker_settings=%libs% %linker_flags% set linker_settings=%libs% %odin_res% %linker_flags%
del *.pdb > NUL 2> NUL del *.pdb > NUL 2> NUL
del *.ilk > NUL 2> NUL del *.ilk > NUL 2> NUL
rc %rc_flags% %odin_rc%
cl %compiler_settings% "src\main.cpp" "src\libtommath.cpp" /link %linker_settings% -OUT:%exe_name% cl %compiler_settings% "src\main.cpp" "src\libtommath.cpp" /link %linker_settings% -OUT:%exe_name%
mt -nologo -inputresource:%exe_name%;#1 -manifest misc\odin.manifest -outputresource:%exe_name%;#1 -validate_manifest -identity:"odin, processorArchitecture=amd64, version=%odin_version_full%, type=win32"
if %errorlevel% neq 0 goto end_of_build if %errorlevel% neq 0 goto end_of_build
call build_vendor.bat call build_vendor.bat
if %errorlevel% neq 0 goto end_of_build if %errorlevel% neq 0 goto end_of_build
rem If the demo doesn't run for you and your CPU is more than a decade old, try -microarch:native rem If the demo doesn't run for you and your CPU is more than a decade old, try -microarch:native
if %release_mode% EQU 0 odin run examples/demo -vet -strict-style -- Hellope World if %release_mode% EQU 0 odin run examples/demo -vet -strict-style -resource:examples/demo/demo.rc -- Hellope World
rem Many non-compiler devs seem to run debug build but don't realize. rem Many non-compiler devs seem to run debug build but don't realize.
if %release_mode% EQU 0 echo: & echo Debug compiler built. Note: run "build.bat release" if you want a faster, release mode compiler. if %release_mode% EQU 0 echo: & echo Debug compiler built. Note: run "build.bat release" if you want a faster, release mode compiler.
+1 -1
View File
@@ -130,7 +130,7 @@ build_odin() {
EXTRAFLAGS="-O3" EXTRAFLAGS="-O3"
;; ;;
release-native) release-native)
if [ "$OS_ARCH" = "arm64" ]; then if [ "$OS_ARCH" = "arm64" ] || [ "$OS_ARCH" = "aarch64" ]; then
# Use preferred flag for Arm (ie arm64 / aarch64 / etc) # Use preferred flag for Arm (ie arm64 / aarch64 / etc)
EXTRAFLAGS="-O3 -mcpu=native" EXTRAFLAGS="-O3 -mcpu=native"
else else
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env sh
# Intended for use in Alpine containers, see the "nightly" Github action for a list of dependencies
CXX="clang++-18"
LLVM_CONFIG="llvm-config-18"
DISABLED_WARNINGS="-Wno-switch -Wno-macro-redefined -Wno-unused-value"
CPPFLAGS="-DODIN_VERSION_RAW=\"dev-$(date +"%Y-%m")\""
CXXFLAGS="-std=c++14 $($LLVM_CONFIG --cxxflags --ldflags)"
LDFLAGS="-static -lm -lzstd -lz -lffi -pthread -ldl -fuse-ld=mold"
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --link-static --ldflags --libs --system-libs --libfiles)"
LDFLAGS="$LDFLAGS -Wl,-rpath=\$ORIGIN"
EXTRAFLAGS="-DNIGHTLY -O3"
set -x
$CXX src/main.cpp src/libtommath.cpp $DISABLED_WARNINGS $CPPFLAGS $CXXFLAGS $EXTRAFLAGS $LDFLAGS -o odin
+24 -19
View File
@@ -2,7 +2,7 @@ import os
import sys import sys
from zipfile import ZipFile, ZIP_DEFLATED from zipfile import ZipFile, ZIP_DEFLATED
from b2sdk.v2 import InMemoryAccountInfo, B2Api from b2sdk.v2 import InMemoryAccountInfo, B2Api
from datetime import datetime from datetime import datetime, timezone
import json import json
UPLOAD_FOLDER = "nightly/" UPLOAD_FOLDER = "nightly/"
@@ -22,7 +22,7 @@ def auth() -> bool:
pass # Not yet authenticated pass # Not yet authenticated
err = b2_api.authorize_account("production", application_key_id, application_key) err = b2_api.authorize_account("production", application_key_id, application_key)
return err == None return err is None
def get_bucket(): def get_bucket():
if not auth(): sys.exit(1) if not auth(): sys.exit(1)
@@ -32,30 +32,35 @@ def remove_prefix(text: str, prefix: str) -> str:
return text[text.startswith(prefix) and len(prefix):] return text[text.startswith(prefix) and len(prefix):]
def create_and_upload_artifact_zip(platform: str, artifact: str) -> int: def create_and_upload_artifact_zip(platform: str, artifact: str) -> int:
now = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0) now = datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
destination_zip_name = "odin-{}-nightly+{}.zip".format(platform, now.strftime("%Y-%m-%d"))
source_zip_name = artifact source_archive: str
if not artifact.endswith(".zip"): destination_name = f'odin-{platform}-nightly+{now.strftime("%Y-%m-%d")}'
print(f"Creating archive {destination_zip_name} from {artifact} and uploading to {bucket_name}")
source_zip_name = destination_zip_name if platform.startswith("linux") or platform.startswith("macos"):
with ZipFile(source_zip_name, mode='w', compression=ZIP_DEFLATED, compresslevel=9) as z: destination_name += ".tar.gz"
source_archive = artifact
else:
destination_name += ".zip"
source_archive = destination_name
print(f"Creating archive {destination_name} from {artifact} and uploading to {bucket_name}")
with ZipFile(source_archive, mode='w', compression=ZIP_DEFLATED, compresslevel=9) as z:
for root, directory, filenames in os.walk(artifact): for root, directory, filenames in os.walk(artifact):
for file in filenames: for file in filenames:
file_path = os.path.join(root, file) file_path = os.path.join(root, file)
zip_path = os.path.join("dist", os.path.relpath(file_path, artifact)) zip_path = os.path.join("dist", os.path.relpath(file_path, artifact))
z.write(file_path, zip_path) z.write(file_path, zip_path)
if not os.path.exists(source_zip_name): if not os.path.exists(source_archive):
print(f"Error: Newly created ZIP archive {source_zip_name} not found.") print(f"Error: archive {source_archive} not found.")
return 1 return 1
print("Uploading {} to {}".format(source_zip_name, UPLOAD_FOLDER + destination_zip_name)) print("Uploading {} to {}".format(source_archive, UPLOAD_FOLDER + destination_name))
bucket = get_bucket() bucket = get_bucket()
res = bucket.upload_local_file( res = bucket.upload_local_file(
source_zip_name, # Local file to upload source_archive, # Local file to upload
"nightly/" + destination_zip_name, # B2 destination path "nightly/" + destination_name, # B2 destination path
) )
return 0 return 0
@@ -65,8 +70,8 @@ def prune_artifacts():
bucket = get_bucket() bucket = get_bucket()
for file, _ in bucket.ls(UPLOAD_FOLDER, latest_only=False): for file, _ in bucket.ls(UPLOAD_FOLDER, latest_only=False):
# Timestamp is in milliseconds # Timestamp is in milliseconds
date = datetime.fromtimestamp(file.upload_timestamp / 1_000.0).replace(hour=0, minute=0, second=0, microsecond=0) date = datetime.fromtimestamp(file.upload_timestamp / 1_000.0, tz=timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
now = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0) now = datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
delta = now - date delta = now - date
if delta.days > int(days_to_keep): if delta.days > int(days_to_keep):
@@ -100,7 +105,7 @@ def update_nightly_json():
'sizeInBytes': size, 'sizeInBytes': size,
}) })
now = datetime.utcnow().isoformat() now = datetime.now(timezone.utc).isoformat()
nightly = json.dumps({ nightly = json.dumps({
'last_updated' : now, 'last_updated' : now,
@@ -137,4 +142,4 @@ if __name__ == "__main__":
elif command == "json": elif command == "json":
res = update_nightly_json() res = update_nightly_json()
sys.exit(res) sys.exit(res)
+2 -2
View File
@@ -334,7 +334,7 @@ Inputs:
Returns: Returns:
- index: The index of the byte `c`, or -1 if it was not found. - index: The index of the byte `c`, or -1 if it was not found.
*/ */
index_byte :: proc(s: []byte, c: byte) -> (index: int) #no_bounds_check { index_byte :: proc "contextless" (s: []byte, c: byte) -> (index: int) #no_bounds_check {
i, l := 0, len(s) i, l := 0, len(s)
// Guard against small strings. On modern systems, it is ALWAYS // Guard against small strings. On modern systems, it is ALWAYS
@@ -469,7 +469,7 @@ Inputs:
Returns: Returns:
- index: The index of the byte `c`, or -1 if it was not found. - index: The index of the byte `c`, or -1 if it was not found.
*/ */
last_index_byte :: proc(s: []byte, c: byte) -> int #no_bounds_check { last_index_byte :: proc "contextless" (s: []byte, c: byte) -> int #no_bounds_check {
i := len(s) i := len(s)
// Guard against small strings. On modern systems, it is ALWAYS // Guard against small strings. On modern systems, it is ALWAYS
+1 -1
View File
@@ -291,7 +291,7 @@ scan_escape :: proc(t: ^Tokenizer) -> bool {
n -= 1 n -= 1
} }
if x > max || 0xd800 <= x && x <= 0xe000 { if x > max || 0xd800 <= x && x <= 0xdfff {
error_offset(t, offset, "escape sequence is an invalid Unicode code point") error_offset(t, offset, "escape sequence is an invalid Unicode code point")
return false return false
} }
+8
View File
@@ -98,6 +98,14 @@ when ODIN_OS == .Haiku {
ERANGE :: B_POSIX_ERROR_BASE + 17 ERANGE :: B_POSIX_ERROR_BASE + 17
} }
when ODIN_OS == .JS {
_ :: libc
_get_errno :: proc "c" () -> ^int {
@(static) errno: int
return &errno
}
}
// Odin has no way to make an identifier "errno" behave as a function call to // Odin has no way to make an identifier "errno" behave as a function call to
// read the value, or to produce an lvalue such that you can assign a different // read the value, or to produce an lvalue such that you can assign a different
// error value to errno. To work around this, just expose it as a function like // error value to errno. To work around this, just expose it as a function like
+1 -1
View File
@@ -235,7 +235,7 @@ atomic_compare_exchange_weak :: #force_inline proc(object, expected: ^$T, desire
return ok return ok
} }
atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$T, desited: T, success, failure: memory_order) -> bool { atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$T, desired: T, success, failure: memory_order) -> bool {
assert(failure != .release) assert(failure != .release)
assert(failure != .acq_rel) assert(failure != .acq_rel)
+24
View File
@@ -89,6 +89,30 @@ when ODIN_OS == .Linux {
} }
} }
when ODIN_OS == .JS {
fpos_t :: struct #raw_union { _: [16]char, _: longlong, _: double, }
_IOFBF :: 0
_IOLBF :: 1
_IONBF :: 2
BUFSIZ :: 1024
EOF :: int(-1)
FOPEN_MAX :: 1000
FILENAME_MAX :: 4096
L_tmpnam :: 20
SEEK_SET :: 0
SEEK_CUR :: 1
SEEK_END :: 2
TMP_MAX :: 308915776
}
when ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD { when ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD {
fpos_t :: distinct i64 fpos_t :: distinct i64
+10
View File
@@ -10,6 +10,9 @@ when ODIN_OS == .Windows {
foreign import libc "system:c" foreign import libc "system:c"
} }
@(require)
import "base:runtime"
when ODIN_OS == .Windows { when ODIN_OS == .Windows {
RAND_MAX :: 0x7fff RAND_MAX :: 0x7fff
@@ -145,6 +148,10 @@ aligned_alloc :: #force_inline proc "c" (alignment, size: size_t) -> rawptr {
_aligned_malloc :: proc(size, alignment: size_t) -> rawptr --- _aligned_malloc :: proc(size, alignment: size_t) -> rawptr ---
} }
return _aligned_malloc(size=size, alignment=alignment) return _aligned_malloc(size=size, alignment=alignment)
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
context = runtime.default_context()
data, _ := runtime.mem_alloc_bytes(auto_cast size, auto_cast alignment)
return raw_data(data)
} else { } else {
foreign libc { foreign libc {
aligned_alloc :: proc(alignment, size: size_t) -> rawptr --- aligned_alloc :: proc(alignment, size: size_t) -> rawptr ---
@@ -160,6 +167,9 @@ aligned_free :: #force_inline proc "c" (ptr: rawptr) {
_aligned_free :: proc(ptr: rawptr) --- _aligned_free :: proc(ptr: rawptr) ---
} }
_aligned_free(ptr) _aligned_free(ptr)
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
context = runtime.default_context()
runtime.mem_free(ptr)
} else { } else {
free(ptr) free(ptr)
} }
+1
View File
@@ -12,6 +12,7 @@ when ODIN_OS == .Windows {
foreign import libc "system:c" foreign import libc "system:c"
} }
@(default_calling_convention="c")
foreign libc { foreign libc {
// 7.24.2 Copying functions // 7.24.2 Copying functions
memcpy :: proc(s1, s2: rawptr, n: size_t) -> rawptr --- memcpy :: proc(s1, s2: rawptr, n: size_t) -> rawptr ---
+1 -1
View File
@@ -45,7 +45,7 @@ when ODIN_OS == .Windows {
} }
} }
when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Darwin || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD || ODIN_OS == .Haiku { when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Darwin || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD || ODIN_OS == .Haiku || ODIN_OS == .JS {
@(default_calling_convention="c") @(default_calling_convention="c")
foreign libc { foreign libc {
// 7.27.2 Time manipulation functions // 7.27.2 Time manipulation functions
+1 -1
View File
@@ -14,7 +14,7 @@ when ODIN_OS == .Windows {
wctrans_t :: distinct wchar_t wctrans_t :: distinct wchar_t
wctype_t :: distinct ushort wctype_t :: distinct ushort
} else when ODIN_OS == .Linux { } else when ODIN_OS == .Linux || ODIN_OS == .JS {
wctrans_t :: distinct intptr_t wctrans_t :: distinct intptr_t
wctype_t :: distinct ulong wctype_t :: distinct ulong
+1 -1
View File
@@ -1,4 +1,4 @@
//+vet !using-param #+vet !using-param
package compress_zlib package compress_zlib
/* /*
+35 -6
View File
@@ -259,6 +259,7 @@ Inputs:
unsafe_unset :: proc(b: ^Bit_Array, bit: int) #no_bounds_check { unsafe_unset :: proc(b: ^Bit_Array, bit: int) #no_bounds_check {
b.bits[bit >> INDEX_SHIFT] &~= 1 << uint(bit & INDEX_MASK) b.bits[bit >> INDEX_SHIFT] &~= 1 << uint(bit & INDEX_MASK)
} }
/* /*
A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative). A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative).
@@ -276,22 +277,50 @@ Returns:
- ba: Allocates a bit_Array, backing data is set to `max-min / 64` indices, rounded up (eg 65 - 0 allocates for [2]u64). - ba: Allocates a bit_Array, backing data is set to `max-min / 64` indices, rounded up (eg 65 - 0 allocates for [2]u64).
*/ */
create :: proc(max_index: int, min_index: int = 0, allocator := context.allocator) -> (res: ^Bit_Array, ok: bool) #optional_ok { create :: proc(max_index: int, min_index: int = 0, allocator := context.allocator) -> (res: ^Bit_Array, ok: bool) #optional_ok {
context.allocator = allocator
size_in_bits := max_index - min_index size_in_bits := max_index - min_index
if size_in_bits < 0 { return {}, false } if size_in_bits < 0 { return {}, false }
res = new(Bit_Array, allocator)
ok = init(res, max_index, min_index, allocator)
res.free_pointer = true
if !ok { free(res, allocator) }
return
}
/*
A helper function to initialize a Bit Array with optional bias, in case your smallest index is non-zero (including negative).
The range of bits created by this procedure is `min_index..<max_index`, and the
array will be able to expand beyond `max_index` if needed.
*Allocates (`make(ba.bits)`)*
Inputs:
- max_index: maximum starting index
- min_index: minimum starting index (used as a bias)
- allocator: (default is context.allocator)
*/
init :: proc(res: ^Bit_Array, max_index: int, min_index: int = 0, allocator := context.allocator) -> (ok: bool) {
size_in_bits := max_index - min_index
if size_in_bits < 0 { return false }
legs := size_in_bits >> INDEX_SHIFT legs := size_in_bits >> INDEX_SHIFT
if size_in_bits & INDEX_MASK > 0 {legs+=1} if size_in_bits & INDEX_MASK > 0 { legs += 1 }
bits, err := make([dynamic]u64, legs)
ok = err == mem.Allocator_Error.None bits, err := make([dynamic]u64, legs, allocator)
res = new(Bit_Array) ok = err == nil
res.bits = bits res.bits = bits
res.bias = min_index res.bias = min_index
res.length = max_index - min_index res.length = max_index - min_index
res.free_pointer = true res.free_pointer = false
return return
} }
/* /*
Sets all values in the Bit_Array to zero. Sets all values in the Bit_Array to zero.
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64 #+build amd64
package aes_hw_intel package aes_hw_intel
import "core:sys/info" import "core:sys/info"
+1 -1
View File
@@ -20,7 +20,7 @@
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//+build amd64 #+build amd64
package aes_hw_intel package aes_hw_intel
import "base:intrinsics" import "base:intrinsics"
@@ -20,7 +20,7 @@
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//+build amd64 #+build amd64
package aes_hw_intel package aes_hw_intel
import "base:intrinsics" import "base:intrinsics"
@@ -51,7 +51,7 @@ _ROT_16: simd.u32x4 : {16, 16, 16, 16}
when ODIN_ENDIAN == .Big { when ODIN_ENDIAN == .Big {
@(private = "file") @(private = "file")
_increment_counter :: #force_inline proc "contextless" (ctx: ^Context) -> simd.u32x4 { _increment_counter :: #force_inline proc "contextless" (ctx: ^_chacha20.Context) -> simd.u32x4 {
// In the Big Endian case, the low and high portions in the vector // In the Big Endian case, the low and high portions in the vector
// are flipped, so the 64-bit addition can't be done with a simple // are flipped, so the 64-bit addition can't be done with a simple
// vector add. // vector add.
@@ -1,4 +1,4 @@
//+build amd64 #+build amd64
package chacha20_simd256 package chacha20_simd256
import "base:intrinsics" import "base:intrinsics"
@@ -1,4 +1,4 @@
//+build !amd64 #+build !amd64
package chacha20_simd256 package chacha20_simd256
import "base:intrinsics" import "base:intrinsics"
+8 -6
View File
@@ -81,16 +81,18 @@ bytepad :: proc(ctx: ^Context, x_strings: [][]byte, w: int) {
// 2. while len(z) mod 8 0: // 2. while len(z) mod 8 0:
// z = z || 0 // z = z || 0
// 3. while (len(z)/8) mod w 0: // 3. while (len(z)/8) mod w != 0:
// z = z || 00000000 // z = z || 00000000
z_len := u128(z_hi) << 64 | u128(z_lo) z_len := u128(z_hi) << 64 | u128(z_lo)
z_rem := int(z_len % u128(w)) z_rem := int(z_len % u128(w))
pad := _PAD[:w - z_rem] if z_rem != 0 {
pad := _PAD[:w - z_rem]
// We just add the padding to the state, instead of returning z. // We just add the padding to the state, instead of returning z.
// //
// 4. return z. // 4. return z.
update(ctx, pad) update(ctx, pad)
}
} }
encode_string :: #force_inline proc(ctx: ^Context, s: []byte) -> (u64, u64) { encode_string :: #force_inline proc(ctx: ^Context, s: []byte) -> (u64, u64) {
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64 #+build amd64
package aes package aes
import "base:intrinsics" import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64 #+build amd64
package aes package aes
import "base:intrinsics" import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64 #+build amd64
package aes package aes
import "base:intrinsics" import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !amd64 #+build !amd64
package aes package aes
@(private = "file") @(private = "file")
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64 #+build amd64
package aes package aes
import "core:crypto/_aes/hw_intel" import "core:crypto/_aes/hw_intel"
+4 -38
View File
@@ -1,16 +1,15 @@
package crypto_hash package crypto_hash
/* /*
Copyright 2021 zhibog Copyright 2021 zhibog
Made available under the BSD-3 license. Made available under the BSD-3 license.
List of contributors: List of contributors:
zhibog, dotbmp: Initial implementation. zhibog, dotbmp: Initial implementation.
*/ */
import "core:io" import "core:io"
import "core:mem" import "core:mem"
import "core:os"
// hash_bytes will hash the given input and return the computed digest // hash_bytes will hash the given input and return the computed digest
// in a newly allocated slice. // in a newly allocated slice.
@@ -87,36 +86,3 @@ hash_stream :: proc(
return dst, io.Error.None return dst, io.Error.None
} }
// hash_file will read the file provided by the given handle and return the
// computed digest in a newly allocated slice.
hash_file :: proc(
algorithm: Algorithm,
hd: os.Handle,
load_at_once := false,
allocator := context.allocator,
) -> (
[]byte,
io.Error,
) {
if !load_at_once {
return hash_stream(algorithm, os.stream_from_handle(hd), allocator)
}
buf, ok := os.read_entire_file(hd, allocator)
if !ok {
return nil, io.Error.Unknown
}
defer delete(buf, allocator)
return hash_bytes(algorithm, buf, allocator), io.Error.None
}
hash :: proc {
hash_stream,
hash_file,
hash_bytes,
hash_string,
hash_bytes_to_buffer,
hash_string_to_buffer,
}
+10
View File
@@ -0,0 +1,10 @@
#+build freestanding
package crypto_hash
hash :: proc {
hash_stream,
hash_bytes,
hash_string,
hash_bytes_to_buffer,
hash_string_to_buffer,
}
+38
View File
@@ -0,0 +1,38 @@
#+build !freestanding
package crypto_hash
import "core:io"
import "core:os"
// hash_file will read the file provided by the given handle and return the
// computed digest in a newly allocated slice.
hash_file :: proc(
algorithm: Algorithm,
hd: os.Handle,
load_at_once := false,
allocator := context.allocator,
) -> (
[]byte,
io.Error,
) {
if !load_at_once {
return hash_stream(algorithm, os.stream_from_handle(hd), allocator)
}
buf, ok := os.read_entire_file(hd, allocator)
if !ok {
return nil, io.Error.Unknown
}
defer delete(buf, allocator)
return hash_bytes(algorithm, buf, allocator), io.Error.None
}
hash :: proc {
hash_stream,
hash_file,
hash_bytes,
hash_string,
hash_bytes_to_buffer,
hash_string_to_buffer,
}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build freebsd, openbsd, netbsd #+build freebsd, openbsd, netbsd
package crypto package crypto
foreign import libc "system:c" foreign import libc "system:c"
+7 -7
View File
@@ -1,10 +1,10 @@
//+build !linux #+build !linux
//+build !windows #+build !windows
//+build !openbsd #+build !openbsd
//+build !freebsd #+build !freebsd
//+build !netbsd #+build !netbsd
//+build !darwin #+build !darwin
//+build !js #+build !js
package crypto package crypto
HAS_RAND_BYTES :: false HAS_RAND_BYTES :: false
+2 -2
View File
@@ -1,5 +1,5 @@
//+private file #+private file
//+build linux, darwin #+build linux, darwin
package debug_trace package debug_trace
import "base:intrinsics" import "base:intrinsics"
+3 -3
View File
@@ -1,6 +1,6 @@
//+build !windows #+build !windows
//+build !linux #+build !linux
//+build !darwin #+build !darwin
package debug_trace package debug_trace
import "base:runtime" import "base:runtime"
+2 -2
View File
@@ -1,5 +1,5 @@
//+private #+private
//+build windows #+build windows
package debug_trace package debug_trace
import "base:intrinsics" import "base:intrinsics"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build js #+build js
//+private #+private
package dynlib package dynlib
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) { _load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
+2 -2
View File
@@ -1,5 +1,5 @@
//+build linux, darwin, freebsd, openbsd, netbsd #+build linux, darwin, freebsd, openbsd, netbsd
//+private #+private
package dynlib package dynlib
import "core:os" import "core:os"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build windows #+build windows
//+private #+private
package dynlib package dynlib
import win32 "core:sys/windows" import win32 "core:sys/windows"
+11 -27
View File
@@ -675,10 +675,6 @@ _unmarshal_map :: proc(d: Decoder, v: any, ti: ^reflect.Type_Info, hdr: Header,
return return
case reflect.Type_Info_Map: case reflect.Type_Info_Map:
if !reflect.is_string(t.key) {
return _unsupported(v, hdr)
}
raw_map := (^mem.Raw_Map)(v.data) raw_map := (^mem.Raw_Map)(v.data)
if raw_map.allocator.procedure == nil { if raw_map.allocator.procedure == nil {
raw_map.allocator = context.allocator raw_map.allocator = context.allocator
@@ -695,43 +691,31 @@ _unmarshal_map :: proc(d: Decoder, v: any, ti: ^reflect.Type_Info, hdr: Header,
new_len := uintptr(min(scap, runtime.map_len(raw_map^)+length)) new_len := uintptr(min(scap, runtime.map_len(raw_map^)+length))
runtime.map_reserve_dynamic(raw_map, t.map_info, new_len) or_return runtime.map_reserve_dynamic(raw_map, t.map_info, new_len) or_return
} }
// Temporary memory to unmarshal keys into before inserting them into the map. // Temporary memory to unmarshal values into before inserting them into the map.
elem_backing := mem.alloc_bytes_non_zeroed(t.value.size, t.value.align, context.temp_allocator) or_return elem_backing := mem.alloc_bytes_non_zeroed(t.value.size, t.value.align, context.temp_allocator) or_return
defer delete(elem_backing, context.temp_allocator) defer delete(elem_backing, context.temp_allocator)
map_backing_value := any{raw_data(elem_backing), t.value.id} map_backing_value := any{raw_data(elem_backing), t.value.id}
for idx := 0; unknown || idx < length; idx += 1 { // Temporary memory to unmarshal keys into.
// Decode key, keys can only be strings. key_backing := mem.alloc_bytes_non_zeroed(t.key.size, t.key.align, context.temp_allocator) or_return
key: string defer delete(key_backing, context.temp_allocator)
if keyv, kerr := decode_key(d, v); unknown && kerr == .Break { key_backing_value := any{raw_data(key_backing), t.key.id}
break
} else if kerr != nil {
err = kerr
return
} else {
key = keyv
}
for idx := 0; unknown || idx < length; idx += 1 {
if unknown || idx > scap { if unknown || idx > scap {
// Reserve space for new element so we can return allocator errors. // Reserve space for new element so we can return allocator errors.
new_len := uintptr(runtime.map_len(raw_map^)+1) new_len := uintptr(runtime.map_len(raw_map^)+1)
runtime.map_reserve_dynamic(raw_map, t.map_info, new_len) or_return runtime.map_reserve_dynamic(raw_map, t.map_info, new_len) or_return
} }
mem.zero_slice(key_backing)
_unmarshal_value(d, key_backing_value, _decode_header(r) or_return) or_return
mem.zero_slice(elem_backing) mem.zero_slice(elem_backing)
_unmarshal_value(d, map_backing_value, _decode_header(r) or_return) or_return _unmarshal_value(d, map_backing_value, _decode_header(r) or_return) or_return
key_ptr := rawptr(&key) set_ptr := runtime.__dynamic_map_set_without_hash(raw_map, t.map_info, key_backing_value.data, map_backing_value.data)
key_cstr: cstring
if reflect.is_cstring(t.key) {
assert_safe_for_cstring(key)
key_cstr = cstring(raw_data(key))
key_ptr = &key_cstr
}
set_ptr := runtime.__dynamic_map_set_without_hash(raw_map, t.map_info, key_ptr, map_backing_value.data)
// We already reserved space for it, so this shouldn't fail. // We already reserved space for it, so this shouldn't fail.
assert(set_ptr != nil) assert(set_ptr != nil)
} }
+1
View File
@@ -154,6 +154,7 @@ write_section :: proc(w: io.Writer, name: string, n_written: ^int = nil) -> (n:
io.write_byte (w, '[', &n) or_return io.write_byte (w, '[', &n) or_return
io.write_string(w, name, &n) or_return io.write_string(w, name, &n) or_return
io.write_byte (w, ']', &n) or_return io.write_byte (w, ']', &n) or_return
io.write_byte (w, '\n', &n) or_return
return return
} }
+10 -5
View File
@@ -312,13 +312,18 @@ unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
case .String: case .String:
advance_token(p) advance_token(p)
str := unquote_string(token, p.spec, p.allocator) or_return str := unquote_string(token, p.spec, p.allocator) or_return
if unmarshal_string_token(p, any{v.data, ti.id}, str, ti) { dest := any{v.data, ti.id}
return nil if !unmarshal_string_token(p, dest, str, ti) {
delete(str, p.allocator)
return UNSUPPORTED_TYPE
} }
delete(str, p.allocator)
return UNSUPPORTED_TYPE
switch destv in dest {
case string, cstring:
case: delete(str, p.allocator)
}
return nil
case .Open_Brace: case .Open_Brace:
return unmarshal_object(p, v, .Close_Brace) return unmarshal_object(p, v, .Close_Brace)
+1 -1
View File
@@ -1,4 +1,4 @@
//+build netbsd, openbsd #+build netbsd, openbsd
package flags package flags
import "base:runtime" import "base:runtime"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build !netbsd #+build !netbsd
//+build !openbsd #+build !openbsd
package flags package flags
import "base:runtime" import "base:runtime"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private #+private
package flags package flags
import "base:intrinsics" import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private #+private
package flags package flags
import "core:container/bit_array" import "core:container/bit_array"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private #+private
package flags package flags
import "base:intrinsics" import "base:intrinsics"
+3 -3
View File
@@ -1,6 +1,6 @@
//+private #+private
//+build !netbsd #+build !netbsd
//+build !openbsd #+build !openbsd
package flags package flags
import "core:net" import "core:net"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private #+private
package flags package flags
@require import "base:runtime" @require import "base:runtime"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build ignore #+build ignore
package custom_formatter_example package custom_formatter_example
import "core:fmt" import "core:fmt"
import "core:io" import "core:io"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js #+build js
package fmt package fmt
import "core:bufio" import "core:bufio"
+3 -3
View File
@@ -1,6 +1,6 @@
//+build !freestanding #+build !freestanding
//+build !js #+build !js
//+build !orca #+build !orca
package fmt package fmt
import "base:runtime" import "base:runtime"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js #+build js
package core_image_bmp package core_image_bmp
load :: proc{load_from_bytes, load_from_context} load :: proc{load_from_bytes, load_from_context}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js #+build !js
package core_image_bmp package core_image_bmp
import "core:os" import "core:os"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js #+build js
package image package image
load :: proc{ load :: proc{
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js #+build !js
package image package image
import "core:os" import "core:os"
+1 -1
View File
@@ -1,4 +1,4 @@
//+vet !using-stmt #+vet !using-stmt
package netpbm package netpbm
import "core:bytes" import "core:bytes"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js #+build js
package netpbm package netpbm
load :: proc { load :: proc {
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js #+build !js
package netpbm package netpbm
import "core:os" import "core:os"
+1 -1
View File
@@ -8,7 +8,7 @@
*/ */
//+vet !using-stmt #+vet !using-stmt
package png package png
import "core:compress" import "core:compress"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js #+build js
package png package png
load :: proc{load_from_bytes, load_from_context} load :: proc{load_from_bytes, load_from_context}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js #+build !js
package png package png
import "core:os" import "core:os"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js #+build js
package qoi package qoi
save :: proc{save_to_buffer} save :: proc{save_to_buffer}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js #+build !js
package qoi package qoi
import "core:os" import "core:os"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js #+build js
package tga package tga
save :: proc{save_to_buffer} save :: proc{save_to_buffer}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js #+build !js
package tga package tga
import "core:os" import "core:os"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build !freestanding #+build !freestanding
//+build !orca #+build !orca
package log package log
import "core:encoding/ansi" import "core:encoding/ansi"
+1 -1
View File
@@ -7,7 +7,7 @@
The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks.
*/ */
//+build ignore #+build ignore
package math_big package math_big
import "core:time" import "core:time"
+35 -35
View File
@@ -22,9 +22,9 @@ F32_EPSILON :: 1e-7
F64_EPSILON :: 1e-15 F64_EPSILON :: 1e-15
// Odin matrices are stored internally as Column-Major, which matches OpenGL/GLSL by default // Odin matrices are stored internally as Column-Major, which matches OpenGL/GLSL by default
mat2 :: distinct matrix[2, 2]f32 mat2 :: matrix[2, 2]f32
mat3 :: distinct matrix[3, 3]f32 mat3 :: matrix[3, 3]f32
mat4 :: distinct matrix[4, 4]f32 mat4 :: matrix[4, 4]f32
mat2x2 :: mat2 mat2x2 :: mat2
mat3x3 :: mat3 mat3x3 :: mat3
mat4x4 :: mat4 mat4x4 :: mat4
@@ -33,52 +33,52 @@ mat4x4 :: mat4
// but they match how GLSL and OpenGL defines them in name // but they match how GLSL and OpenGL defines them in name
// Odin: matrix[R, C]f32 // Odin: matrix[R, C]f32
// GLSL: matCxR // GLSL: matCxR
mat3x2 :: distinct matrix[2, 3]f32 mat3x2 :: matrix[2, 3]f32
mat4x2 :: distinct matrix[2, 4]f32 mat4x2 :: matrix[2, 4]f32
mat2x3 :: distinct matrix[3, 2]f32 mat2x3 :: matrix[3, 2]f32
mat4x3 :: distinct matrix[3, 4]f32 mat4x3 :: matrix[3, 4]f32
mat2x4 :: distinct matrix[4, 2]f32 mat2x4 :: matrix[4, 2]f32
mat3x4 :: distinct matrix[4, 3]f32 mat3x4 :: matrix[4, 3]f32
vec2 :: distinct [2]f32 vec2 :: [2]f32
vec3 :: distinct [3]f32 vec3 :: [3]f32
vec4 :: distinct [4]f32 vec4 :: [4]f32
ivec2 :: distinct [2]i32 ivec2 :: [2]i32
ivec3 :: distinct [3]i32 ivec3 :: [3]i32
ivec4 :: distinct [4]i32 ivec4 :: [4]i32
uvec2 :: distinct [2]u32 uvec2 :: [2]u32
uvec3 :: distinct [3]u32 uvec3 :: [3]u32
uvec4 :: distinct [4]u32 uvec4 :: [4]u32
bvec2 :: distinct [2]bool bvec2 :: [2]bool
bvec3 :: distinct [3]bool bvec3 :: [3]bool
bvec4 :: distinct [4]bool bvec4 :: [4]bool
quat :: distinct quaternion128 quat :: quaternion128
// Double Precision (f64) Floating Point Types // Double Precision (f64) Floating Point Types
dmat2 :: distinct matrix[2, 2]f64 dmat2 :: matrix[2, 2]f64
dmat3 :: distinct matrix[3, 3]f64 dmat3 :: matrix[3, 3]f64
dmat4 :: distinct matrix[4, 4]f64 dmat4 :: matrix[4, 4]f64
dmat2x2 :: dmat2 dmat2x2 :: dmat2
dmat3x3 :: dmat3 dmat3x3 :: dmat3
dmat4x4 :: dmat4 dmat4x4 :: dmat4
dmat3x2 :: distinct matrix[2, 3]f64 dmat3x2 :: matrix[2, 3]f64
dmat4x2 :: distinct matrix[2, 4]f64 dmat4x2 :: matrix[2, 4]f64
dmat2x3 :: distinct matrix[3, 2]f64 dmat2x3 :: matrix[3, 2]f64
dmat4x3 :: distinct matrix[3, 4]f64 dmat4x3 :: matrix[3, 4]f64
dmat2x4 :: distinct matrix[4, 2]f64 dmat2x4 :: matrix[4, 2]f64
dmat3x4 :: distinct matrix[4, 3]f64 dmat3x4 :: matrix[4, 3]f64
dvec2 :: distinct [2]f64 dvec2 :: [2]f64
dvec3 :: distinct [3]f64 dvec3 :: [3]f64
dvec4 :: distinct [4]f64 dvec4 :: [4]f64
dquat :: distinct quaternion256 dquat :: quaternion256
cos :: proc{ cos :: proc{
cos_f32, cos_f32,
+64 -64
View File
@@ -21,89 +21,89 @@ LN10 :: 2.30258509299404568401799145468436421
FLOAT_EPSILON :: 1e-7 FLOAT_EPSILON :: 1e-7
DOUBLE_EPSILON :: 1e-15 DOUBLE_EPSILON :: 1e-15
// Aliases (not distinct) of types // Aliases (not distict) of types
float :: f32 float :: f32
double :: f64 double :: f64
int :: builtin.i32 int :: builtin.i32
uint :: builtin.u32 uint :: builtin.u32
// Odin matrices are stored internally as Column-Major, which matches the internal layout of HLSL by default // Odin matrices are stored internally as Column-Major, which matches the internal layout of HLSL by default
float1x1 :: distinct matrix[1, 1]float float1x1 :: matrix[1, 1]float
float2x2 :: distinct matrix[2, 2]float float2x2 :: matrix[2, 2]float
float3x3 :: distinct matrix[3, 3]float float3x3 :: matrix[3, 3]float
float4x4 :: distinct matrix[4, 4]float float4x4 :: matrix[4, 4]float
float1x2 :: distinct matrix[1, 2]float float1x2 :: matrix[1, 2]float
float1x3 :: distinct matrix[1, 3]float float1x3 :: matrix[1, 3]float
float1x4 :: distinct matrix[1, 4]float float1x4 :: matrix[1, 4]float
float2x1 :: distinct matrix[2, 1]float float2x1 :: matrix[2, 1]float
float2x3 :: distinct matrix[2, 3]float float2x3 :: matrix[2, 3]float
float2x4 :: distinct matrix[2, 4]float float2x4 :: matrix[2, 4]float
float3x1 :: distinct matrix[3, 1]float float3x1 :: matrix[3, 1]float
float3x2 :: distinct matrix[3, 2]float float3x2 :: matrix[3, 2]float
float3x4 :: distinct matrix[3, 4]float float3x4 :: matrix[3, 4]float
float4x1 :: distinct matrix[4, 1]float float4x1 :: matrix[4, 1]float
float4x2 :: distinct matrix[4, 2]float float4x2 :: matrix[4, 2]float
float4x3 :: distinct matrix[4, 3]float float4x3 :: matrix[4, 3]float
float2 :: distinct [2]float float2 :: [2]float
float3 :: distinct [3]float float3 :: [3]float
float4 :: distinct [4]float float4 :: [4]float
int2 :: distinct [2]int int2 :: [2]int
int3 :: distinct [3]int int3 :: [3]int
int4 :: distinct [4]int int4 :: [4]int
uint2 :: distinct [2]uint uint2 :: [2]uint
uint3 :: distinct [3]uint uint3 :: [3]uint
uint4 :: distinct [4]uint uint4 :: [4]uint
bool2 :: distinct [2]bool bool2 :: [2]bool
bool3 :: distinct [3]bool bool3 :: [3]bool
bool4 :: distinct [4]bool bool4 :: [4]bool
// Double Precision (double) Floating Point Types // Double Precision (double) Floating Point Types
double1x1 :: distinct matrix[1, 1]double double1x1 :: matrix[1, 1]double
double2x2 :: distinct matrix[2, 2]double double2x2 :: matrix[2, 2]double
double3x3 :: distinct matrix[3, 3]double double3x3 :: matrix[3, 3]double
double4x4 :: distinct matrix[4, 4]double double4x4 :: matrix[4, 4]double
double1x2 :: distinct matrix[1, 2]double double1x2 :: matrix[1, 2]double
double1x3 :: distinct matrix[1, 3]double double1x3 :: matrix[1, 3]double
double1x4 :: distinct matrix[1, 4]double double1x4 :: matrix[1, 4]double
double2x1 :: distinct matrix[2, 1]double double2x1 :: matrix[2, 1]double
double2x3 :: distinct matrix[2, 3]double double2x3 :: matrix[2, 3]double
double2x4 :: distinct matrix[2, 4]double double2x4 :: matrix[2, 4]double
double3x1 :: distinct matrix[3, 1]double double3x1 :: matrix[3, 1]double
double3x2 :: distinct matrix[3, 2]double double3x2 :: matrix[3, 2]double
double3x4 :: distinct matrix[3, 4]double double3x4 :: matrix[3, 4]double
double4x1 :: distinct matrix[4, 1]double double4x1 :: matrix[4, 1]double
double4x2 :: distinct matrix[4, 2]double double4x2 :: matrix[4, 2]double
double4x3 :: distinct matrix[4, 3]double double4x3 :: matrix[4, 3]double
double2 :: distinct [2]double double2 :: [2]double
double3 :: distinct [3]double double3 :: [3]double
double4 :: distinct [4]double double4 :: [4]double
int1x1 :: distinct matrix[1, 1]int int1x1 :: matrix[1, 1]int
int2x2 :: distinct matrix[2, 2]int int2x2 :: matrix[2, 2]int
int3x3 :: distinct matrix[3, 3]int int3x3 :: matrix[3, 3]int
int4x4 :: distinct matrix[4, 4]int int4x4 :: matrix[4, 4]int
int1x2 :: distinct matrix[1, 2]int int1x2 :: matrix[1, 2]int
int1x3 :: distinct matrix[1, 3]int int1x3 :: matrix[1, 3]int
int1x4 :: distinct matrix[1, 4]int int1x4 :: matrix[1, 4]int
int2x1 :: distinct matrix[2, 1]int int2x1 :: matrix[2, 1]int
int2x3 :: distinct matrix[2, 3]int int2x3 :: matrix[2, 3]int
int2x4 :: distinct matrix[2, 4]int int2x4 :: matrix[2, 4]int
int3x1 :: distinct matrix[3, 1]int int3x1 :: matrix[3, 1]int
int3x2 :: distinct matrix[3, 2]int int3x2 :: matrix[3, 2]int
int3x4 :: distinct matrix[3, 4]int int3x4 :: matrix[3, 4]int
int4x1 :: distinct matrix[4, 1]int int4x1 :: matrix[4, 1]int
int4x2 :: distinct matrix[4, 2]int int4x2 :: matrix[4, 2]int
int4x3 :: distinct matrix[4, 3]int int4x3 :: matrix[4, 3]int
cos :: proc{ cos :: proc{
cos_float, cos_float,
+3 -3
View File
@@ -444,11 +444,11 @@ bias :: proc "contextless" (t, b: $T) -> T where intrinsics.type_is_numeric(T) {
return t / (((1/b) - 2) * (1 - t) + 1) return t / (((1/b) - 2) * (1 - t) + 1)
} }
@(require_results) @(require_results)
gain :: proc "contextless" (t, g: $T) -> T where intrinsics.type_is_numeric(T) { gain :: proc "contextless" (t, g: $T) -> T where intrinsics.type_is_float(T) {
if t < 0.5 { if t < 0.5 {
return bias(t*2, g)*0.5 return bias(t*2, g) * 0.5
} }
return bias(t*2 - 1, 1 - g)*0.5 + 0.5 return bias(t*2 - 1, 1 - g) * 0.5 + 0.5
} }
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js #+build !js
package math package math
import "base:intrinsics" import "base:intrinsics"

Some files were not shown because too many files have changed in this diff Show More