mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-17 00:11:25 -07:00
Merge pull request #4208 from laytan/more-wasm-vendor-support
wasm: support more vendor libraries
This commit is contained in:
@@ -334,7 +334,7 @@ Inputs:
|
||||
Returns:
|
||||
- index: The index of the byte `c`, or -1 if it was not found.
|
||||
*/
|
||||
index_byte :: proc(s: []byte, c: byte) -> (index: int) #no_bounds_check {
|
||||
index_byte :: proc "contextless" (s: []byte, c: byte) -> (index: int) #no_bounds_check {
|
||||
i, l := 0, len(s)
|
||||
|
||||
// Guard against small strings. On modern systems, it is ALWAYS
|
||||
@@ -469,7 +469,7 @@ Inputs:
|
||||
Returns:
|
||||
- index: The index of the byte `c`, or -1 if it was not found.
|
||||
*/
|
||||
last_index_byte :: proc(s: []byte, c: byte) -> int #no_bounds_check {
|
||||
last_index_byte :: proc "contextless" (s: []byte, c: byte) -> int #no_bounds_check {
|
||||
i := len(s)
|
||||
|
||||
// Guard against small strings. On modern systems, it is ALWAYS
|
||||
|
||||
@@ -2277,3 +2277,81 @@ buddy_allocator_proc :: proc(
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// An allocator that keeps track of allocation sizes and passes it along to resizes.
|
||||
// This is useful if you are using a library that needs an equivalent of `realloc` but want to use
|
||||
// the Odin allocator interface.
|
||||
//
|
||||
// You want to wrap your allocator into this one if you are trying to use any allocator that relies
|
||||
// on the old size to work.
|
||||
//
|
||||
// The overhead of this allocator is an extra max(alignment, size_of(Header)) bytes allocated for each allocation, these bytes are
|
||||
// used to store the size and original pointer.
|
||||
Compat_Allocator :: struct {
|
||||
parent: Allocator,
|
||||
}
|
||||
|
||||
compat_allocator_init :: proc(rra: ^Compat_Allocator, allocator := context.allocator) {
|
||||
rra.parent = allocator
|
||||
}
|
||||
|
||||
compat_allocator :: proc(rra: ^Compat_Allocator) -> Allocator {
|
||||
return Allocator{
|
||||
data = rra,
|
||||
procedure = compat_allocator_proc,
|
||||
}
|
||||
}
|
||||
|
||||
compat_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int,
|
||||
location := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
size, old_size := size, old_size
|
||||
|
||||
Header :: struct {
|
||||
size: int,
|
||||
ptr: rawptr,
|
||||
}
|
||||
|
||||
rra := (^Compat_Allocator)(allocator_data)
|
||||
switch mode {
|
||||
case .Alloc, .Alloc_Non_Zeroed:
|
||||
a := max(alignment, size_of(Header))
|
||||
size += a
|
||||
assert(size >= 0, "overflow")
|
||||
|
||||
allocation := rra.parent.procedure(rra.parent.data, mode, size, alignment, old_memory, old_size, location) or_return
|
||||
#no_bounds_check data = allocation[a:]
|
||||
|
||||
([^]Header)(raw_data(data))[-1] = {
|
||||
size = size,
|
||||
ptr = raw_data(allocation),
|
||||
}
|
||||
return
|
||||
|
||||
case .Free:
|
||||
header := ([^]Header)(old_memory)[-1]
|
||||
return rra.parent.procedure(rra.parent.data, mode, size, alignment, header.ptr, header.size, location)
|
||||
|
||||
case .Resize, .Resize_Non_Zeroed:
|
||||
header := ([^]Header)(old_memory)[-1]
|
||||
|
||||
a := max(alignment, size_of(header))
|
||||
size += a
|
||||
assert(size >= 0, "overflow")
|
||||
|
||||
allocation := rra.parent.procedure(rra.parent.data, mode, size, alignment, header.ptr, header.size, location) or_return
|
||||
#no_bounds_check data = allocation[a:]
|
||||
|
||||
([^]Header)(raw_data(data))[-1] = {
|
||||
size = size,
|
||||
ptr = raw_data(allocation),
|
||||
}
|
||||
return
|
||||
|
||||
case .Free_All, .Query_Info, .Query_Features:
|
||||
return rra.parent.procedure(rra.parent.data, mode, size, alignment, old_memory, old_size, location)
|
||||
|
||||
case: unreachable()
|
||||
}
|
||||
}
|
||||
|
||||
+19
-70
@@ -3,33 +3,38 @@ package os
|
||||
|
||||
import "base:runtime"
|
||||
|
||||
foreign import "odin_env"
|
||||
|
||||
@(require_results)
|
||||
is_path_separator :: proc(c: byte) -> bool {
|
||||
return c == '/' || c == '\\'
|
||||
}
|
||||
|
||||
Handle :: distinct u32
|
||||
|
||||
stdout: Handle = 1
|
||||
stderr: Handle = 2
|
||||
|
||||
@(require_results)
|
||||
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Error) {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
close :: proc(fd: Handle) -> Error {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
return nil
|
||||
}
|
||||
|
||||
flush :: proc(fd: Handle) -> (err: Error) {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
write :: proc(fd: Handle, data: []byte) -> (int, Error) {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
read_console :: proc(handle: Handle, b: []byte) -> (n: int, err: Error) {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
foreign odin_env {
|
||||
@(link_name="write")
|
||||
_write :: proc "contextless" (fd: Handle, p: []byte) ---
|
||||
}
|
||||
_write(fd, data)
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
read :: proc(fd: Handle, data: []byte) -> (int, Error) {
|
||||
@@ -45,19 +50,6 @@ file_size :: proc(fd: Handle) -> (i64, Error) {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
|
||||
@(private)
|
||||
MAX_RW :: 1<<30
|
||||
|
||||
@(private)
|
||||
pread :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
@(private)
|
||||
pwrite :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
@@ -65,16 +57,6 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error)
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
stdout: Handle = 1
|
||||
stderr: Handle = 2
|
||||
|
||||
@(require_results)
|
||||
get_std_handle :: proc "contextless" (h: uint) -> Handle {
|
||||
context = runtime.default_context()
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
|
||||
@(require_results)
|
||||
exists :: proc(path: string) -> bool {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
@@ -90,9 +72,6 @@ is_dir :: proc(path: string) -> bool {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
// NOTE(tetra): GetCurrentDirectory is not thread safe with SetCurrentDirectory and GetFullPathName
|
||||
//@private cwd_lock := win32.SRWLOCK{} // zero is initialized
|
||||
|
||||
@(require_results)
|
||||
get_current_directory :: proc(allocator := context.allocator) -> string {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
@@ -118,18 +97,6 @@ remove_directory :: proc(path: string) -> (err: Error) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@(private, require_results)
|
||||
is_abs :: proc(path: string) -> bool {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
@(private, require_results)
|
||||
fix_long_path :: proc(path: string) -> string {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
|
||||
link :: proc(old_name, new_name: string) -> (err: Error) {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
@@ -169,7 +136,6 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
Handle :: distinct uintptr
|
||||
File_Time :: distinct u64
|
||||
|
||||
_Platform_Error :: enum i32 {
|
||||
@@ -254,12 +220,7 @@ WSAECONNRESET :: Platform_Error.WSAECONNRESET
|
||||
ERROR_FILE_IS_PIPE :: General_Error.File_Is_Pipe
|
||||
ERROR_FILE_IS_NOT_DIR :: General_Error.Not_Dir
|
||||
|
||||
// "Argv" arguments converted to Odin strings
|
||||
args := _alloc_command_line_arguments()
|
||||
|
||||
|
||||
|
||||
|
||||
args: []string
|
||||
|
||||
@(require_results)
|
||||
last_write_time :: proc(fd: Handle) -> (File_Time, Error) {
|
||||
@@ -279,26 +240,14 @@ get_page_size :: proc() -> int {
|
||||
|
||||
@(private, require_results)
|
||||
_processor_core_count :: proc() -> int {
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
return 1
|
||||
}
|
||||
|
||||
exit :: proc "contextless" (code: int) -> ! {
|
||||
context = runtime.default_context()
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
unimplemented_contextless("core:os procedure not supported on JS target")
|
||||
}
|
||||
|
||||
|
||||
|
||||
@(require_results)
|
||||
current_thread_id :: proc "contextless" () -> int {
|
||||
context = runtime.default_context()
|
||||
unimplemented("core:os procedure not supported on JS target")
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
@(require_results)
|
||||
_alloc_command_line_arguments :: proc() -> []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ Inputs:
|
||||
Returns:
|
||||
- res: A string created from the null-terminated byte pointer and length
|
||||
*/
|
||||
string_from_null_terminated_ptr :: proc(ptr: [^]byte, len: int) -> (res: string) {
|
||||
string_from_null_terminated_ptr :: proc "contextless" (ptr: [^]byte, len: int) -> (res: string) {
|
||||
s := string(ptr[:len])
|
||||
s = truncate_to_byte(s, 0)
|
||||
return s
|
||||
@@ -139,7 +139,7 @@ NOTE: Failure to find the byte results in returning the entire string.
|
||||
Returns:
|
||||
- res: The truncated string
|
||||
*/
|
||||
truncate_to_byte :: proc(str: string, b: byte) -> (res: string) {
|
||||
truncate_to_byte :: proc "contextless" (str: string, b: byte) -> (res: string) {
|
||||
n := index_byte(str, b)
|
||||
if n < 0 {
|
||||
n = len(str)
|
||||
@@ -261,7 +261,7 @@ Inputs:
|
||||
Returns:
|
||||
- result: `-1` if `lhs` comes first, `1` if `rhs` comes first, or `0` if they are equal
|
||||
*/
|
||||
compare :: proc(lhs, rhs: string) -> (result: int) {
|
||||
compare :: proc "contextless" (lhs, rhs: string) -> (result: int) {
|
||||
return mem.compare(transmute([]byte)lhs, transmute([]byte)rhs)
|
||||
}
|
||||
/*
|
||||
@@ -1447,7 +1447,7 @@ Output:
|
||||
-1
|
||||
|
||||
*/
|
||||
index_byte :: proc(s: string, c: byte) -> (res: int) {
|
||||
index_byte :: proc "contextless" (s: string, c: byte) -> (res: int) {
|
||||
return #force_inline bytes.index_byte(transmute([]u8)s, c)
|
||||
}
|
||||
/*
|
||||
@@ -1482,7 +1482,7 @@ Output:
|
||||
-1
|
||||
|
||||
*/
|
||||
last_index_byte :: proc(s: string, c: byte) -> (res: int) {
|
||||
last_index_byte :: proc "contextless" (s: string, c: byte) -> (res: int) {
|
||||
return #force_inline bytes.last_index_byte(transmute([]u8)s, c)
|
||||
}
|
||||
/*
|
||||
@@ -1576,8 +1576,8 @@ Output:
|
||||
-1
|
||||
|
||||
*/
|
||||
index :: proc(s, substr: string) -> (res: int) {
|
||||
hash_str_rabin_karp :: proc(s: string) -> (hash: u32 = 0, pow: u32 = 1) {
|
||||
index :: proc "contextless" (s, substr: string) -> (res: int) {
|
||||
hash_str_rabin_karp :: proc "contextless" (s: string) -> (hash: u32 = 0, pow: u32 = 1) {
|
||||
for i := 0; i < len(s); i += 1 {
|
||||
hash = hash*PRIME_RABIN_KARP + u32(s[i])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user