mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-09 04:51:37 -07:00
Compare commits
562 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e6475fec4d | |||
| a0b35f67f8 | |||
| 5e308cef5e | |||
| bbf76fa43e | |||
| 8ad5e46ff8 | |||
| c26e7e17a1 | |||
| 31ea10490f | |||
| aa36ae01cf | |||
| 7a98b58189 | |||
| cc29b41ccc | |||
| 35f1b0f11e | |||
| 468bd3dfde | |||
| c33d2ff96b | |||
| 9199c6df34 | |||
| 7cfaf0b181 | |||
| 8b5492dd4d | |||
| 92bc3a5b4d | |||
| 80393cb708 | |||
| 7fd32a74c5 | |||
| f798f0b446 | |||
| c3971fe5fa | |||
| 73193e99f7 | |||
| 04b000370b | |||
| 30cf3ed02f | |||
| 94acfaf21e | |||
| e825326d73 | |||
| d4d546a63a | |||
| cc3c9bd871 | |||
| 8a00d85cea | |||
| 2392300ffb | |||
| f469bbb004 | |||
| ee76acd665 | |||
| 8312528a87 | |||
| 36b958c120 | |||
| d8187d1cf2 | |||
| b46b34228e | |||
| 47be77ead5 | |||
| 28a3a68dc9 | |||
| 31d5bc48a7 | |||
| 5f99d6b427 | |||
| cb2768625a | |||
| 3e024347ee | |||
| 7e12e37df9 | |||
| b7140875cf | |||
| 0b4a4212bb | |||
| afed3ce6b5 | |||
| e064f8c6be | |||
| 1cebc025b0 | |||
| d4e87f7a62 | |||
| b6599a52b5 | |||
| b59647084b | |||
| bb308b3ff4 | |||
| c1496ab6c0 | |||
| 4f800a7fda | |||
| e67692b066 | |||
| 771d308d64 | |||
| 1f187adff4 | |||
| 35d818bb4e | |||
| f32e27d2e4 | |||
| 69d375705e | |||
| 44eef21997 | |||
| bd38b4839c | |||
| 4608d26e6e | |||
| 1e3a924e11 | |||
| 10c2f8dbeb | |||
| 8906ffb39c | |||
| 831558a7c2 | |||
| bb4fc9979a | |||
| 793ef6012b | |||
| 3b6ed2164b | |||
| 0b8e98febe | |||
| 4bde87de8f | |||
| bcf2b93c6e | |||
| da1e09c95d | |||
| cf89526a9f | |||
| 61795232f4 | |||
| 8371995bfc | |||
| f047f804f6 | |||
| 33cc671302 | |||
| c5ae7daecd | |||
| 8cba4aa1c3 | |||
| 70bff68f69 | |||
| a9f2271a90 | |||
| 50597e8691 | |||
| 00ec862b63 | |||
| 28b26043fb | |||
| d8696badb6 | |||
| 9e00d610c8 | |||
| d393d3292f | |||
| 6ef915c312 | |||
| 01c7380df8 | |||
| 66c53a1174 | |||
| 7c1922b0a7 | |||
| 90a0c834bb | |||
| c8ed499293 | |||
| 62922a421c | |||
| 9f609dd740 | |||
| b6cbdf7c54 | |||
| e79f94ca5e | |||
| b82f8df5f5 | |||
| 2141299d2b | |||
| 1cb93efe8a | |||
| 142e7d6b52 | |||
| 872a29752c | |||
| 7989d512a0 | |||
| 1dd9b8560d | |||
| b746e5287e | |||
| ff35a59548 | |||
| c93923c9f7 | |||
| 0e4ed515b9 | |||
| 417e9bb37f | |||
| 0157ff1541 | |||
| 591f827e5f | |||
| 55ff1769d0 | |||
| e240c034de | |||
| d52e0a892c | |||
| f112c27f7d | |||
| 8006ba919e | |||
| 16eac6c844 | |||
| 5bf8852b2e | |||
| 77cf4373a8 | |||
| 19c2b4d54f | |||
| 4fffd1b271 | |||
| 66c902406d | |||
| 3aae1740c7 | |||
| fcaa3abe47 | |||
| ba6203f8d3 | |||
| 4c8e355444 | |||
| a6502c3e8c | |||
| 4e07d3f1d3 | |||
| 15a8970493 | |||
| 6f23b5bb60 | |||
| b0ff41e673 | |||
| 41c717de3f | |||
| fee99c0800 | |||
| 58745bc7ae | |||
| 5c63617191 | |||
| d8af35f01e | |||
| 27753ff7a8 | |||
| 9004441e43 | |||
| 2695b269a4 | |||
| 67252ff415 | |||
| b839d06ac8 | |||
| 131e8d4187 | |||
| db8950922c | |||
| 6bf70b60d6 | |||
| 7b1086b489 | |||
| 4b8462aa70 | |||
| f858374ef2 | |||
| eaafe92402 | |||
| 15d70390e5 | |||
| 75c5cf3e80 | |||
| 609eb00335 | |||
| 2fc04f29c8 | |||
| 5c0c1287dc | |||
| ac4f4e883a | |||
| 80c390e851 | |||
| c50eaa0b77 | |||
| 46ca1c8b32 | |||
| bb29304029 | |||
| ed29c881a5 | |||
| 0b74a661e3 | |||
| a205bcd0da | |||
| 27daebf46c | |||
| 04ddcc5e64 | |||
| 7eabb1d744 | |||
| 3c2efb24b7 | |||
| 2181a42bbf | |||
| cf8f138c61 | |||
| 249242687c | |||
| 60eac68be7 | |||
| c21e62ddb4 | |||
| f61996fd6f | |||
| b5f7332ffb | |||
| dad418cf91 | |||
| d0eae4a9ad | |||
| 54ffd6df06 | |||
| a3c3e5c822 | |||
| cf705d4b29 | |||
| 861efa4e54 | |||
| 59086a24a1 | |||
| 424dc590a3 | |||
| 31ee829b44 | |||
| abbbfd2925 | |||
| 9fe8095a84 | |||
| d9cfe692a9 | |||
| 64508e477b | |||
| 563ed69c28 | |||
| c305c9dd04 | |||
| dd7c88989a | |||
| 386f144cca | |||
| 1d29dfd037 | |||
| ae69f4b749 | |||
| 0b5cd3400f | |||
| 77b033cf96 | |||
| 5d556fe277 | |||
| af8b592bf6 | |||
| 7676480526 | |||
| 77780f9ce8 | |||
| a78cd48aa3 | |||
| 76806080ef | |||
| 5d4fd09ff0 | |||
| 0d834a2c2e | |||
| 55e9a1b971 | |||
| fd05d94789 | |||
| 53bb6c85f7 | |||
| 21d0b073b1 | |||
| 3498d4341d | |||
| aeb568f79a | |||
| 3ff887c6b6 | |||
| 613f231fed | |||
| eba7be34e7 | |||
| af9ae4897a | |||
| 9f813a6263 | |||
| 5d57fe77be | |||
| ab54ad3a75 | |||
| 9919a0cacd | |||
| 91dece1656 | |||
| 5cd1784d41 | |||
| 1e1904e9ab | |||
| d6f6099419 | |||
| d712ea43eb | |||
| 962af780ae | |||
| cf7d705c1f | |||
| a7d7c92a53 | |||
| 4b6410e225 | |||
| b173fa1b9a | |||
| 225ffdec36 | |||
| 7f9cfd1579 | |||
| e3eea1b9fa | |||
| fe8325f0ad | |||
| 38fedf2631 | |||
| 253edb51f7 | |||
| 82aefd4203 | |||
| 3c80f15a7a | |||
| 085b725774 | |||
| 3039131a5f | |||
| daa3bb9a3b | |||
| 152479052e | |||
| 90cb62c5ac | |||
| 4a616d97df | |||
| 642ecc363b | |||
| bd45900257 | |||
| eccb548935 | |||
| a82f26f4c0 | |||
| eeaa9f048b | |||
| ca9cfc7167 | |||
| 0e446e1d68 | |||
| 90d024fb70 | |||
| d830069e5c | |||
| 7deb28c810 | |||
| 2b5c2cab1f | |||
| 39c8749d8f | |||
| 4f2915a9b5 | |||
| d3bff23bce | |||
| 007730bfbc | |||
| e54b1560ee | |||
| abd52529a6 | |||
| acfac3cf2d | |||
| 842f1ae304 | |||
| 8371ef6681 | |||
| 987faa3f18 | |||
| e397fb6a7f | |||
| 3337d6b264 | |||
| fdc56c4d9a | |||
| 791b05b14f | |||
| 45d26dc7f9 | |||
| dbad23385d | |||
| e9e7863033 | |||
| 5bced00f5d | |||
| 357c8f6f34 | |||
| baf5a06fba | |||
| 3d202da63f | |||
| 5a6f761535 | |||
| f7d74ff3a8 | |||
| 95721fe296 | |||
| ba3d545c96 | |||
| 66e83ef30d | |||
| 94288161e9 | |||
| 130318d003 | |||
| 1ae57d8d20 | |||
| 26d00925cc | |||
| 634fa7aa30 | |||
| 096258b5d5 | |||
| 6bdd572a30 | |||
| c39b934e7f | |||
| a1349d8776 | |||
| c1a67f37e6 | |||
| cc60725eda | |||
| 04c08c2e2d | |||
| c68d847fb3 | |||
| 5162c6c506 | |||
| 10702f1134 | |||
| 32e13f17ae | |||
| d08b3d3b82 | |||
| a89d22b291 | |||
| 84700e09c9 | |||
| 355f84d0cd | |||
| b33f6ba1b0 | |||
| c1264c2a79 | |||
| 9a8fb2fb27 | |||
| 2c5be4e054 | |||
| 02884207d5 | |||
| b116e8ff55 | |||
| a4dd489284 | |||
| 290561a39b | |||
| a7fe647c8c | |||
| 327ca2ab71 | |||
| 68960e7d0a | |||
| ee02d04a9b | |||
| 6bbeb0a243 | |||
| a52b1e0321 | |||
| d560dad0d8 | |||
| 5441620b6c | |||
| 244907149a | |||
| bec09d82df | |||
| acbf5c8d97 | |||
| e0bb07728d | |||
| 0ca5e70c7d | |||
| 9456c36684 | |||
| 80622bcb3a | |||
| 18fd1fefc3 | |||
| 568705069c | |||
| cbf0471c72 | |||
| 35f0dcbb92 | |||
| 6e979a96a1 | |||
| 7491b3c332 | |||
| 4ff836609c | |||
| 8814170edf | |||
| e17dfcf7a2 | |||
| 80cc2f5416 | |||
| 9973e0255c | |||
| 4dd3248507 | |||
| 833157ecc9 | |||
| 652557bfcd | |||
| 29fedc1808 | |||
| 093ade0504 | |||
| 6ef779cd5c | |||
| 9508a1f031 | |||
| c794f853e9 | |||
| 0975820c48 | |||
| 0d33df15b4 | |||
| 4a3b4da73c | |||
| 09588836e7 | |||
| 19c1ed154c | |||
| abf6ea7732 | |||
| 6e0f1cc866 | |||
| 4d6f7dcac0 | |||
| aa25714d43 | |||
| fff99c726e | |||
| a16d3b6c9a | |||
| 68619f299e | |||
| 017d6bdf73 | |||
| 16ef59700b | |||
| d38f5ffb49 | |||
| 97e06cb98e | |||
| 8616842ec6 | |||
| aa91479870 | |||
| d03d9e49a6 | |||
| d2d2026736 | |||
| 603efa860a | |||
| 3d7b924260 | |||
| 19f0127e55 | |||
| af94c4ab32 | |||
| b12d312408 | |||
| 4f3f256375 | |||
| c24e18bf10 | |||
| 8b84b9a4a2 | |||
| 86e291235d | |||
| 466e29bb38 | |||
| 016d1a84d4 | |||
| 3ed2ab6e2c | |||
| e90f5d2528 | |||
| 129d85fe7d | |||
| 18a63037d1 | |||
| 3166c7bef9 | |||
| 55a9ba1fc0 | |||
| 275f1cc0de | |||
| 387f56634d | |||
| c94829f4d3 | |||
| 201a7b90bb | |||
| 27ed10746d | |||
| 3b22c0854c | |||
| 1025b9e6c0 | |||
| 244a4acfa1 | |||
| 788e4b2b6a | |||
| 7f7cfebc91 | |||
| 16cd16b91e | |||
| 2938655a3d | |||
| b1db33b519 | |||
| a1435a6a90 | |||
| fec1ccd7a3 | |||
| 9b06ea5bfd | |||
| b379d25a12 | |||
| a15afccd36 | |||
| 83b5f82a92 | |||
| 1632f19826 | |||
| 496d732aaf | |||
| 26db1c8860 | |||
| 7ff424d148 | |||
| f4322886f3 | |||
| 005cadb52c | |||
| 90ba78cdfc | |||
| a66524b0b2 | |||
| f16ed256ea | |||
| b442ea8601 | |||
| 309ea50a7c | |||
| 5c4f241f22 | |||
| fce7bcec49 | |||
| 459de29a87 | |||
| b2c2235e58 | |||
| 3a60109180 | |||
| 074314b887 | |||
| 8a14a656fb | |||
| e9a6a34480 | |||
| 026aef69e3 | |||
| 73f5ab473c | |||
| 0a594147af | |||
| ff82396e7c | |||
| beb10cce63 | |||
| 4df668fa22 | |||
| 564c7821c5 | |||
| fdd4882568 | |||
| 92ff04629e | |||
| c3f363cfbc | |||
| dbb783fbf2 | |||
| 45da009377 | |||
| 4d14b4257e | |||
| cbd4d5e765 | |||
| 74b28f1ff9 | |||
| 9d6f71fd2e | |||
| f9de8fdaba | |||
| 580f0599cd | |||
| cc724ff5d2 | |||
| 957cd64699 | |||
| 3637dcbd04 | |||
| 954dd86f7a | |||
| 6298b23e07 | |||
| 053425e8d7 | |||
| 5ae27c6ebc | |||
| d783bca297 | |||
| ce3f6b60d2 | |||
| a25a9e6ebe | |||
| 0dddd2b97e | |||
| aa75909418 | |||
| 0f379d7378 | |||
| ae020ffb2e | |||
| 036d7edda9 | |||
| 75dd562a0a | |||
| 0a17525791 | |||
| 499a5d1f9c | |||
| e72d0ba804 | |||
| f3a2b625ae | |||
| 167ced8ad1 | |||
| 05df34f99c | |||
| 299accb717 | |||
| 3b30bc305c | |||
| 73e4954346 | |||
| f1f5dc614e | |||
| 6eb80831b5 | |||
| b78d546010 | |||
| c719a86312 | |||
| dc767da12b | |||
| 300b01d77d | |||
| 1ab0745ca8 | |||
| 8c636ac37b | |||
| 466a90010f | |||
| 5a4746c3a0 | |||
| 1842cd6297 | |||
| c4c2282595 | |||
| d2202416d2 | |||
| 0a08a65202 | |||
| f8cd13767e | |||
| 3a351ec407 | |||
| 7c9d2f61f5 | |||
| 6017a20e1c | |||
| 2d988bbc5f | |||
| 64814f4199 | |||
| c0112d1c70 | |||
| c0e17808d4 | |||
| 6d3cffa13c | |||
| b350a35b77 | |||
| 03f6b9bbf6 | |||
| f8641ddd1b | |||
| aea3e9a585 | |||
| 4843db0960 | |||
| de220a9aa5 | |||
| 9750b64096 | |||
| 834f082dba | |||
| e5106e48a8 | |||
| da6213196d | |||
| 2b9096517c | |||
| 90358f97d5 | |||
| c19da21d81 | |||
| 78506b97a3 | |||
| 490f8c1568 | |||
| a99e57c62c | |||
| ddf5ca7adf | |||
| 6778598bc6 | |||
| 0aa971207b | |||
| a4fd0c133e | |||
| ce018b4e6f | |||
| 1a7c1d107a | |||
| d2d5ac33f4 | |||
| 578de09775 | |||
| dcf339517e | |||
| b2c5998e78 | |||
| 7487d507be | |||
| c6b551d2c3 | |||
| 2f1228baa0 | |||
| 73eea33b56 | |||
| c3bd94a27e | |||
| 645207b8b0 | |||
| d86e56089a | |||
| 597ba796b7 | |||
| 288312a812 | |||
| 6bbc165121 | |||
| b8f8cb9582 | |||
| 001b2b9d8f | |||
| 33735ba5cc | |||
| 3da77bcd67 | |||
| 996175753c | |||
| 0e6109e171 | |||
| 5b9b21e756 | |||
| d93aca647b | |||
| 6ed4bfeba1 | |||
| 99a3e9a510 | |||
| c0154bffad | |||
| 9276476760 | |||
| c86bbc61bc | |||
| 02da1ac9af | |||
| b618b665c6 | |||
| 806c87d71d | |||
| 309953e0f2 | |||
| 9e4b45f0f0 | |||
| f6f2c67f37 | |||
| d93f55c5d4 | |||
| f072136c04 | |||
| 71b2527df0 | |||
| b24157738f | |||
| 35f961d80f | |||
| a248d49f34 | |||
| 60321d98d4 | |||
| 195259e88b | |||
| 35731e66cf | |||
| 54b46247bd | |||
| 186565b0c1 | |||
| 575aedc3bf | |||
| 3557955f53 | |||
| 4577d541ec | |||
| f0e631cfa3 | |||
| 45322023e3 | |||
| 7d94810d01 | |||
| e0b78476c5 | |||
| 2794eb31d9 | |||
| d8e4a1b93f | |||
| 9c06898303 | |||
| 90aa7dff04 | |||
| 1adea2f4d6 | |||
| 171d917b7e | |||
| ef06cd93cc | |||
| c0521c6d99 |
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -266,6 +266,9 @@ bin/
|
|||||||
*.exe
|
*.exe
|
||||||
*.obj
|
*.obj
|
||||||
*.pdb
|
*.pdb
|
||||||
|
*.res
|
||||||
|
desktop.ini
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
# - Linux/MacOS
|
# - Linux/MacOS
|
||||||
odin
|
odin
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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),
|
||||||
@@ -68,7 +101,7 @@ copy :: proc{copy_slice, copy_from_string}
|
|||||||
// Note: If you want the elements to remain in their order, use `ordered_remove`.
|
// Note: If you want the elements to remain in their order, use `ordered_remove`.
|
||||||
// Note: If the index is out of bounds, this procedure will panic.
|
// Note: If the index is out of bounds, this procedure will panic.
|
||||||
@builtin
|
@builtin
|
||||||
unordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) #no_bounds_check {
|
unordered_remove :: proc(array: ^$D/[dynamic]$T, #any_int index: int, loc := #caller_location) #no_bounds_check {
|
||||||
bounds_check_error_loc(loc, index, len(array))
|
bounds_check_error_loc(loc, index, len(array))
|
||||||
n := len(array)-1
|
n := len(array)-1
|
||||||
if index != n {
|
if index != n {
|
||||||
@@ -82,7 +115,7 @@ unordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_loca
|
|||||||
// Note: If the elements do not have to remain in their order, prefer `unordered_remove`.
|
// Note: If the elements do not have to remain in their order, prefer `unordered_remove`.
|
||||||
// Note: If the index is out of bounds, this procedure will panic.
|
// Note: If the index is out of bounds, this procedure will panic.
|
||||||
@builtin
|
@builtin
|
||||||
ordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) #no_bounds_check {
|
ordered_remove :: proc(array: ^$D/[dynamic]$T, #any_int index: int, loc := #caller_location) #no_bounds_check {
|
||||||
bounds_check_error_loc(loc, index, len(array))
|
bounds_check_error_loc(loc, index, len(array))
|
||||||
if index+1 < len(array) {
|
if index+1 < len(array) {
|
||||||
copy(array[index:], array[index+1:])
|
copy(array[index:], array[index+1:])
|
||||||
@@ -95,7 +128,7 @@ ordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_locati
|
|||||||
// Note: This is an O(N) operation.
|
// Note: This is an O(N) operation.
|
||||||
// Note: If the range is out of bounds, this procedure will panic.
|
// Note: If the range is out of bounds, this procedure will panic.
|
||||||
@builtin
|
@builtin
|
||||||
remove_range :: proc(array: ^$D/[dynamic]$T, lo, hi: int, loc := #caller_location) #no_bounds_check {
|
remove_range :: proc(array: ^$D/[dynamic]$T, #any_int lo, hi: int, loc := #caller_location) #no_bounds_check {
|
||||||
slice_expr_error_lo_hi_loc(loc, lo, hi, len(array))
|
slice_expr_error_lo_hi_loc(loc, lo, hi, len(array))
|
||||||
n := max(hi-lo, 0)
|
n := max(hi-lo, 0)
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
@@ -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,
|
||||||
@@ -602,7 +647,7 @@ append_nothing :: proc(array: ^$T/[dynamic]$E, loc := #caller_location) -> (n: i
|
|||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, #no_broadcast arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
inject_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -620,7 +665,7 @@ inject_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, #no_broadcast arg: E,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
inject_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
inject_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -643,7 +688,7 @@ inject_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, #no_broadcast args:
|
|||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -668,7 +713,7 @@ inject_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string
|
|||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
assign_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
assign_at_elem :: proc(array: ^$T/[dynamic]$E, #any_int index: int, arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
if index < len(array) {
|
if index < len(array) {
|
||||||
array[index] = arg
|
array[index] = arg
|
||||||
ok = true
|
ok = true
|
||||||
@@ -682,7 +727,7 @@ assign_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #calle
|
|||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
assign_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
assign_at_elems :: proc(array: ^$T/[dynamic]$E, #any_int index: int, #no_broadcast args: ..E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
new_size := index + len(args)
|
new_size := index + len(args)
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
ok = true
|
ok = true
|
||||||
@@ -699,7 +744,7 @@ assign_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, #no_broadcast args:
|
|||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
assign_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, #any_int index: int, arg: string, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error {
|
||||||
new_size := index + len(arg)
|
new_size := index + len(arg)
|
||||||
if len(arg) == 0 {
|
if len(arg) == 0 {
|
||||||
ok = true
|
ok = true
|
||||||
@@ -838,7 +883,7 @@ non_zero_resize_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int length: i
|
|||||||
|
|
||||||
Note: Prefer the procedure group `shrink`
|
Note: Prefer the procedure group `shrink`
|
||||||
*/
|
*/
|
||||||
shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, new_cap := -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {
|
shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, #any_int new_cap := -1, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {
|
||||||
return _shrink_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), new_cap, loc)
|
return _shrink_dynamic_array((^Raw_Dynamic_Array)(array), size_of(E), align_of(E), new_cap, loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -894,26 +939,14 @@ map_upsert :: proc(m: ^$T/map[$K]$V, key: K, value: V, loc := #caller_location)
|
|||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
card :: proc "contextless" (s: $S/bit_set[$E; $U]) -> int {
|
card :: proc "contextless" (s: $S/bit_set[$E; $U]) -> int {
|
||||||
when size_of(S) == 1 {
|
return int(intrinsics.count_ones(transmute(intrinsics.type_bit_set_underlying_type(S))s))
|
||||||
return int(intrinsics.count_ones(transmute(u8)s))
|
|
||||||
} else when size_of(S) == 2 {
|
|
||||||
return int(intrinsics.count_ones(transmute(u16)s))
|
|
||||||
} else when size_of(S) == 4 {
|
|
||||||
return int(intrinsics.count_ones(transmute(u32)s))
|
|
||||||
} else when size_of(S) == 8 {
|
|
||||||
return int(intrinsics.count_ones(transmute(u64)s))
|
|
||||||
} else when size_of(S) == 16 {
|
|
||||||
return int(intrinsics.count_ones(transmute(u128)s))
|
|
||||||
} else {
|
|
||||||
#panic("Unhandled card bit_set size")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@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 +985,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
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ raw_soa_footer :: proc{
|
|||||||
|
|
||||||
|
|
||||||
@(builtin, require_results)
|
@(builtin, require_results)
|
||||||
make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
make_soa_aligned :: proc($T: typeid/#soa[]$E, #any_int length, alignment: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
||||||
if length <= 0 {
|
if length <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, alloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
@(builtin, require_results)
|
@(builtin, require_results)
|
||||||
make_soa_slice :: proc($T: typeid/#soa[]$E, length: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
make_soa_slice :: proc($T: typeid/#soa[]$E, #any_int length: int, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
||||||
return make_soa_aligned(T, length, align_of(E), allocator, loc)
|
return make_soa_aligned(T, length, align_of(E), allocator, loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ make_soa :: proc{
|
|||||||
|
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error {
|
resize_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -183,7 +183,7 @@ resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_locat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
non_zero_resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error {
|
non_zero_resize_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int length: int, loc := #caller_location) -> Allocator_Error {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -194,12 +194,12 @@ non_zero_resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #cal
|
|||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error {
|
reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error {
|
||||||
return _reserve_soa(array, capacity, true, loc)
|
return _reserve_soa(array, capacity, true, loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@builtin
|
||||||
non_zero_reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error {
|
non_zero_reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int capacity: int, loc := #caller_location) -> Allocator_Error {
|
||||||
return _reserve_soa(array, capacity, false, loc)
|
return _reserve_soa(array, capacity, false, loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,7 +484,7 @@ into_dynamic_soa :: proc(array: $T/#soa[]$E) -> #soa[dynamic]E {
|
|||||||
// Note: If you the elements to remain in their order, use `ordered_remove_soa`.
|
// Note: If you the elements to remain in their order, use `ordered_remove_soa`.
|
||||||
// Note: If the index is out of bounds, this procedure will panic.
|
// Note: If the index is out of bounds, this procedure will panic.
|
||||||
@builtin
|
@builtin
|
||||||
unordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, index: int, loc := #caller_location) #no_bounds_check {
|
unordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int index: int, loc := #caller_location) #no_bounds_check {
|
||||||
bounds_check_error_loc(loc, index, len(array))
|
bounds_check_error_loc(loc, index, len(array))
|
||||||
if index+1 < len(array) {
|
if index+1 < len(array) {
|
||||||
ti := type_info_of(typeid_of(T))
|
ti := type_info_of(typeid_of(T))
|
||||||
@@ -512,7 +512,7 @@ unordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, index: int, loc := #cal
|
|||||||
// Note: If you the elements do not have to remain in their order, prefer `unordered_remove_soa`.
|
// Note: If you the elements do not have to remain in their order, prefer `unordered_remove_soa`.
|
||||||
// Note: If the index is out of bounds, this procedure will panic.
|
// Note: If the index is out of bounds, this procedure will panic.
|
||||||
@builtin
|
@builtin
|
||||||
ordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, index: int, loc := #caller_location) #no_bounds_check {
|
ordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int index: int, loc := #caller_location) #no_bounds_check {
|
||||||
bounds_check_error_loc(loc, index, len(array))
|
bounds_check_error_loc(loc, index, len(array))
|
||||||
if index+1 < len(array) {
|
if index+1 < len(array) {
|
||||||
ti := type_info_of(typeid_of(T))
|
ti := type_info_of(typeid_of(T))
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//+private
|
#+private
|
||||||
//+build windows
|
#+build windows
|
||||||
//+no-instrumentation
|
#+no-instrumentation
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//+build orca
|
#+build orca
|
||||||
//+private
|
#+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
foreign {
|
foreign {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//+build darwin
|
#+build darwin
|
||||||
//+private
|
#+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//+build freestanding
|
#+build freestanding
|
||||||
//+private
|
#+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
// TODO(bill): reimplement `os.write`
|
// TODO(bill): reimplement `os.write`
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//+build haiku
|
#+build haiku
|
||||||
//+private
|
#+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
foreign import libc "system:c"
|
foreign import libc "system:c"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//+build js
|
#+build js
|
||||||
//+private
|
#+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
foreign import "odin_env"
|
foreign import "odin_env"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//+private
|
#+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//+build orca
|
#+build orca
|
||||||
//+private
|
#+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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,4 +1,4 @@
|
|||||||
//+private
|
#+private
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
foreign import "system:Foundation.framework"
|
foreign import "system:Foundation.framework"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//+build js
|
#+build js
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
init_default_context_for_js: Context
|
init_default_context_for_js: Context
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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,4 +1,4 @@
|
|||||||
//+build wasm32, wasm64p32
|
#+build wasm32, wasm64p32
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
Executable
+19
@@ -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
|
||||||
+23
-18
@@ -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,
|
||||||
|
|||||||
@@ -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,18 +469,16 @@ 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
|
||||||
// worth vectorizing assuming there is a hardware vector unit, and
|
// worth vectorizing assuming there is a hardware vector unit, and
|
||||||
// the data size is large enough.
|
// the data size is large enough.
|
||||||
if i < SIMD_REG_SIZE_128 {
|
if i < SIMD_REG_SIZE_128 {
|
||||||
if i > 0 { // Handle s == nil.
|
#reverse for ch, j in s {
|
||||||
for /**/; i >= 0; i -= 1 {
|
if ch == c {
|
||||||
if s[i] == c {
|
return j
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ The following is a mostly-complete projection of the C11 standard library as def
|
|||||||
| `<inttypes.h>` | Fully projected |
|
| `<inttypes.h>` | Fully projected |
|
||||||
| `<iso646.h>` | Not applicable, use Odin's operators |
|
| `<iso646.h>` | Not applicable, use Odin's operators |
|
||||||
| `<limits.h>` | Not projected |
|
| `<limits.h>` | Not projected |
|
||||||
| `<locale.h>` | Not projected |
|
| `<locale.h>` | Fully projected |
|
||||||
| `<math.h>` | Mostly projected, see [limitations](#Limitations) |
|
| `<math.h>` | Mostly projected, see [limitations](#Limitations) |
|
||||||
| `<setjmp.h>` | Fully projected |
|
| `<setjmp.h>` | Fully projected |
|
||||||
| `<signal.h>` | Fully projected |
|
| `<signal.h>` | Fully projected |
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
package libc
|
||||||
|
|
||||||
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import libc "system:libucrt.lib"
|
||||||
|
} else when ODIN_OS == .Darwin {
|
||||||
|
foreign import libc "system:System.framework"
|
||||||
|
} else {
|
||||||
|
foreign import libc "system:c"
|
||||||
|
}
|
||||||
|
|
||||||
|
// locale.h - category macros
|
||||||
|
|
||||||
|
foreign libc {
|
||||||
|
/*
|
||||||
|
Sets the components of an object with the type lconv with the values appropriate for the
|
||||||
|
formatting of numeric quantities (monetary and otherwise) according to the rules of the current
|
||||||
|
locale.
|
||||||
|
|
||||||
|
Returns: a pointer to the lconv structure, might be invalidated by subsequent calls to localeconv() and setlocale()
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/localeconv.html ]]
|
||||||
|
*/
|
||||||
|
localeconv :: proc() -> ^lconv ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Selects the appropriate piece of the global locale, as specified by the category and locale arguments,
|
||||||
|
and can be used to change or query the entire global locale or portions thereof.
|
||||||
|
|
||||||
|
Returns: the current locale if `locale` is `nil`, the set locale otherwise
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/setlocale.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LSETLOCALE)
|
||||||
|
setlocale :: proc(category: Locale_Category, locale: cstring) -> cstring ---
|
||||||
|
}
|
||||||
|
|
||||||
|
Locale_Category :: enum c.int {
|
||||||
|
ALL = LC_ALL,
|
||||||
|
COLLATE = LC_COLLATE,
|
||||||
|
CTYPE = LC_CTYPE,
|
||||||
|
MESSAGES = LC_MESSAGES,
|
||||||
|
MONETARY = LC_MONETARY,
|
||||||
|
NUMERIC = LC_NUMERIC,
|
||||||
|
TIME = LC_TIME,
|
||||||
|
}
|
||||||
|
|
||||||
|
when ODIN_OS == .NetBSD {
|
||||||
|
@(private) LSETLOCALE :: "__setlocale50"
|
||||||
|
} else {
|
||||||
|
@(private) LSETLOCALE :: "setlocale"
|
||||||
|
}
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
lconv :: struct {
|
||||||
|
decimal_point: cstring,
|
||||||
|
thousand_sep: cstring,
|
||||||
|
grouping: cstring,
|
||||||
|
int_curr_symbol: cstring,
|
||||||
|
currency_symbol: cstring,
|
||||||
|
mon_decimal_points: cstring,
|
||||||
|
mon_thousands_sep: cstring,
|
||||||
|
mon_grouping: cstring,
|
||||||
|
positive_sign: cstring,
|
||||||
|
negative_sign: cstring,
|
||||||
|
int_frac_digits: c.char,
|
||||||
|
frac_digits: c.char,
|
||||||
|
p_cs_precedes: c.char,
|
||||||
|
p_sep_by_space: c.char,
|
||||||
|
n_cs_precedes: c.char,
|
||||||
|
n_sep_by_space: c.char,
|
||||||
|
p_sign_posn: c.char,
|
||||||
|
n_sign_posn: c.char,
|
||||||
|
_W_decimal_point: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_thousands_sep: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_int_curr_symbol: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_currency_symbol: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_mon_decimal_point: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_mon_thousands_sep: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_positive_sign: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_negative_sign: [^]u16 `fmt:"s,0"`,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lconv :: struct {
|
||||||
|
decimal_point: cstring,
|
||||||
|
thousand_sep: cstring,
|
||||||
|
grouping: cstring,
|
||||||
|
int_curr_symbol: cstring,
|
||||||
|
currency_symbol: cstring,
|
||||||
|
mon_decimal_points: cstring,
|
||||||
|
mon_thousands_sep: cstring,
|
||||||
|
mon_grouping: cstring,
|
||||||
|
positive_sign: cstring,
|
||||||
|
negative_sign: cstring,
|
||||||
|
int_frac_digits: c.char,
|
||||||
|
frac_digits: c.char,
|
||||||
|
p_cs_precedes: c.char,
|
||||||
|
p_sep_by_space: c.char,
|
||||||
|
n_cs_precedes: c.char,
|
||||||
|
n_sep_by_space: c.char,
|
||||||
|
p_sign_posn: c.char,
|
||||||
|
n_sign_posn: c.char,
|
||||||
|
_int_p_cs_precedes: c.char,
|
||||||
|
_int_n_cs_precedes: c.char,
|
||||||
|
_int_p_sep_by_space: c.char,
|
||||||
|
_int_n_sep_by_space: c.char,
|
||||||
|
_int_p_sign_posn: c.char,
|
||||||
|
_int_n_sign_posn: c.char,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Windows {
|
||||||
|
|
||||||
|
LC_ALL :: 0
|
||||||
|
LC_COLLATE :: 1
|
||||||
|
LC_CTYPE :: 2
|
||||||
|
LC_MESSAGES :: 6
|
||||||
|
LC_MONETARY :: 3
|
||||||
|
LC_NUMERIC :: 4
|
||||||
|
LC_TIME :: 5
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Linux {
|
||||||
|
|
||||||
|
LC_CTYPE :: 0
|
||||||
|
LC_NUMERIC :: 1
|
||||||
|
LC_TIME :: 2
|
||||||
|
LC_COLLATE :: 3
|
||||||
|
LC_MONETARY :: 4
|
||||||
|
LC_MESSAGES :: 5
|
||||||
|
LC_ALL :: 6
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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,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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 ---
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
|
||||||
|
Made available under Odin's BSD-3 license.
|
||||||
|
|
||||||
|
List of contributors:
|
||||||
|
Jeroen van Rijn: Initial implementation.
|
||||||
|
Ginger Bill: Cosmetic changes.
|
||||||
|
|
||||||
|
A small GZIP implementation as an example.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Example:
|
||||||
|
import "core:bytes"
|
||||||
|
import "core:os"
|
||||||
|
import "core:compress"
|
||||||
|
import "core:fmt"
|
||||||
|
|
||||||
|
// Small GZIP file with fextra, fname and fcomment present.
|
||||||
|
@private
|
||||||
|
TEST: []u8 = {
|
||||||
|
0x1f, 0x8b, 0x08, 0x1c, 0xcb, 0x3b, 0x3a, 0x5a,
|
||||||
|
0x02, 0x03, 0x07, 0x00, 0x61, 0x62, 0x03, 0x00,
|
||||||
|
0x63, 0x64, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x6e,
|
||||||
|
0x61, 0x6d, 0x65, 0x00, 0x54, 0x68, 0x69, 0x73,
|
||||||
|
0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f,
|
||||||
|
0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x2b, 0x48,
|
||||||
|
0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x01, 0x00, 0x15,
|
||||||
|
0x6a, 0x2c, 0x42, 0x07, 0x00, 0x00, 0x00,
|
||||||
|
}
|
||||||
|
|
||||||
|
main :: proc() {
|
||||||
|
// Set up output buffer.
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
|
||||||
|
stdout :: proc(s: string) {
|
||||||
|
os.write_string(os.stdout, s)
|
||||||
|
}
|
||||||
|
stderr :: proc(s: string) {
|
||||||
|
os.write_string(os.stderr, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
args := os.args
|
||||||
|
|
||||||
|
if len(args) < 2 {
|
||||||
|
stderr("No input file specified.\n")
|
||||||
|
err := load(data=TEST, buf=&buf, known_gzip_size=len(TEST))
|
||||||
|
if err == nil {
|
||||||
|
stdout("Displaying test vector: ")
|
||||||
|
stdout(bytes.buffer_to_string(&buf))
|
||||||
|
stdout("\n")
|
||||||
|
} else {
|
||||||
|
fmt.printf("gzip.load returned %v\n", err)
|
||||||
|
}
|
||||||
|
bytes.buffer_destroy(&buf)
|
||||||
|
os.exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The rest are all files.
|
||||||
|
args = args[1:]
|
||||||
|
err: Error
|
||||||
|
|
||||||
|
for file in args {
|
||||||
|
if file == "-" {
|
||||||
|
// Read from stdin
|
||||||
|
s := os.stream_from_handle(os.stdin)
|
||||||
|
ctx := &compress.Context_Stream_Input{
|
||||||
|
input = s,
|
||||||
|
}
|
||||||
|
err = load(ctx, &buf)
|
||||||
|
} else {
|
||||||
|
err = load(file, &buf)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if err != E_General.File_Not_Found {
|
||||||
|
stderr("File not found: ")
|
||||||
|
stderr(file)
|
||||||
|
stderr("\n")
|
||||||
|
os.exit(1)
|
||||||
|
}
|
||||||
|
stderr("GZIP returned an error.\n")
|
||||||
|
bytes.buffer_destroy(&buf)
|
||||||
|
os.exit(2)
|
||||||
|
}
|
||||||
|
stdout(bytes.buffer_to_string(&buf))
|
||||||
|
}
|
||||||
|
bytes.buffer_destroy(&buf)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package compress_gzip
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
//+build ignore
|
|
||||||
package compress_gzip
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
|
|
||||||
Made available under Odin's BSD-3 license.
|
|
||||||
|
|
||||||
List of contributors:
|
|
||||||
Jeroen van Rijn: Initial implementation.
|
|
||||||
Ginger Bill: Cosmetic changes.
|
|
||||||
|
|
||||||
A small GZIP implementation as an example.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import "core:bytes"
|
|
||||||
import "core:os"
|
|
||||||
import "core:compress"
|
|
||||||
import "core:fmt"
|
|
||||||
|
|
||||||
// Small GZIP file with fextra, fname and fcomment present.
|
|
||||||
@private
|
|
||||||
TEST: []u8 = {
|
|
||||||
0x1f, 0x8b, 0x08, 0x1c, 0xcb, 0x3b, 0x3a, 0x5a,
|
|
||||||
0x02, 0x03, 0x07, 0x00, 0x61, 0x62, 0x03, 0x00,
|
|
||||||
0x63, 0x64, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x6e,
|
|
||||||
0x61, 0x6d, 0x65, 0x00, 0x54, 0x68, 0x69, 0x73,
|
|
||||||
0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f,
|
|
||||||
0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x2b, 0x48,
|
|
||||||
0xac, 0xcc, 0xc9, 0x4f, 0x4c, 0x01, 0x00, 0x15,
|
|
||||||
0x6a, 0x2c, 0x42, 0x07, 0x00, 0x00, 0x00,
|
|
||||||
}
|
|
||||||
|
|
||||||
main :: proc() {
|
|
||||||
// Set up output buffer.
|
|
||||||
buf := bytes.Buffer{}
|
|
||||||
|
|
||||||
stdout :: proc(s: string) {
|
|
||||||
os.write_string(os.stdout, s)
|
|
||||||
}
|
|
||||||
stderr :: proc(s: string) {
|
|
||||||
os.write_string(os.stderr, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
args := os.args
|
|
||||||
|
|
||||||
if len(args) < 2 {
|
|
||||||
stderr("No input file specified.\n")
|
|
||||||
err := load(data=TEST, buf=&buf, known_gzip_size=len(TEST))
|
|
||||||
if err == nil {
|
|
||||||
stdout("Displaying test vector: ")
|
|
||||||
stdout(bytes.buffer_to_string(&buf))
|
|
||||||
stdout("\n")
|
|
||||||
} else {
|
|
||||||
fmt.printf("gzip.load returned %v\n", err)
|
|
||||||
}
|
|
||||||
bytes.buffer_destroy(&buf)
|
|
||||||
os.exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The rest are all files.
|
|
||||||
args = args[1:]
|
|
||||||
err: Error
|
|
||||||
|
|
||||||
for file in args {
|
|
||||||
if file == "-" {
|
|
||||||
// Read from stdin
|
|
||||||
s := os.stream_from_handle(os.stdin)
|
|
||||||
ctx := &compress.Context_Stream_Input{
|
|
||||||
input = s,
|
|
||||||
}
|
|
||||||
err = load(ctx, &buf)
|
|
||||||
} else {
|
|
||||||
err = load(file, &buf)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
if err != E_General.File_Not_Found {
|
|
||||||
stderr("File not found: ")
|
|
||||||
stderr(file)
|
|
||||||
stderr("\n")
|
|
||||||
os.exit(1)
|
|
||||||
}
|
|
||||||
stderr("GZIP returned an error.\n")
|
|
||||||
bytes.buffer_destroy(&buf)
|
|
||||||
os.exit(2)
|
|
||||||
}
|
|
||||||
stdout(bytes.buffer_to_string(&buf))
|
|
||||||
}
|
|
||||||
bytes.buffer_destroy(&buf)
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
which is an English word model.
|
which is an English word model.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// package shoco is an implementation of the shoco short string compressor
|
|
||||||
package compress_shoco
|
package compress_shoco
|
||||||
|
|
||||||
DEFAULT_MODEL :: Shoco_Model {
|
DEFAULT_MODEL :: Shoco_Model {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
An implementation of [shoco](https://github.com/Ed-von-Schleck/shoco) by Christian Schramm.
|
An implementation of [shoco](https://github.com/Ed-von-Schleck/shoco) by Christian Schramm.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// package shoco is an implementation of the shoco short string compressor
|
// package shoco is an implementation of the shoco short string compressor.
|
||||||
package compress_shoco
|
package compress_shoco
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
|
||||||
|
Made available under Odin's BSD-3 license.
|
||||||
|
|
||||||
|
List of contributors:
|
||||||
|
Jeroen van Rijn: Initial implementation.
|
||||||
|
|
||||||
|
An example of how to use `zlib.inflate`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Example:
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "core:bytes"
|
||||||
|
import "core:fmt"
|
||||||
|
|
||||||
|
main :: proc() {
|
||||||
|
ODIN_DEMO := []u8{
|
||||||
|
120, 218, 101, 144, 65, 110, 131, 48, 16, 69, 215, 246, 41, 190, 44, 69, 73, 32, 148, 182,
|
||||||
|
75, 75, 28, 32, 251, 46, 217, 88, 238, 0, 86, 192, 32, 219, 36, 170, 170, 172, 122, 137,
|
||||||
|
238, 122, 197, 30, 161, 70, 162, 20, 81, 203, 139, 25, 191, 255, 191, 60, 51, 40, 125, 81,
|
||||||
|
53, 33, 144, 15, 156, 155, 110, 232, 93, 128, 208, 189, 35, 89, 117, 65, 112, 222, 41, 99,
|
||||||
|
33, 37, 6, 215, 235, 195, 17, 239, 156, 197, 170, 118, 170, 131, 44, 32, 82, 164, 72, 240,
|
||||||
|
253, 245, 249, 129, 12, 185, 224, 76, 105, 61, 118, 99, 171, 66, 239, 38, 193, 35, 103, 85,
|
||||||
|
172, 66, 127, 33, 139, 24, 244, 235, 141, 49, 204, 223, 76, 208, 205, 204, 166, 7, 173, 60,
|
||||||
|
97, 159, 238, 37, 214, 41, 105, 129, 167, 5, 102, 27, 152, 173, 97, 178, 129, 73, 129, 231,
|
||||||
|
5, 230, 27, 152, 175, 225, 52, 192, 127, 243, 170, 157, 149, 18, 121, 142, 115, 109, 227, 122,
|
||||||
|
64, 87, 114, 111, 161, 49, 182, 6, 181, 158, 162, 226, 206, 167, 27, 215, 246, 48, 56, 99,
|
||||||
|
67, 117, 16, 47, 13, 45, 35, 151, 98, 231, 75, 1, 173, 90, 61, 101, 146, 71, 136, 244,
|
||||||
|
170, 218, 145, 176, 123, 45, 173, 56, 113, 134, 191, 51, 219, 78, 235, 95, 28, 249, 253, 7,
|
||||||
|
159, 150, 133, 125,
|
||||||
|
}
|
||||||
|
OUTPUT_SIZE :: 432
|
||||||
|
|
||||||
|
buf: bytes.Buffer
|
||||||
|
|
||||||
|
// We can pass ", true" to inflate a raw DEFLATE stream instead of a ZLIB wrapped one.
|
||||||
|
err := inflate(input=ODIN_DEMO, buf=&buf, expected_output_size=OUTPUT_SIZE)
|
||||||
|
defer bytes.buffer_destroy(&buf)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.printf("\nError: %v\n", err)
|
||||||
|
}
|
||||||
|
s := bytes.buffer_to_string(&buf)
|
||||||
|
fmt.printf("Input: %v bytes, output (%v bytes):\n%v\n", len(ODIN_DEMO), len(s), s)
|
||||||
|
assert(len(s) == OUTPUT_SIZE)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package compress_zlib
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
//+build ignore
|
|
||||||
package compress_zlib
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
|
|
||||||
Made available under Odin's BSD-3 license.
|
|
||||||
|
|
||||||
List of contributors:
|
|
||||||
Jeroen van Rijn: Initial implementation.
|
|
||||||
|
|
||||||
An example of how to use `zlib.inflate`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import "core:bytes"
|
|
||||||
import "core:fmt"
|
|
||||||
|
|
||||||
main :: proc() {
|
|
||||||
ODIN_DEMO := []u8{
|
|
||||||
120, 218, 101, 144, 65, 110, 131, 48, 16, 69, 215, 246, 41, 190, 44, 69, 73, 32, 148, 182,
|
|
||||||
75, 75, 28, 32, 251, 46, 217, 88, 238, 0, 86, 192, 32, 219, 36, 170, 170, 172, 122, 137,
|
|
||||||
238, 122, 197, 30, 161, 70, 162, 20, 81, 203, 139, 25, 191, 255, 191, 60, 51, 40, 125, 81,
|
|
||||||
53, 33, 144, 15, 156, 155, 110, 232, 93, 128, 208, 189, 35, 89, 117, 65, 112, 222, 41, 99,
|
|
||||||
33, 37, 6, 215, 235, 195, 17, 239, 156, 197, 170, 118, 170, 131, 44, 32, 82, 164, 72, 240,
|
|
||||||
253, 245, 249, 129, 12, 185, 224, 76, 105, 61, 118, 99, 171, 66, 239, 38, 193, 35, 103, 85,
|
|
||||||
172, 66, 127, 33, 139, 24, 244, 235, 141, 49, 204, 223, 76, 208, 205, 204, 166, 7, 173, 60,
|
|
||||||
97, 159, 238, 37, 214, 41, 105, 129, 167, 5, 102, 27, 152, 173, 97, 178, 129, 73, 129, 231,
|
|
||||||
5, 230, 27, 152, 175, 225, 52, 192, 127, 243, 170, 157, 149, 18, 121, 142, 115, 109, 227, 122,
|
|
||||||
64, 87, 114, 111, 161, 49, 182, 6, 181, 158, 162, 226, 206, 167, 27, 215, 246, 48, 56, 99,
|
|
||||||
67, 117, 16, 47, 13, 45, 35, 151, 98, 231, 75, 1, 173, 90, 61, 101, 146, 71, 136, 244,
|
|
||||||
170, 218, 145, 176, 123, 45, 173, 56, 113, 134, 191, 51, 219, 78, 235, 95, 28, 249, 253, 7,
|
|
||||||
159, 150, 133, 125,
|
|
||||||
}
|
|
||||||
OUTPUT_SIZE :: 432
|
|
||||||
|
|
||||||
buf: bytes.Buffer
|
|
||||||
|
|
||||||
// We can pass ", true" to inflate a raw DEFLATE stream instead of a ZLIB wrapped one.
|
|
||||||
err := inflate(input=ODIN_DEMO, buf=&buf, expected_output_size=OUTPUT_SIZE)
|
|
||||||
defer bytes.buffer_destroy(&buf)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.printf("\nError: %v\n", err)
|
|
||||||
}
|
|
||||||
s := bytes.buffer_to_string(&buf)
|
|
||||||
fmt.printf("Input: %v bytes, output (%v bytes):\n%v\n", len(ODIN_DEMO), len(s), s)
|
|
||||||
assert(len(s) == OUTPUT_SIZE)
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
//+vet !using-param
|
#+vet !using-param
|
||||||
package compress_zlib
|
package compress_zlib
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package container_dynamic_bit_array
|
package container_dynamic_bit_array
|
||||||
|
|
||||||
|
import "base:builtin"
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ NUM_BITS :: 64
|
|||||||
Bit_Array :: struct {
|
Bit_Array :: struct {
|
||||||
bits: [dynamic]u64,
|
bits: [dynamic]u64,
|
||||||
bias: int,
|
bias: int,
|
||||||
max_index: int,
|
length: int,
|
||||||
free_pointer: bool,
|
free_pointer: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,9 +53,9 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
iterate_by_all :: proc (it: ^Bit_Array_Iterator) -> (set: bool, index: int, ok: bool) {
|
iterate_by_all :: proc (it: ^Bit_Array_Iterator) -> (set: bool, index: int, ok: bool) {
|
||||||
index = it.word_idx * NUM_BITS + int(it.bit_idx) + it.array.bias
|
index = it.word_idx * NUM_BITS + int(it.bit_idx) + it.array.bias
|
||||||
if index > it.array.max_index { return false, 0, false }
|
if index >= it.array.length + it.array.bias { return false, 0, false }
|
||||||
|
|
||||||
word := it.array.bits[it.word_idx] if len(it.array.bits) > it.word_idx else 0
|
word := it.array.bits[it.word_idx] if builtin.len(it.array.bits) > it.word_idx else 0
|
||||||
set = (word >> it.bit_idx & 1) == 1
|
set = (word >> it.bit_idx & 1) == 1
|
||||||
|
|
||||||
it.bit_idx += 1
|
it.bit_idx += 1
|
||||||
@@ -106,22 +107,22 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
@(private="file")
|
@(private="file")
|
||||||
iterate_internal_ :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) -> (index: int, ok: bool) {
|
iterate_internal_ :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) -> (index: int, ok: bool) {
|
||||||
word := it.array.bits[it.word_idx] if len(it.array.bits) > it.word_idx else 0
|
word := it.array.bits[it.word_idx] if builtin.len(it.array.bits) > it.word_idx else 0
|
||||||
when ! ITERATE_SET_BITS { word = ~word }
|
when ! ITERATE_SET_BITS { word = ~word }
|
||||||
|
|
||||||
// If the word is empty or we have already gone over all the bits in it,
|
// If the word is empty or we have already gone over all the bits in it,
|
||||||
// b.bit_idx is greater than the index of any set bit in the word,
|
// b.bit_idx is greater than the index of any set bit in the word,
|
||||||
// meaning that word >> b.bit_idx == 0.
|
// meaning that word >> b.bit_idx == 0.
|
||||||
for it.word_idx < len(it.array.bits) && word >> it.bit_idx == 0 {
|
for it.word_idx < builtin.len(it.array.bits) && word >> it.bit_idx == 0 {
|
||||||
it.word_idx += 1
|
it.word_idx += 1
|
||||||
it.bit_idx = 0
|
it.bit_idx = 0
|
||||||
word = it.array.bits[it.word_idx] if len(it.array.bits) > it.word_idx else 0
|
word = it.array.bits[it.word_idx] if builtin.len(it.array.bits) > it.word_idx else 0
|
||||||
when ! ITERATE_SET_BITS { word = ~word }
|
when ! ITERATE_SET_BITS { word = ~word }
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are iterating the set bits, reaching the end of the array means we have no more bits to check
|
// If we are iterating the set bits, reaching the end of the array means we have no more bits to check
|
||||||
when ITERATE_SET_BITS {
|
when ITERATE_SET_BITS {
|
||||||
if it.word_idx >= len(it.array.bits) {
|
if it.word_idx >= builtin.len(it.array.bits) {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,7 +136,7 @@ iterate_internal_ :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) ->
|
|||||||
it.bit_idx = 0
|
it.bit_idx = 0
|
||||||
it.word_idx += 1
|
it.word_idx += 1
|
||||||
}
|
}
|
||||||
return index, index <= it.array.max_index
|
return index, index < it.array.length + it.array.bias
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Gets the state of a bit in the bit-array
|
Gets the state of a bit in the bit-array
|
||||||
@@ -160,7 +161,7 @@ get :: proc(ba: ^Bit_Array, #any_int index: uint) -> (res: bool, ok: bool) #opti
|
|||||||
If we `get` a bit that doesn't fit in the Bit Array, it's naturally `false`.
|
If we `get` a bit that doesn't fit in the Bit Array, it's naturally `false`.
|
||||||
This early-out prevents unnecessary resizing.
|
This early-out prevents unnecessary resizing.
|
||||||
*/
|
*/
|
||||||
if leg_index + 1 > len(ba.bits) { return false, true }
|
if leg_index + 1 > builtin.len(ba.bits) { return false, true }
|
||||||
|
|
||||||
val := u64(1 << uint(bit_index))
|
val := u64(1 << uint(bit_index))
|
||||||
res = ba.bits[leg_index] & val == val
|
res = ba.bits[leg_index] & val == val
|
||||||
@@ -208,7 +209,7 @@ set :: proc(ba: ^Bit_Array, #any_int index: uint, set_to: bool = true, allocator
|
|||||||
|
|
||||||
resize_if_needed(ba, leg_index) or_return
|
resize_if_needed(ba, leg_index) or_return
|
||||||
|
|
||||||
ba.max_index = max(idx, ba.max_index)
|
ba.length = max(1 + idx, ba.length)
|
||||||
|
|
||||||
if set_to {
|
if set_to {
|
||||||
ba.bits[leg_index] |= 1 << uint(bit_index)
|
ba.bits[leg_index] |= 1 << uint(bit_index)
|
||||||
@@ -258,9 +259,13 @@ 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).
|
||||||
|
|
||||||
|
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 (`new(Bit_Array) & make(ba.bits)`)*
|
*Allocates (`new(Bit_Array) & make(ba.bits)`)*
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
@@ -272,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 < 1 { return {}, false }
|
if size_in_bits < 0 { return {}, false }
|
||||||
|
|
||||||
legs := size_in_bits >> INDEX_SHIFT
|
res = new(Bit_Array, allocator)
|
||||||
if size_in_bits & INDEX_MASK > 0 {legs+=1}
|
ok = init(res, max_index, min_index, allocator)
|
||||||
bits, err := make([dynamic]u64, legs)
|
|
||||||
ok = err == mem.Allocator_Error.None
|
|
||||||
res = new(Bit_Array)
|
|
||||||
res.bits = bits
|
|
||||||
res.bias = min_index
|
|
||||||
res.max_index = max_index
|
|
||||||
res.free_pointer = true
|
res.free_pointer = true
|
||||||
|
|
||||||
|
if !ok { free(res, allocator) }
|
||||||
|
|
||||||
return
|
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, allocator)
|
||||||
|
ok = err == nil
|
||||||
|
|
||||||
|
res.bits = bits
|
||||||
|
res.bias = min_index
|
||||||
|
res.length = max_index - min_index
|
||||||
|
res.free_pointer = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Sets all values in the Bit_Array to zero.
|
Sets all values in the Bit_Array to zero.
|
||||||
|
|
||||||
@@ -299,6 +332,48 @@ clear :: proc(ba: ^Bit_Array) {
|
|||||||
mem.zero_slice(ba.bits[:])
|
mem.zero_slice(ba.bits[:])
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
Gets the length of set and unset valid bits in the Bit_Array.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- ba: The target Bit_Array
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- length: The length of valid bits.
|
||||||
|
*/
|
||||||
|
len :: proc(ba: ^Bit_Array) -> (length: int) {
|
||||||
|
if ba == nil { return }
|
||||||
|
return ba.length
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Shrinks the Bit_Array's backing storage to the smallest possible size.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- ba: The target Bit_Array
|
||||||
|
*/
|
||||||
|
shrink :: proc(ba: ^Bit_Array) #no_bounds_check {
|
||||||
|
if ba == nil { return }
|
||||||
|
legs_needed := builtin.len(ba.bits)
|
||||||
|
for i := legs_needed - 1; i >= 0; i -= 1 {
|
||||||
|
if ba.bits[i] == 0 {
|
||||||
|
legs_needed -= 1
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if legs_needed == builtin.len(ba.bits) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ba.length = 0
|
||||||
|
if legs_needed > 0 {
|
||||||
|
if legs_needed > 1 {
|
||||||
|
ba.length = (legs_needed - 1) * NUM_BITS
|
||||||
|
}
|
||||||
|
ba.length += NUM_BITS - int(intrinsics.count_leading_zeros(ba.bits[legs_needed - 1]))
|
||||||
|
}
|
||||||
|
resize(&ba.bits, legs_needed)
|
||||||
|
builtin.shrink(&ba.bits)
|
||||||
|
}
|
||||||
|
/*
|
||||||
Deallocates the Bit_Array and its backing storage
|
Deallocates the Bit_Array and its backing storage
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
@@ -321,8 +396,8 @@ resize_if_needed :: proc(ba: ^Bit_Array, legs: int, allocator := context.allocat
|
|||||||
|
|
||||||
context.allocator = allocator
|
context.allocator = allocator
|
||||||
|
|
||||||
if legs + 1 > len(ba.bits) {
|
if legs + 1 > builtin.len(ba.bits) {
|
||||||
resize(&ba.bits, legs + 1)
|
resize(&ba.bits, legs + 1)
|
||||||
}
|
}
|
||||||
return len(ba.bits) > legs
|
return builtin.len(ba.bits) > legs
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
The Bit Array can be used in several ways:
|
The Bit Array can be used in several ways:
|
||||||
|
|
||||||
- By default you don't need to instantiate a Bit Array:
|
By default you don't need to instantiate a Bit Array.
|
||||||
|
Example:
|
||||||
package test
|
package test
|
||||||
|
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
@@ -22,8 +22,8 @@ The Bit Array can be used in several ways:
|
|||||||
destroy(&bits)
|
destroy(&bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
- A Bit Array can optionally allow for negative indices, if the minimum value was given during creation:
|
A Bit Array can optionally allow for negative indices, if the minimum value was given during creation.
|
||||||
|
Example:
|
||||||
package test
|
package test
|
||||||
|
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
/*
|
/*
|
||||||
Package list implements an intrusive doubly-linked list.
|
Package list implements an intrusive doubly-linked list.
|
||||||
|
|
||||||
An intrusive container requires a `Node` to be embedded in your own structure, like this:
|
An intrusive container requires a `Node` to be embedded in your own structure, like this.
|
||||||
|
Example:
|
||||||
My_String :: struct {
|
My_String :: struct {
|
||||||
node: list.Node,
|
node: list.Node,
|
||||||
value: string,
|
value: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
Embedding the members of a `list.Node` in your structure with the `using` keyword is also allowed:
|
Embedding the members of a `list.Node` in your structure with the `using` keyword is also allowed.
|
||||||
|
Example:
|
||||||
My_String :: struct {
|
My_String :: struct {
|
||||||
using node: list.Node,
|
using node: list.Node,
|
||||||
value: string,
|
value: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
Here is a full example:
|
Here is a full example.
|
||||||
|
Example:
|
||||||
package test
|
package test
|
||||||
|
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
@@ -42,5 +42,8 @@ Here is a full example:
|
|||||||
value: string,
|
value: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Output:
|
||||||
|
Hello
|
||||||
|
World
|
||||||
*/
|
*/
|
||||||
package container_intrusive_list
|
package container_intrusive_list
|
||||||
|
|||||||
@@ -139,9 +139,13 @@ clear :: proc "contextless" (a: ^$A/Small_Array($N, $T)) {
|
|||||||
resize(a, 0)
|
resize(a, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
push_back_elems :: proc "contextless" (a: ^$A/Small_Array($N, $T), items: ..T) {
|
push_back_elems :: proc "contextless" (a: ^$A/Small_Array($N, $T), items: ..T) -> bool {
|
||||||
n := copy(a.data[a.len:], items[:])
|
if a.len + builtin.len(items) <= cap(a^) {
|
||||||
a.len += n
|
n := copy(a.data[a.len:], items[:])
|
||||||
|
a.len += n
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
inject_at :: proc "contextless" (a: ^$A/Small_Array($N, $T), item: T, index: int) -> bool #no_bounds_check {
|
inject_at :: proc "contextless" (a: ^$A/Small_Array($N, $T), item: T, index: int) -> bool #no_bounds_check {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//+build amd64
|
#+build amd64
|
||||||
package aes_hw_intel
|
package aes_hw_intel
|
||||||
|
|
||||||
import "core:sys/info"
|
import "core:sys/info"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
+34
-35
@@ -10,49 +10,48 @@ algorithm.
|
|||||||
WARNING: Reusing the same key + iv to seal (encrypt) multiple messages
|
WARNING: Reusing the same key + iv to seal (encrypt) multiple messages
|
||||||
results in catastrophic loss of security for most algorithms.
|
results in catastrophic loss of security for most algorithms.
|
||||||
|
|
||||||
```odin
|
Example:
|
||||||
package aead_example
|
package aead_example
|
||||||
|
|
||||||
import "core:bytes"
|
import "core:bytes"
|
||||||
import "core:crypto"
|
import "core:crypto"
|
||||||
import "core:crypto/aead"
|
import "core:crypto/aead"
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
algo := aead.Algorithm.XCHACHA20POLY1305
|
algo := aead.Algorithm.XCHACHA20POLY1305
|
||||||
|
|
||||||
// The example added associated data, and plaintext.
|
// The example added associated data, and plaintext.
|
||||||
aad_str := "Get your ass in gear boys."
|
aad_str := "Get your ass in gear boys."
|
||||||
pt_str := "They're immanetizing the Eschaton."
|
pt_str := "They're immanetizing the Eschaton."
|
||||||
|
|
||||||
aad := transmute([]byte)aad_str
|
aad := transmute([]byte)aad_str
|
||||||
plaintext := transmute([]byte)pt_str
|
plaintext := transmute([]byte)pt_str
|
||||||
pt_len := len(plaintext)
|
pt_len := len(plaintext)
|
||||||
|
|
||||||
// Generate a random key for the purposes of illustration.
|
// Generate a random key for the purposes of illustration.
|
||||||
key := make([]byte, aead.KEY_SIZES[algo])
|
key := make([]byte, aead.KEY_SIZES[algo])
|
||||||
defer delete(key)
|
defer delete(key)
|
||||||
crypto.rand_bytes(key)
|
crypto.rand_bytes(key)
|
||||||
|
|
||||||
// `ciphertext || tag`, is a common way data is transmitted, so
|
// `ciphertext || tag`, is a common way data is transmitted, so
|
||||||
// demonstrate that.
|
// demonstrate that.
|
||||||
buf := make([]byte, pt_len + aead.TAG_SIZES[algo])
|
buf := make([]byte, pt_len + aead.TAG_SIZES[algo])
|
||||||
defer delete(buf)
|
defer delete(buf)
|
||||||
ciphertext, tag := buf[:pt_len], buf[pt_len:]
|
ciphertext, tag := buf[:pt_len], buf[pt_len:]
|
||||||
|
|
||||||
// Seal the AAD + Plaintext.
|
// Seal the AAD + Plaintext.
|
||||||
iv := make([]byte, aead.IV_SIZES[algo])
|
iv := make([]byte, aead.IV_SIZES[algo])
|
||||||
defer delete(iv)
|
defer delete(iv)
|
||||||
crypto.rand_bytes(iv) // Random IVs are safe with XChaCha20-Poly1305.
|
crypto.rand_bytes(iv) // Random IVs are safe with XChaCha20-Poly1305.
|
||||||
aead.seal(algo, ciphertext, tag, key, iv, aad, plaintext)
|
aead.seal(algo, ciphertext, tag, key, iv, aad, plaintext)
|
||||||
|
|
||||||
// Open the AAD + Ciphertext.
|
// Open the AAD + Ciphertext.
|
||||||
opened_pt := buf[:pt_len]
|
opened_pt := buf[:pt_len]
|
||||||
if ok := aead.open(algo, opened_pt, key, iv, aad, ciphertext, tag); !ok {
|
if ok := aead.open(algo, opened_pt, key, iv, aad, ciphertext, tag); !ok {
|
||||||
panic("aead example: failed to open")
|
panic("aead example: failed to open")
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(bytes.equal(opened_pt, plaintext))
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(bytes.equal(opened_pt, plaintext))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
*/
|
*/
|
||||||
package aead
|
package aead
|
||||||
@@ -2,9 +2,9 @@
|
|||||||
package aes implements the AES block cipher and some common modes.
|
package aes implements the AES block cipher and some common modes.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf ]]
|
||||||
- https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf ]]
|
||||||
- https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf ]]
|
||||||
*/
|
*/
|
||||||
package aes
|
package aes
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//+build amd64
|
#+build amd64
|
||||||
package aes
|
package aes
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//+build amd64
|
#+build amd64
|
||||||
package aes
|
package aes
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//+build amd64
|
#+build amd64
|
||||||
package aes
|
package aes
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//+build !amd64
|
#+build !amd64
|
||||||
package aes
|
package aes
|
||||||
|
|
||||||
@(private = "file")
|
@(private = "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"
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
package blake2b implements the BLAKE2b hash algorithm.
|
package blake2b implements the BLAKE2b hash algorithm.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://datatracker.ietf.org/doc/html/rfc7693
|
- [[ https://datatracker.ietf.org/doc/html/rfc7693 ]]
|
||||||
- https://www.blake2.net
|
- [[ https://www.blake2.net ]]
|
||||||
*/
|
*/
|
||||||
package blake2b
|
package blake2b
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
package blake2s implements the BLAKE2s hash algorithm.
|
package blake2s implements the BLAKE2s hash algorithm.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://datatracker.ietf.org/doc/html/rfc7693
|
- [[ https://datatracker.ietf.org/doc/html/rfc7693 ]]
|
||||||
- https://www.blake2.net/
|
- [[ https://www.blake2.net/ ]]
|
||||||
*/
|
*/
|
||||||
package blake2s
|
package blake2s
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
package chacha20 implements the ChaCha20 and XChaCha20 stream ciphers.
|
package chacha20 implements the ChaCha20 and XChaCha20 stream ciphers.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://datatracker.ietf.org/doc/html/rfc8439
|
- [[ https://datatracker.ietf.org/doc/html/rfc8439 ]]
|
||||||
- https://datatracker.ietf.org/doc/draft-irtf-cfrg-xchacha/03/
|
- [[ https://datatracker.ietf.org/doc/draft-irtf-cfrg-xchacha/03/ ]]
|
||||||
*/
|
*/
|
||||||
package chacha20
|
package chacha20
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ AEAD_XChaCha20_Poly1305 Authenticated Encryption with Additional Data
|
|||||||
algorithms.
|
algorithms.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://www.rfc-editor.org/rfc/rfc8439
|
- [[ https://www.rfc-editor.org/rfc/rfc8439 ]]
|
||||||
- https://datatracker.ietf.org/doc/html/draft-arciszewski-xchacha-03
|
- [[ https://datatracker.ietf.org/doc/html/draft-arciszewski-xchacha-03 ]]
|
||||||
*/
|
*/
|
||||||
package chacha20poly1305
|
package chacha20poly1305
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
package ed25519 implements the Ed25519 EdDSA signature algorithm.
|
package ed25519 implements the Ed25519 EdDSA signature algorithm.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://datatracker.ietf.org/doc/html/rfc8032
|
- [[ https://datatracker.ietf.org/doc/html/rfc8032 ]]
|
||||||
- https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf ]]
|
||||||
- https://eprint.iacr.org/2020/1244.pdf
|
- [[ https://eprint.iacr.org/2020/1244.pdf ]]
|
||||||
*/
|
*/
|
||||||
package ed25519
|
package ed25519
|
||||||
|
|
||||||
|
|||||||
+27
-29
@@ -17,46 +17,44 @@ accomplish common tasks.
|
|||||||
A third optional boolean parameter controls if the file is streamed
|
A third optional boolean parameter controls if the file is streamed
|
||||||
(default), or or read at once.
|
(default), or or read at once.
|
||||||
|
|
||||||
```odin
|
Example:
|
||||||
package hash_example
|
package hash_example
|
||||||
|
|
||||||
import "core:crypto/hash"
|
import "core:crypto/hash"
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
input := "Feed the fire."
|
input := "Feed the fire."
|
||||||
|
|
||||||
// Compute the digest, using the high level API.
|
// Compute the digest, using the high level API.
|
||||||
returned_digest := hash.hash(hash.Algorithm.SHA512_256, input)
|
returned_digest := hash.hash(hash.Algorithm.SHA512_256, input)
|
||||||
defer delete(returned_digest)
|
defer delete(returned_digest)
|
||||||
|
|
||||||
// Variant that takes a destination buffer, instead of returning
|
// Variant that takes a destination buffer, instead of returning
|
||||||
// the digest.
|
// the digest.
|
||||||
digest := make([]byte, hash.DIGEST_SIZES[hash.Algorithm.BLAKE2B]) // @note: Destination buffer has to be at least as big as the digest size of the hash.
|
digest := make([]byte, hash.DIGEST_SIZES[hash.Algorithm.BLAKE2B]) // @note: Destination buffer has to be at least as big as the digest size of the hash.
|
||||||
defer delete(digest)
|
defer delete(digest)
|
||||||
hash.hash(hash.Algorithm.BLAKE2B, input, digest)
|
hash.hash(hash.Algorithm.BLAKE2B, input, digest)
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
A generic low level API is provided supporting the init/update/final interface
|
A generic low level API is provided supporting the init/update/final interface
|
||||||
that is typical with cryptographic hash function implementations.
|
that is typical with cryptographic hash function implementations.
|
||||||
|
|
||||||
```odin
|
Example:
|
||||||
package hash_example
|
package hash_example
|
||||||
|
|
||||||
import "core:crypto/hash"
|
import "core:crypto/hash"
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
input := "Let the cinders burn."
|
input := "Let the cinders burn."
|
||||||
|
|
||||||
// Compute the digest, using the low level API.
|
// Compute the digest, using the low level API.
|
||||||
ctx: hash.Context
|
ctx: hash.Context
|
||||||
digest := make([]byte, hash.DIGEST_SIZES[hash.Algorithm.SHA3_512])
|
digest := make([]byte, hash.DIGEST_SIZES[hash.Algorithm.SHA3_512])
|
||||||
defer delete(digest)
|
defer delete(digest)
|
||||||
|
|
||||||
hash.init(&ctx, hash.Algorithm.SHA3_512)
|
hash.init(&ctx, hash.Algorithm.SHA3_512)
|
||||||
hash.update(&ctx, transmute([]byte)input)
|
hash.update(&ctx, transmute([]byte)input)
|
||||||
hash.final(&ctx, digest)
|
hash.final(&ctx, digest)
|
||||||
}
|
}
|
||||||
```
|
|
||||||
*/
|
*/
|
||||||
package crypto_hash
|
package crypto_hash
|
||||||
@@ -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,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
package hkdf implements the HKDF HMAC-based Extract-and-Expand Key
|
package hkdf implements the HKDF HMAC-based Extract-and-Expand Key
|
||||||
Derivation Function.
|
Derivation Function.
|
||||||
|
|
||||||
See: https://www.rfc-editor.org/rfc/rfc5869
|
See: [[ https://www.rfc-editor.org/rfc/rfc5869 ]]
|
||||||
*/
|
*/
|
||||||
package hkdf
|
package hkdf
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
package hmac implements the HMAC MAC algorithm.
|
package hmac implements the HMAC MAC algorithm.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.198-1.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.198-1.pdf ]]
|
||||||
*/
|
*/
|
||||||
package hmac
|
package hmac
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
package kmac implements the KMAC MAC algorithm.
|
package kmac implements the KMAC MAC algorithm.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf ]]
|
||||||
*/
|
*/
|
||||||
package kmac
|
package kmac
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ WARNING: The MD5 algorithm is known to be insecure and should only be
|
|||||||
used for interoperating with legacy applications.
|
used for interoperating with legacy applications.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://eprint.iacr.org/2005/075
|
- [[ https://eprint.iacr.org/2005/075 ]]
|
||||||
- https://datatracker.ietf.org/doc/html/rfc1321
|
- [[ https://datatracker.ietf.org/doc/html/rfc1321 ]]
|
||||||
*/
|
*/
|
||||||
package md5
|
package md5
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ WARNING: The SHA1 algorithm is known to be insecure and should only be
|
|||||||
used for interoperating with legacy applications.
|
used for interoperating with legacy applications.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://eprint.iacr.org/2017/190
|
- [[ https://eprint.iacr.org/2017/190 ]]
|
||||||
- https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf ]]
|
||||||
- https://datatracker.ietf.org/doc/html/rfc3174
|
- [[ https://datatracker.ietf.org/doc/html/rfc3174 ]]
|
||||||
*/
|
*/
|
||||||
package sha1
|
package sha1
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
package pbkdf2 implements the PBKDF2 password-based key derivation function.
|
package pbkdf2 implements the PBKDF2 password-based key derivation function.
|
||||||
|
|
||||||
See: https://www.rfc-editor.org/rfc/rfc2898
|
See: [[ https://www.rfc-editor.org/rfc/rfc2898 ]]
|
||||||
*/
|
*/
|
||||||
package pbkdf2
|
package pbkdf2
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
package poly1305 implements the Poly1305 one-time MAC algorithm.
|
package poly1305 implements the Poly1305 one-time MAC algorithm.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://datatracker.ietf.org/doc/html/rfc8439
|
- [[ https://datatracker.ietf.org/doc/html/rfc8439 ]]
|
||||||
*/
|
*/
|
||||||
package poly1305
|
package poly1305
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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,7 +2,7 @@
|
|||||||
package ristretto255 implement the ristretto255 prime-order group.
|
package ristretto255 implement the ristretto255 prime-order group.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://www.rfc-editor.org/rfc/rfc9496
|
- [[ https://www.rfc-editor.org/rfc/rfc9496 ]]
|
||||||
*/
|
*/
|
||||||
package ristretto255
|
package ristretto255
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
package sha2 implements the SHA2 hash algorithm family.
|
package sha2 implements the SHA2 hash algorithm family.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf ]]
|
||||||
- https://datatracker.ietf.org/doc/html/rfc3874
|
- [[ https://datatracker.ietf.org/doc/html/rfc3874 ]]
|
||||||
*/
|
*/
|
||||||
package sha2
|
package sha2
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ pre-standardization Keccak algorithm is required, it can be found in
|
|||||||
crypto/legacy/keccak.
|
crypto/legacy/keccak.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf ]]
|
||||||
*/
|
*/
|
||||||
package sha3
|
package sha3
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ package shake implements the SHAKE and cSHAKE XOF algorithm families.
|
|||||||
The SHA3 hash algorithm can be found in the crypto/sha3.
|
The SHA3 hash algorithm can be found in the crypto/sha3.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf ]]
|
||||||
- https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf ]]
|
||||||
*/
|
*/
|
||||||
package shake
|
package shake
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
/*
|
||||||
|
package siphash Implements the SipHash hashing algorithm.
|
||||||
|
|
||||||
|
Use the specific procedures for a certain setup. The generic procedures will default to Siphash 2-4.
|
||||||
|
|
||||||
|
See:
|
||||||
|
- [[ https://github.com/veorq/SipHash ]]
|
||||||
|
- [[ https://www.aumasson.jp/siphash/siphash.pdf ]]
|
||||||
|
*/
|
||||||
package siphash
|
package siphash
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6,10 +15,6 @@ package siphash
|
|||||||
|
|
||||||
List of contributors:
|
List of contributors:
|
||||||
zhibog: Initial implementation.
|
zhibog: Initial implementation.
|
||||||
|
|
||||||
Implementation of the SipHash hashing algorithm, as defined at <https://github.com/veorq/SipHash> and <https://www.aumasson.jp/siphash/siphash.pdf>
|
|
||||||
|
|
||||||
Use the specific procedures for a certain setup. The generic procdedures will default to Siphash 2-4
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "core:crypto"
|
import "core:crypto"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
package sm3 implements the SM3 hash algorithm.
|
package sm3 implements the SM3 hash algorithm.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
|
- [[ https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02 ]]
|
||||||
*/
|
*/
|
||||||
package sm3
|
package sm3
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
package tuplehash implements the TupleHash and TupleHashXOF algorithms.
|
package tuplehash implements the TupleHash and TupleHashXOF algorithms.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf
|
- [[ https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf ]]
|
||||||
*/
|
*/
|
||||||
package tuplehash
|
package tuplehash
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package x25519 implements the X25519 (aka curve25519) Elliptic-Curve
|
|||||||
Diffie-Hellman key exchange protocol.
|
Diffie-Hellman key exchange protocol.
|
||||||
|
|
||||||
See:
|
See:
|
||||||
- https://www.rfc-editor.org/rfc/rfc7748
|
- [[ https://www.rfc-editor.org/rfc/rfc7748 ]]
|
||||||
*/
|
*/
|
||||||
package x25519
|
package x25519
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
//+build !windows !linux !darwin
|
#+build !windows
|
||||||
|
#+build !linux
|
||||||
|
#+build !darwin
|
||||||
package debug_trace
|
package debug_trace
|
||||||
|
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//+private
|
#+private
|
||||||
//+build windows
|
#+build windows
|
||||||
package debug_trace
|
package debug_trace
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ Package `core:dynlib` implements loading of shared libraries/DLLs and their symb
|
|||||||
The behaviour of dynamically loaded libraries is specific to the target platform of the program.
|
The behaviour of dynamically loaded libraries is specific to the target platform of the program.
|
||||||
For in depth detail on the underlying behaviour please refer to your target platform's documentation.
|
For in depth detail on the underlying behaviour please refer to your target platform's documentation.
|
||||||
|
|
||||||
See `example` directory for an example library exporting 3 symbols and a host program loading them automatically
|
For a full example, see: [[ core/dynlib/example; https://github.com/odin-lang/Odin/tree/master/core/dynlib/example ]]
|
||||||
by defining a symbol table struct.
|
|
||||||
*/
|
*/
|
||||||
package dynlib
|
package dynlib
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user