Merge branch 'master' into fract_trunc_classify_#1574

Resolve conflicts with [9848e88] & sameify Makefile & tests/common/common.odin
This commit is contained in:
gitlost
2022-03-09 16:09:04 +00:00
26 changed files with 1375 additions and 1037 deletions
-1
View File
@@ -14,7 +14,6 @@ package siphash
import "core:crypto"
import "core:crypto/util"
import "core:mem"
/*
High level API
+27
View File
@@ -0,0 +1,27 @@
/*
Implementation of the LEB128 variable integer encoding as used by DWARF encoding and DEX files, among others.
Author of this Odin package: Jeroen van Rijn
Example:
```odin
import "core:encoding/varint"
import "core:fmt"
main :: proc() {
buf: [varint.LEB128_MAX_BYTES]u8
value := u128(42)
encode_size, encode_err := varint.encode_uleb128(buf[:], value)
assert(encode_size == 1 && encode_err == .None)
fmt.println(buf[:encode_size])
decoded_val, decode_size, decode_err := varint.decode_uleb128(buf[:encode_size])
assert(decoded_val == value && decode_size == encode_size && decode_err == .None)
}
```
*/
package varint
+139
View File
@@ -0,0 +1,139 @@
/*
Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license.
List of contributors:
Jeroen van Rijn: Initial implementation.
*/
// package varint implements variable length integer encoding and decoding using
// the LEB128 format as used by DWARF debug info, Android .dex and other file formats.
package varint
import "core:fmt"
// In theory we should use the bigint package. In practice, varints bigger than this indicate a corrupted file.
// Instead we'll set limits on the values we'll encode/decode
// 18 * 7 bits = 126, which means that a possible 19th byte may at most be `0b0000_0011`.
LEB128_MAX_BYTES :: 19
Error :: enum {
None = 0,
Buffer_Too_Small = 1,
Value_Too_Large = 2,
}
// Decode a slice of bytes encoding an unsigned LEB128 integer into value and number of bytes used.
// Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes.
decode_uleb128 :: proc(buf: []u8) -> (val: u128, size: int, err: Error) {
more := true
for v, i in buf {
size = i + 1
// 18 * 7 bits = 126, which means that a possible 19th byte may at most be 0b0000_0011.
if size > LEB128_MAX_BYTES || size == LEB128_MAX_BYTES && v > 0b0000_0011 {
return 0, 0, .Value_Too_Large
}
val |= u128(v & 0x7f) << uint(i * 7)
if v < 128 {
more = false
break
}
}
// If the buffer runs out before the number ends, return an error.
if more {
return 0, 0, .Buffer_Too_Small
}
return
}
// Decode a slice of bytes encoding a signed LEB128 integer into value and number of bytes used.
// Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes.
decode_ileb128 :: proc(buf: []u8) -> (val: i128, size: int, err: Error) {
shift: uint
if len(buf) == 0 {
return 0, 0, .Buffer_Too_Small
}
for v in buf {
size += 1
// 18 * 7 bits = 126, which including sign means we can have a 19th byte.
if size > LEB128_MAX_BYTES || size == LEB128_MAX_BYTES && v > 0x7f {
return 0, 0, .Value_Too_Large
}
val |= i128(v & 0x7f) << shift
shift += 7
if v < 128 { break }
}
if buf[size - 1] & 0x40 == 0x40 {
val |= max(i128) << shift
}
return
}
// Encode `val` into `buf` as an unsigned LEB128 encoded series of bytes.
// `buf` must be appropriately sized.
encode_uleb128 :: proc(buf: []u8, val: u128) -> (size: int, err: Error) {
val := val
for {
size += 1
if size > len(buf) {
fmt.println(val, buf[:size - 1])
return 0, .Buffer_Too_Small
}
low := val & 0x7f
val >>= 7
if val > 0 {
low |= 0x80 // more bytes to follow
}
buf[size - 1] = u8(low)
if val == 0 { break }
}
return
}
@(private)
SIGN_MASK :: (i128(1) << 121) // sign extend mask
// Encode `val` into `buf` as a signed LEB128 encoded series of bytes.
// `buf` must be appropriately sized.
encode_ileb128 :: proc(buf: []u8, val: i128) -> (size: int, err: Error) {
val := val
more := true
for more {
size += 1
if size > len(buf) {
return 0, .Buffer_Too_Small
}
low := val & 0x7f
val >>= 7
low = (low ~ SIGN_MASK) - SIGN_MASK
if (val == 0 && low & 0x40 != 0x40) || (val == -1 && low & 0x40 == 0x40) {
more = false
} else {
low |= 0x80
}
buf[size - 1] = u8(low)
}
return
}
+1
View File
@@ -680,6 +680,7 @@ make_directory :: proc(path: string, mode: u32 = 0o775) -> Errno {
}
exit :: proc "contextless" (code: int) -> ! {
runtime._cleanup_runtime_contextless()
_unix_exit(i32(code))
}
+1
View File
@@ -419,6 +419,7 @@ set_current_directory :: proc(path: string) -> (err: Errno) {
}
exit :: proc "contextless" (code: int) -> ! {
runtime._cleanup_runtime_contextless()
_unix_exit(c.int(code))
}
+1
View File
@@ -802,6 +802,7 @@ set_current_directory :: proc(path: string) -> (err: Errno) {
}
exit :: proc "contextless" (code: int) -> ! {
runtime._cleanup_runtime_contextless()
_unix_exit(c.int(code))
}
+2 -1
View File
@@ -2,9 +2,9 @@ package os
foreign import libc "system:c"
import "core:runtime"
import "core:strings"
import "core:c"
import "core:runtime"
Handle :: distinct i32
Pid :: distinct i32
@@ -658,6 +658,7 @@ set_current_directory :: proc(path: string) -> (err: Errno) {
}
exit :: proc "contextless" (code: int) -> ! {
runtime._cleanup_runtime_contextless()
_unix_exit(c.int(code))
}
+2
View File
@@ -1,6 +1,7 @@
package os
import "core:sys/wasm/wasi"
import "core:runtime"
Handle :: distinct i32
Errno :: distinct i32
@@ -93,5 +94,6 @@ heap_free :: proc(ptr: rawptr) {
exit :: proc "contextless" (code: int) -> ! {
runtime._cleanup_runtime_contextless()
wasi.proc_exit(wasi.exitcode_t(code))
}
+2
View File
@@ -2,6 +2,7 @@
package os
import win32 "core:sys/windows"
import "core:runtime"
Handle :: distinct uintptr
File_Time :: distinct u64
@@ -128,6 +129,7 @@ get_page_size :: proc() -> int {
exit :: proc "contextless" (code: int) -> ! {
runtime._cleanup_runtime_contextless()
win32.ExitProcess(win32.DWORD(code))
}
+5
View File
@@ -459,6 +459,11 @@ _cleanup_runtime :: proc() {
default_temp_allocator_destroy(&global_default_temp_allocator_data)
}
_cleanup_runtime_contextless :: proc "contextless" () {
context = default_context()
_cleanup_runtime()
}
/////////////////////////////
/////////////////////////////