Merge remote-tracking branch 'offical/master'

This commit is contained in:
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/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)
./odin check tests/benchmark -vet -strict-style -no-entry-point
build_freebsd:
name: FreeBSD Build, Check, and Test
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/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)
./odin check tests/benchmark -vet -strict-style -no-entry-point
ci:
strategy:
fail-fast: false
@@ -128,6 +131,8 @@ jobs:
cd tests/issues
./run.sh
- name: Check benchmarks
run: ./odin check tests/benchmark -vet -strict-style -no-entry-point
- name: Odin check examples/all for Linux i386
run: ./odin check examples/all -vet -strict-style -disallow-do -target:linux_i386
if: matrix.os == 'ubuntu-latest'
@@ -203,6 +208,11 @@ jobs:
run: |
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
- 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
shell: cmd
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
- 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
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
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
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
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 examples dist
- name: Upload artifact
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v4
with:
include-hidden-files: true
name: windows_artifacts
path: dist
build_ubuntu:
name: Ubuntu Build
build_linux:
name: Linux Build
if: github.repository == 'odin-lang/Odin'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jirutka/setup-alpine@v1
with:
branch: v3.20
- name: (Linux) Download LLVM
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 18
echo "/usr/lib/llvm-18/bin" >> $GITHUB_PATH
apk add --no-cache \
musl-dev llvm18-dev clang18 git mold lz4 \
libxml2-static llvm18-static zlib-static zstd-static \
make
shell: alpine.sh --root {0}
- 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
run: ./odin run examples/demo
- name: Copy artifacts
run: |
mkdir dist
cp odin dist
cp LICENSE dist
cp -r shared dist
cp -r base dist
cp -r core dist
cp -r vendor dist
cp -r examples dist
# Zipping so executable permissions are retained, see https://github.com/actions/upload-artifact/issues/38
zip -r dist.zip dist
FILE="odin-linux-amd64-nightly+$(date -I)"
mkdir $FILE
cp odin $FILE
cp LICENSE $FILE
cp -r shared $FILE
cp -r base $FILE
cp -r core $FILE
cp -r vendor $FILE
cp -r examples $FILE
# 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
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v4
with:
name: ubuntu_artifacts
path: dist.zip
name: linux_artifacts
path: dist.tar.gz
build_macos:
name: MacOS Build
if: github.repository == 'odin-lang/Odin'
@@ -89,24 +101,27 @@ jobs:
run: CXXFLAGS="-L/usr/lib/system -L/usr/lib" make nightly
- name: Bundle
run: |
mkdir dist
cp odin dist
cp LICENSE dist
cp -r shared dist
cp -r base dist
cp -r core dist
cp -r vendor dist
cp -r examples dist
dylibbundler -b -x dist/odin -d dist/libs -od -p @executable_path/libs
# Zipping so executable permissions are retained, see https://github.com/actions/upload-artifact/issues/38
zip -r dist.zip dist
FILE="odin-macos-amd64-nightly+$(date -I)"
mkdir $FILE
cp odin $FILE
cp LICENSE $FILE
cp -r shared $FILE
cp -r base $FILE
cp -r core $FILE
cp -r vendor $FILE
cp -r examples $FILE
dylibbundler -b -x $FILE/odin -d $FILE/libs -od -p @executable_path/libs
# 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: ./dist/odin run examples/demo
run: |
FILE="odin-macos-amd64-nightly+$(date -I)"
$FILE/odin run examples/demo
- name: Upload artifact
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v4
with:
name: macos_artifacts
path: dist.zip
path: dist.tar.gz
build_macos_arm:
name: MacOS ARM Build
if: github.repository == 'odin-lang/Odin'
@@ -123,30 +138,33 @@ jobs:
run: CXXFLAGS="-L/usr/lib/system -L/usr/lib" make nightly
- name: Bundle
run: |
mkdir dist
cp odin dist
cp LICENSE dist
cp -r shared dist
cp -r base dist
cp -r core dist
cp -r vendor dist
cp -r examples dist
dylibbundler -b -x dist/odin -d dist/libs -od -p @executable_path/libs
# Zipping so executable permissions are retained, see https://github.com/actions/upload-artifact/issues/38
zip -r dist.zip dist
FILE="odin-macos-arm64-nightly+$(date -I)"
mkdir $FILE
cp odin $FILE
cp LICENSE $FILE
cp -r shared $FILE
cp -r base $FILE
cp -r core $FILE
cp -r vendor $FILE
cp -r examples $FILE
dylibbundler -b -x $FILE/odin -d $FILE/libs -od -p @executable_path/libs
# 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: ./dist/odin run examples/demo
run: |
FILE="odin-macos-arm64-nightly+$(date -I)"
$FILE/odin run examples/demo
- name: Upload artifact
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v4
with:
name: macos_arm_artifacts
path: dist.zip
path: dist.tar.gz
upload_b2:
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:
- uses: actions/checkout@v4
- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
with:
python-version: '3.8.x'
@@ -160,24 +178,33 @@ jobs:
run: python -c "import sys; print(sys.version)"
- name: Download Windows artifacts
uses: actions/download-artifact@v1
uses: actions/download-artifact@v4.1.7
with:
name: windows_artifacts
path: windows_artifacts
- name: Download Ubuntu artifacts
uses: actions/download-artifact@v1
uses: actions/download-artifact@v4.1.7
with:
name: ubuntu_artifacts
name: linux_artifacts
path: linux_artifacts
- name: Download macOS artifacts
uses: actions/download-artifact@v1
uses: actions/download-artifact@v4.1.7
with:
name: macos_artifacts
path: macos_artifacts
- name: Download macOS arm artifacts
uses: actions/download-artifact@v1
uses: actions/download-artifact@v4.1.7
with:
name: macos_arm_artifacts
path: macos_arm_artifacts
- name: Debug
run: |
tree -L 2
- name: Create archives and upload
shell: bash
@@ -187,9 +214,10 @@ jobs:
BUCKET: ${{ secrets.B2_BUCKET }}
DAYS_TO_KEEP: ${{ secrets.B2_DAYS_TO_KEEP }}
run: |
file linux_artifacts/dist.tar.gz
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 macos-amd64 macos_artifacts/dist.zip
python3 ci/nightly.py artifact macos-arm64 macos_arm_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.tar.gz
python3 ci/nightly.py artifact macos-arm64 macos_arm_artifacts/dist.tar.gz
python3 ci/nightly.py prune
python3 ci/nightly.py json
+3
View File
@@ -266,6 +266,9 @@ bin/
*.exe
*.obj
*.pdb
*.res
desktop.ini
Thumbs.db
# - Linux/MacOS
odin
+1 -1
View File
@@ -1,5 +1,5 @@
// This is purely for documentation
//+build ignore
#+build ignore
package intrinsics
// Package-Related
+1 -1
View File
@@ -18,7 +18,7 @@
// This could change at a later date if the all these data structures are
// implemented within the compiler rather than in this "preload" file
//
//+no-instrumentation
#+no-instrumentation
package runtime
import "base:intrinsics"
+49 -4
View File
@@ -6,6 +6,39 @@ import "base:intrinsics"
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)
container_of :: #force_inline proc "contextless" (ptr: $P/^$Field_Type, $T: typeid, $field_name: string) -> ^T
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
}
// `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.
//
// Note: Prefer using the procedure group `make`.
@(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)
context.allocator = allocator
@@ -392,6 +436,7 @@ make :: proc{
make_dynamic_array_len,
make_dynamic_array_len_cap,
make_map,
make_map_cap,
make_multi_pointer,
make_soa_slice,
@@ -913,7 +958,7 @@ card :: proc "contextless" (s: $S/bit_set[$E; $U]) -> int {
@builtin
@(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 {
// NOTE(bill): This is wrapped in a procedure call
// to improve performance to make the CPU not
@@ -952,7 +997,7 @@ unimplemented :: proc(message := "", loc := #caller_location) -> ! {
@builtin
@(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 {
// NOTE(bill): This is wrapped in a procedure call
// to improve performance to make the CPU not
+3 -3
View File
@@ -1,6 +1,6 @@
//+private
//+build linux, darwin, freebsd, openbsd, netbsd, haiku
//+no-instrumentation
#+private
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
#+no-instrumentation
package runtime
import "base:intrinsics"
+3 -3
View File
@@ -1,6 +1,6 @@
//+private
//+build wasm32, wasm64p32
//+no-instrumentation
#+private
#+build wasm32, wasm64p32
#+no-instrumentation
package runtime
import "base:intrinsics"
+3 -3
View File
@@ -1,6 +1,6 @@
//+private
//+build windows
//+no-instrumentation
#+private
#+build windows
#+no-instrumentation
package runtime
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) {
// 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))
space := size + a - 1
space := a-1 + size_of(rawptr) + size
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]
allocated_mem = heap_resize(original_old_ptr, space+size_of(rawptr))
allocated_mem = heap_resize(original_old_ptr, space)
} 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):])
ptr := uintptr(aligned_mem)
aligned_ptr := (ptr - 1 + uintptr(a)) & -uintptr(a)
diff := int(aligned_ptr - ptr)
if (size + diff) > space || allocated_mem == nil {
aligned_ptr := (ptr + uintptr(a)-1) & ~(uintptr(a)-1)
if allocated_mem == nil {
aligned_free(old_ptr)
aligned_free(allocated_mem)
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
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)
}
+2 -2
View File
@@ -1,5 +1,5 @@
//+build orca
//+private
#+build orca
#+private
package runtime
foreign {
+2 -2
View File
@@ -1,5 +1,5 @@
//+build js, wasi, freestanding, essence
//+private
#+build js, wasi, freestanding, essence
#+private
package runtime
_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
//+private
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
#+private
package runtime
when ODIN_OS == .Darwin {
+8 -5
View File
@@ -1,4 +1,4 @@
//+vet !cast
#+vet !cast
package runtime
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)
mem_alloc_bytes :: #force_inline proc(size: int, alignment: int = DEFAULT_ALIGNMENT, allocator := context.allocator, loc := #caller_location) -> ([]byte, Allocator_Error) {
if size == 0 {
return nil, nil
}
if allocator.procedure == nil {
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
if size == 0 || allocator.procedure == nil{
return nil, nil
}
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) {
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
if size == 0 || allocator.procedure == 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) {
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
if size == 0 || allocator.procedure == 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) {
assert(is_power_of_two_int(alignment), "Alignment must be a power of two", loc)
if allocator.procedure == 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) {
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)
}
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)
}
+2 -2
View File
@@ -1,5 +1,5 @@
//+build freebsd, openbsd, netbsd
//+private
#+build freebsd, openbsd, netbsd
#+private
package runtime
foreign import libc "system:c"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build darwin
//+private
#+build darwin
#+private
package runtime
import "base:intrinsics"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build freestanding
//+private
#+build freestanding
#+private
package runtime
// TODO(bill): reimplement `os.write`
+2 -2
View File
@@ -1,5 +1,5 @@
//+build haiku
//+private
#+build haiku
#+private
package runtime
foreign import libc "system:c"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build js
//+private
#+build js
#+private
package runtime
foreign import "odin_env"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private
#+private
package runtime
import "base:intrinsics"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build orca
//+private
#+build orca
#+private
package runtime
import "base:intrinsics"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build wasi
//+private
#+build wasi
#+private
package runtime
foreign import wasi "wasi_snapshot_preview1"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build windows
//+private
#+build windows
#+private
package runtime
foreign import kernel32 "system:Kernel32.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private
#+private
package runtime
foreign import "system:Foundation.framework"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js
#+build js
package runtime
init_default_context_for_js: Context
+42 -20
View File
@@ -1,4 +1,4 @@
//+build wasm32, wasm64p32
#+build wasm32, wasm64p32
package runtime
@(private="file")
@@ -14,33 +14,57 @@ ti_uint :: struct #raw_union {
}
@(link_name="__ashlti3", linkage="strong")
__ashlti3 :: proc "contextless" (la, ha: u64, b_: u32) -> i128 {
bits_in_dword :: size_of(u32)*8
b := u32(b_)
__ashlti3 :: proc "contextless" (a: i128, b: u32) -> i128 {
bits :: 64
input, result: ti_int
input.lo, input.hi = la, ha
if b & bits_in_dword != 0 {
input: ti_int = ---
result: ti_int = ---
input.all = a
if b & bits != 0 {
result.lo = 0
result.hi = input.lo << (b-bits_in_dword)
result.hi = input.lo << (b-bits)
} else {
if b == 0 {
return input.all
return a
}
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
}
__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")
__multi3 :: proc "contextless" (la, ha, lb, hb: u64) -> i128 {
__multi3 :: proc "contextless" (a, b: i128) -> i128 {
x, y, r: ti_int
x.lo, x.hi = la, ha
y.lo, y.hi = lb, hb
r.all = i128(x.lo * y.lo) // TODO this is incorrect
x.all = a
y.all = b
r.all = __mulddi3(x.lo, y.lo)
r.hi += x.hi*y.lo + x.lo*y.hi
return r.all
}
@@ -54,18 +78,16 @@ udivti3 :: proc "c" (la, ha, lb, hb: u64) -> u128 {
}
@(link_name="__lshrti3", linkage="strong")
__lshrti3 :: proc "c" (la, ha: u64, b: u32) -> i128 {
bits :: size_of(u32)*8
__lshrti3 :: proc "c" (a: i128, b: u32) -> i128 {
bits :: 64
input, result: ti_int
input.lo = la
input.hi = ha
input.all = a
if b & bits != 0 {
result.hi = 0
result.lo = input.hi >> (b - bits)
} else if b == 0 {
return input.all
return a
} else {
result.hi = input.hi >> b
result.lo = (input.hi << (bits - b)) | (input.lo >> b)
+2 -2
View File
@@ -1,5 +1,5 @@
//+private
//+no-instrumentation
#+private
#+no-instrumentation
package runtime
foreign import kernel32 "system:Kernel32.lib"
+2 -2
View File
@@ -1,5 +1,5 @@
//+private
//+no-instrumentation
#+private
#+no-instrumentation
package runtime
@require foreign import "system:int64.lib"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build wasm32, wasm64p32
#+build wasm32, wasm64p32
package runtime
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 (
set CURR_DATE_TIME=%%j
for /f %%i in ('powershell get-date -format "{yyyyMMdd}"') do (
set CURR_DATE_TIME=%%i
)
set curr_year=%CURR_DATE_TIME:~0,4%
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
set exe_name=odin.exe
@@ -45,7 +45,19 @@ if "%2" == "1" (
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
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_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
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 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
if %nightly% equ 1 set compiler_defines=%compiler_defines% -DNIGHTLY
if %release_mode% EQU 0 ( rem Debug
set compiler_flags=%compiler_flags% -Od -MDd -Z7
set rc_flags=%rc_flags% -D_DEBUG
) else ( rem Release
set compiler_flags=%compiler_flags% -O2 -MT -Z7
set compiler_defines=%compiler_defines% -DNO_ARRAY_BOUNDS_CHECK
@@ -82,6 +106,8 @@ set libs= ^
kernel32.lib ^
Synchronization.lib ^
bin\llvm\windows\LLVM-C.lib
set odin_res=misc\odin.res
set odin_rc=misc\odin.rc
rem DO NOT TOUCH!
rem THIS TILDE STUFF IS FOR DEVELOPMENT ONLY!
@@ -93,7 +119,7 @@ if %tilde_backend% EQU 1 (
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
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 linker_settings=%libs% %linker_flags%
set linker_settings=%libs% %odin_res% %linker_flags%
del *.pdb > 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%
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
call build_vendor.bat
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
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.
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"
;;
release-native)
if [ "$OS_ARCH" = "arm64" ]; then
if [ "$OS_ARCH" = "arm64" ] || [ "$OS_ARCH" = "aarch64" ]; then
# Use preferred flag for Arm (ie arm64 / aarch64 / etc)
EXTRAFLAGS="-O3 -mcpu=native"
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
from zipfile import ZipFile, ZIP_DEFLATED
from b2sdk.v2 import InMemoryAccountInfo, B2Api
from datetime import datetime
from datetime import datetime, timezone
import json
UPLOAD_FOLDER = "nightly/"
@@ -22,7 +22,7 @@ def auth() -> bool:
pass # Not yet authenticated
err = b2_api.authorize_account("production", application_key_id, application_key)
return err == None
return err is None
def get_bucket():
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):]
def create_and_upload_artifact_zip(platform: str, artifact: str) -> int:
now = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0)
destination_zip_name = "odin-{}-nightly+{}.zip".format(platform, now.strftime("%Y-%m-%d"))
now = datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
source_zip_name = artifact
if not artifact.endswith(".zip"):
print(f"Creating archive {destination_zip_name} from {artifact} and uploading to {bucket_name}")
source_archive: str
destination_name = f'odin-{platform}-nightly+{now.strftime("%Y-%m-%d")}'
source_zip_name = destination_zip_name
with ZipFile(source_zip_name, mode='w', compression=ZIP_DEFLATED, compresslevel=9) as z:
if platform.startswith("linux") or platform.startswith("macos"):
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 file in filenames:
file_path = os.path.join(root, file)
zip_path = os.path.join("dist", os.path.relpath(file_path, artifact))
z.write(file_path, zip_path)
if not os.path.exists(source_zip_name):
print(f"Error: Newly created ZIP archive {source_zip_name} not found.")
return 1
if not os.path.exists(source_archive):
print(f"Error: archive {source_archive} not found.")
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()
res = bucket.upload_local_file(
source_zip_name, # Local file to upload
"nightly/" + destination_zip_name, # B2 destination path
source_archive, # Local file to upload
"nightly/" + destination_name, # B2 destination path
)
return 0
@@ -65,8 +70,8 @@ def prune_artifacts():
bucket = get_bucket()
for file, _ in bucket.ls(UPLOAD_FOLDER, latest_only=False):
# Timestamp is in milliseconds
date = datetime.fromtimestamp(file.upload_timestamp / 1_000.0).replace(hour=0, minute=0, second=0, microsecond=0)
now = datetime.utcnow().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.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
delta = now - date
if delta.days > int(days_to_keep):
@@ -100,7 +105,7 @@ def update_nightly_json():
'sizeInBytes': size,
})
now = datetime.utcnow().isoformat()
now = datetime.now(timezone.utc).isoformat()
nightly = json.dumps({
'last_updated' : now,
@@ -137,4 +142,4 @@ if __name__ == "__main__":
elif command == "json":
res = update_nightly_json()
sys.exit(res)
sys.exit(res)
+2 -2
View File
@@ -334,7 +334,7 @@ Inputs:
Returns:
- 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)
// Guard against small strings. On modern systems, it is ALWAYS
@@ -469,7 +469,7 @@ Inputs:
Returns:
- 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)
// 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
}
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")
return false
}
+8
View File
@@ -98,6 +98,14 @@ when ODIN_OS == .Haiku {
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
// 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
+1 -1
View File
@@ -235,7 +235,7 @@ atomic_compare_exchange_weak :: #force_inline proc(object, expected: ^$T, desire
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 != .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 {
fpos_t :: distinct i64
+10
View File
@@ -10,6 +10,9 @@ when ODIN_OS == .Windows {
foreign import libc "system:c"
}
@(require)
import "base:runtime"
when ODIN_OS == .Windows {
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 ---
}
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 {
foreign libc {
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(ptr)
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
context = runtime.default_context()
runtime.mem_free(ptr)
} else {
free(ptr)
}
+1
View File
@@ -12,6 +12,7 @@ when ODIN_OS == .Windows {
foreign import libc "system:c"
}
@(default_calling_convention="c")
foreign libc {
// 7.24.2 Copying functions
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")
foreign libc {
// 7.27.2 Time manipulation functions
+1 -1
View File
@@ -14,7 +14,7 @@ when ODIN_OS == .Windows {
wctrans_t :: distinct wchar_t
wctype_t :: distinct ushort
} else when ODIN_OS == .Linux {
} else when ODIN_OS == .Linux || ODIN_OS == .JS {
wctrans_t :: distinct intptr_t
wctype_t :: distinct ulong
+1 -1
View File
@@ -1,4 +1,4 @@
//+vet !using-param
#+vet !using-param
package compress_zlib
/*
+35 -6
View File
@@ -259,6 +259,7 @@ Inputs:
unsafe_unset :: proc(b: ^Bit_Array, bit: int) #no_bounds_check {
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).
@@ -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).
*/
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
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
if size_in_bits & INDEX_MASK > 0 {legs+=1}
bits, err := make([dynamic]u64, legs)
ok = err == mem.Allocator_Error.None
res = new(Bit_Array)
if size_in_bits & INDEX_MASK > 0 { legs += 1 }
bits, err := make([dynamic]u64, legs, allocator)
ok = err == nil
res.bits = bits
res.bias = min_index
res.length = max_index - min_index
res.free_pointer = true
res.free_pointer = false
return
}
/*
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
import "core:sys/info"
+1 -1
View File
@@ -20,7 +20,7 @@
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//+build amd64
#+build amd64
package aes_hw_intel
import "base:intrinsics"
@@ -20,7 +20,7 @@
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//+build amd64
#+build amd64
package aes_hw_intel
import "base:intrinsics"
@@ -51,7 +51,7 @@ _ROT_16: simd.u32x4 : {16, 16, 16, 16}
when ODIN_ENDIAN == .Big {
@(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
// are flipped, so the 64-bit addition can't be done with a simple
// vector add.
@@ -1,4 +1,4 @@
//+build amd64
#+build amd64
package chacha20_simd256
import "base:intrinsics"
@@ -1,4 +1,4 @@
//+build !amd64
#+build !amd64
package chacha20_simd256
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:
// z = z || 0
// 3. while (len(z)/8) mod w 0:
// 3. while (len(z)/8) mod w != 0:
// z = z || 00000000
z_len := u128(z_hi) << 64 | u128(z_lo)
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.
//
// 4. return z.
update(ctx, pad)
// We just add the padding to the state, instead of returning z.
//
// 4. return z.
update(ctx, pad)
}
}
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
import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64
#+build amd64
package aes
import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64
#+build amd64
package aes
import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !amd64
#+build !amd64
package aes
@(private = "file")
+1 -1
View File
@@ -1,4 +1,4 @@
//+build amd64
#+build amd64
package aes
import "core:crypto/_aes/hw_intel"
+4 -38
View File
@@ -1,16 +1,15 @@
package crypto_hash
/*
Copyright 2021 zhibog
Made available under the BSD-3 license.
Copyright 2021 zhibog
Made available under the BSD-3 license.
List of contributors:
zhibog, dotbmp: Initial implementation.
List of contributors:
zhibog, dotbmp: Initial implementation.
*/
import "core:io"
import "core:mem"
import "core:os"
// hash_bytes will hash the given input and return the computed digest
// in a newly allocated slice.
@@ -87,36 +86,3 @@ hash_stream :: proc(
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
foreign import libc "system:c"
+7 -7
View File
@@ -1,10 +1,10 @@
//+build !linux
//+build !windows
//+build !openbsd
//+build !freebsd
//+build !netbsd
//+build !darwin
//+build !js
#+build !linux
#+build !windows
#+build !openbsd
#+build !freebsd
#+build !netbsd
#+build !darwin
#+build !js
package crypto
HAS_RAND_BYTES :: false
+2 -2
View File
@@ -1,5 +1,5 @@
//+private file
//+build linux, darwin
#+private file
#+build linux, darwin
package debug_trace
import "base:intrinsics"
+3 -3
View File
@@ -1,6 +1,6 @@
//+build !windows
//+build !linux
//+build !darwin
#+build !windows
#+build !linux
#+build !darwin
package debug_trace
import "base:runtime"
+2 -2
View File
@@ -1,5 +1,5 @@
//+private
//+build windows
#+private
#+build windows
package debug_trace
import "base:intrinsics"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build js
//+private
#+build js
#+private
package dynlib
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
+2 -2
View File
@@ -1,5 +1,5 @@
//+build linux, darwin, freebsd, openbsd, netbsd
//+private
#+build linux, darwin, freebsd, openbsd, netbsd
#+private
package dynlib
import "core:os"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build windows
//+private
#+build windows
#+private
package dynlib
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
case reflect.Type_Info_Map:
if !reflect.is_string(t.key) {
return _unsupported(v, hdr)
}
raw_map := (^mem.Raw_Map)(v.data)
if raw_map.allocator.procedure == nil {
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))
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
defer delete(elem_backing, context.temp_allocator)
map_backing_value := any{raw_data(elem_backing), t.value.id}
for idx := 0; unknown || idx < length; idx += 1 {
// Decode key, keys can only be strings.
key: string
if keyv, kerr := decode_key(d, v); unknown && kerr == .Break {
break
} else if kerr != nil {
err = kerr
return
} else {
key = keyv
}
// Temporary memory to unmarshal keys into.
key_backing := mem.alloc_bytes_non_zeroed(t.key.size, t.key.align, context.temp_allocator) or_return
defer delete(key_backing, context.temp_allocator)
key_backing_value := any{raw_data(key_backing), t.key.id}
for idx := 0; unknown || idx < length; idx += 1 {
if unknown || idx > scap {
// Reserve space for new element so we can return allocator errors.
new_len := uintptr(runtime.map_len(raw_map^)+1)
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)
_unmarshal_value(d, map_backing_value, _decode_header(r) or_return) or_return
key_ptr := rawptr(&key)
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)
set_ptr := runtime.__dynamic_map_set_without_hash(raw_map, t.map_info, key_backing_value.data, map_backing_value.data)
// We already reserved space for it, so this shouldn't fail.
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_string(w, name, &n) or_return
io.write_byte (w, ']', &n) or_return
io.write_byte (w, '\n', &n) or_return
return
}
+10 -5
View File
@@ -312,13 +312,18 @@ unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
case .String:
advance_token(p)
str := unquote_string(token, p.spec, p.allocator) or_return
if unmarshal_string_token(p, any{v.data, ti.id}, str, ti) {
return nil
str := unquote_string(token, p.spec, p.allocator) or_return
dest := any{v.data, ti.id}
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:
return unmarshal_object(p, v, .Close_Brace)
+1 -1
View File
@@ -1,4 +1,4 @@
//+build netbsd, openbsd
#+build netbsd, openbsd
package flags
import "base:runtime"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build !netbsd
//+build !openbsd
#+build !netbsd
#+build !openbsd
package flags
import "base:runtime"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private
#+private
package flags
import "base:intrinsics"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private
#+private
package flags
import "core:container/bit_array"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private
#+private
package flags
import "base:intrinsics"
+3 -3
View File
@@ -1,6 +1,6 @@
//+private
//+build !netbsd
//+build !openbsd
#+private
#+build !netbsd
#+build !openbsd
package flags
import "core:net"
+1 -1
View File
@@ -1,4 +1,4 @@
//+private
#+private
package flags
@require import "base:runtime"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build ignore
#+build ignore
package custom_formatter_example
import "core:fmt"
import "core:io"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js
#+build js
package fmt
import "core:bufio"
+3 -3
View File
@@ -1,6 +1,6 @@
//+build !freestanding
//+build !js
//+build !orca
#+build !freestanding
#+build !js
#+build !orca
package fmt
import "base:runtime"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js
#+build js
package core_image_bmp
load :: proc{load_from_bytes, load_from_context}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js
#+build !js
package core_image_bmp
import "core:os"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js
#+build js
package image
load :: proc{
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js
#+build !js
package image
import "core:os"
+1 -1
View File
@@ -1,4 +1,4 @@
//+vet !using-stmt
#+vet !using-stmt
package netpbm
import "core:bytes"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js
#+build js
package netpbm
load :: proc {
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js
#+build !js
package netpbm
import "core:os"
+1 -1
View File
@@ -8,7 +8,7 @@
*/
//+vet !using-stmt
#+vet !using-stmt
package png
import "core:compress"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js
#+build js
package png
load :: proc{load_from_bytes, load_from_context}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js
#+build !js
package png
import "core:os"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js
#+build js
package qoi
save :: proc{save_to_buffer}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js
#+build !js
package qoi
import "core:os"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js
#+build js
package tga
save :: proc{save_to_buffer}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build !js
#+build !js
package tga
import "core:os"
+2 -2
View File
@@ -1,5 +1,5 @@
//+build !freestanding
//+build !orca
#+build !freestanding
#+build !orca
package log
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.
*/
//+build ignore
#+build ignore
package math_big
import "core:time"
+35 -35
View File
@@ -22,9 +22,9 @@ F32_EPSILON :: 1e-7
F64_EPSILON :: 1e-15
// Odin matrices are stored internally as Column-Major, which matches OpenGL/GLSL by default
mat2 :: distinct matrix[2, 2]f32
mat3 :: distinct matrix[3, 3]f32
mat4 :: distinct matrix[4, 4]f32
mat2 :: matrix[2, 2]f32
mat3 :: matrix[3, 3]f32
mat4 :: matrix[4, 4]f32
mat2x2 :: mat2
mat3x3 :: mat3
mat4x4 :: mat4
@@ -33,52 +33,52 @@ mat4x4 :: mat4
// but they match how GLSL and OpenGL defines them in name
// Odin: matrix[R, C]f32
// GLSL: matCxR
mat3x2 :: distinct matrix[2, 3]f32
mat4x2 :: distinct matrix[2, 4]f32
mat2x3 :: distinct matrix[3, 2]f32
mat4x3 :: distinct matrix[3, 4]f32
mat2x4 :: distinct matrix[4, 2]f32
mat3x4 :: distinct matrix[4, 3]f32
mat3x2 :: matrix[2, 3]f32
mat4x2 :: matrix[2, 4]f32
mat2x3 :: matrix[3, 2]f32
mat4x3 :: matrix[3, 4]f32
mat2x4 :: matrix[4, 2]f32
mat3x4 :: matrix[4, 3]f32
vec2 :: distinct [2]f32
vec3 :: distinct [3]f32
vec4 :: distinct [4]f32
vec2 :: [2]f32
vec3 :: [3]f32
vec4 :: [4]f32
ivec2 :: distinct [2]i32
ivec3 :: distinct [3]i32
ivec4 :: distinct [4]i32
ivec2 :: [2]i32
ivec3 :: [3]i32
ivec4 :: [4]i32
uvec2 :: distinct [2]u32
uvec3 :: distinct [3]u32
uvec4 :: distinct [4]u32
uvec2 :: [2]u32
uvec3 :: [3]u32
uvec4 :: [4]u32
bvec2 :: distinct [2]bool
bvec3 :: distinct [3]bool
bvec4 :: distinct [4]bool
bvec2 :: [2]bool
bvec3 :: [3]bool
bvec4 :: [4]bool
quat :: distinct quaternion128
quat :: quaternion128
// Double Precision (f64) Floating Point Types
dmat2 :: distinct matrix[2, 2]f64
dmat3 :: distinct matrix[3, 3]f64
dmat4 :: distinct matrix[4, 4]f64
dmat2 :: matrix[2, 2]f64
dmat3 :: matrix[3, 3]f64
dmat4 :: matrix[4, 4]f64
dmat2x2 :: dmat2
dmat3x3 :: dmat3
dmat4x4 :: dmat4
dmat3x2 :: distinct matrix[2, 3]f64
dmat4x2 :: distinct matrix[2, 4]f64
dmat2x3 :: distinct matrix[3, 2]f64
dmat4x3 :: distinct matrix[3, 4]f64
dmat2x4 :: distinct matrix[4, 2]f64
dmat3x4 :: distinct matrix[4, 3]f64
dmat3x2 :: matrix[2, 3]f64
dmat4x2 :: matrix[2, 4]f64
dmat2x3 :: matrix[3, 2]f64
dmat4x3 :: matrix[3, 4]f64
dmat2x4 :: matrix[4, 2]f64
dmat3x4 :: matrix[4, 3]f64
dvec2 :: distinct [2]f64
dvec3 :: distinct [3]f64
dvec4 :: distinct [4]f64
dvec2 :: [2]f64
dvec3 :: [3]f64
dvec4 :: [4]f64
dquat :: distinct quaternion256
dquat :: quaternion256
cos :: proc{
cos_f32,
+64 -64
View File
@@ -21,89 +21,89 @@ LN10 :: 2.30258509299404568401799145468436421
FLOAT_EPSILON :: 1e-7
DOUBLE_EPSILON :: 1e-15
// Aliases (not distinct) of types
// Aliases (not distict) of types
float :: f32
double :: f64
int :: builtin.i32
uint :: builtin.u32
// Odin matrices are stored internally as Column-Major, which matches the internal layout of HLSL by default
float1x1 :: distinct matrix[1, 1]float
float2x2 :: distinct matrix[2, 2]float
float3x3 :: distinct matrix[3, 3]float
float4x4 :: distinct matrix[4, 4]float
float1x1 :: matrix[1, 1]float
float2x2 :: matrix[2, 2]float
float3x3 :: matrix[3, 3]float
float4x4 :: matrix[4, 4]float
float1x2 :: distinct matrix[1, 2]float
float1x3 :: distinct matrix[1, 3]float
float1x4 :: distinct matrix[1, 4]float
float2x1 :: distinct matrix[2, 1]float
float2x3 :: distinct matrix[2, 3]float
float2x4 :: distinct matrix[2, 4]float
float3x1 :: distinct matrix[3, 1]float
float3x2 :: distinct matrix[3, 2]float
float3x4 :: distinct matrix[3, 4]float
float4x1 :: distinct matrix[4, 1]float
float4x2 :: distinct matrix[4, 2]float
float4x3 :: distinct matrix[4, 3]float
float1x2 :: matrix[1, 2]float
float1x3 :: matrix[1, 3]float
float1x4 :: matrix[1, 4]float
float2x1 :: matrix[2, 1]float
float2x3 :: matrix[2, 3]float
float2x4 :: matrix[2, 4]float
float3x1 :: matrix[3, 1]float
float3x2 :: matrix[3, 2]float
float3x4 :: matrix[3, 4]float
float4x1 :: matrix[4, 1]float
float4x2 :: matrix[4, 2]float
float4x3 :: matrix[4, 3]float
float2 :: distinct [2]float
float3 :: distinct [3]float
float4 :: distinct [4]float
float2 :: [2]float
float3 :: [3]float
float4 :: [4]float
int2 :: distinct [2]int
int3 :: distinct [3]int
int4 :: distinct [4]int
int2 :: [2]int
int3 :: [3]int
int4 :: [4]int
uint2 :: distinct [2]uint
uint3 :: distinct [3]uint
uint4 :: distinct [4]uint
uint2 :: [2]uint
uint3 :: [3]uint
uint4 :: [4]uint
bool2 :: distinct [2]bool
bool3 :: distinct [3]bool
bool4 :: distinct [4]bool
bool2 :: [2]bool
bool3 :: [3]bool
bool4 :: [4]bool
// Double Precision (double) Floating Point Types
double1x1 :: distinct matrix[1, 1]double
double2x2 :: distinct matrix[2, 2]double
double3x3 :: distinct matrix[3, 3]double
double4x4 :: distinct matrix[4, 4]double
double1x1 :: matrix[1, 1]double
double2x2 :: matrix[2, 2]double
double3x3 :: matrix[3, 3]double
double4x4 :: matrix[4, 4]double
double1x2 :: distinct matrix[1, 2]double
double1x3 :: distinct matrix[1, 3]double
double1x4 :: distinct matrix[1, 4]double
double2x1 :: distinct matrix[2, 1]double
double2x3 :: distinct matrix[2, 3]double
double2x4 :: distinct matrix[2, 4]double
double3x1 :: distinct matrix[3, 1]double
double3x2 :: distinct matrix[3, 2]double
double3x4 :: distinct matrix[3, 4]double
double4x1 :: distinct matrix[4, 1]double
double4x2 :: distinct matrix[4, 2]double
double4x3 :: distinct matrix[4, 3]double
double1x2 :: matrix[1, 2]double
double1x3 :: matrix[1, 3]double
double1x4 :: matrix[1, 4]double
double2x1 :: matrix[2, 1]double
double2x3 :: matrix[2, 3]double
double2x4 :: matrix[2, 4]double
double3x1 :: matrix[3, 1]double
double3x2 :: matrix[3, 2]double
double3x4 :: matrix[3, 4]double
double4x1 :: matrix[4, 1]double
double4x2 :: matrix[4, 2]double
double4x3 :: matrix[4, 3]double
double2 :: distinct [2]double
double3 :: distinct [3]double
double4 :: distinct [4]double
double2 :: [2]double
double3 :: [3]double
double4 :: [4]double
int1x1 :: distinct matrix[1, 1]int
int2x2 :: distinct matrix[2, 2]int
int3x3 :: distinct matrix[3, 3]int
int4x4 :: distinct matrix[4, 4]int
int1x1 :: matrix[1, 1]int
int2x2 :: matrix[2, 2]int
int3x3 :: matrix[3, 3]int
int4x4 :: matrix[4, 4]int
int1x2 :: distinct matrix[1, 2]int
int1x3 :: distinct matrix[1, 3]int
int1x4 :: distinct matrix[1, 4]int
int2x1 :: distinct matrix[2, 1]int
int2x3 :: distinct matrix[2, 3]int
int2x4 :: distinct matrix[2, 4]int
int3x1 :: distinct matrix[3, 1]int
int3x2 :: distinct matrix[3, 2]int
int3x4 :: distinct matrix[3, 4]int
int4x1 :: distinct matrix[4, 1]int
int4x2 :: distinct matrix[4, 2]int
int4x3 :: distinct matrix[4, 3]int
int1x2 :: matrix[1, 2]int
int1x3 :: matrix[1, 3]int
int1x4 :: matrix[1, 4]int
int2x1 :: matrix[2, 1]int
int2x3 :: matrix[2, 3]int
int2x4 :: matrix[2, 4]int
int3x1 :: matrix[3, 1]int
int3x2 :: matrix[3, 2]int
int3x4 :: matrix[3, 4]int
int4x1 :: matrix[4, 1]int
int4x2 :: matrix[4, 2]int
int4x3 :: matrix[4, 3]int
cos :: proc{
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)
}
@(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 {
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
import "base:intrinsics"

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