From: Brendan Hansen Date: Sat, 11 Dec 2021 21:26:12 +0000 (-0600) Subject: got onyx's filesystem working on windows; bugs on linux X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=580ffc7ab78f0b3c21f82f51961cfc1f891de304;p=onyx.git got onyx's filesystem working on windows; bugs on linux --- diff --git a/core/os/file.onyx b/core/os/file.onyx index 9795e64e..3705ba1f 100644 --- a/core/os/file.onyx +++ b/core/os/file.onyx @@ -4,18 +4,19 @@ use package core #local fs :: package runtime.fs FileError :: enum { - None; - NotFound; - Exists; - Permission; - BadFile; + None :: 0x00; + NotFound :: 0x01; + Exists :: 0x02; + Permission :: 0x03; + BadFile :: 0x04; + BadMode :: 0x05; } OpenMode :: enum { - Invalid; - Read; - Write; - Append; + Invalid :: 0x00; + Read :: 0x01; + Write :: 0x02; + Append :: 0x03; } File :: struct { diff --git a/core/os/onyx_fs.onyx b/core/os/onyx_fs.onyx index afd229cd..f176a528 100644 --- a/core/os/onyx_fs.onyx +++ b/core/os/onyx_fs.onyx @@ -5,7 +5,7 @@ use package core FileData :: struct { Handle :: #distinct i64 - handle: Handle; + handle: Handle = -1; } __file_open :: (path: str, mode := os.OpenMode.Read) -> (FileData, os.FileError) { @@ -16,62 +16,59 @@ __file_open :: (path: str, mode := os.OpenMode.Read) -> (FileData, os.FileError) return fd, error; } -#package { - #foreign "onyx_runtime" { - __file_open_impl :: (path: str, mode: os.OpenMode, out_handle: ^Handle) -> os.FileError --- +#foreign "onyx_runtime" { + __file_open_impl :: (path: str, mode: os.OpenMode, out_handle: ^FileData.Handle) -> os.FileError --- - __file_close :: (fd: FileData) -> os.FileError --- - __file_exists :: (path: str) -> bool --- + __file_close :: (fd: FileData) -> os.FileError --- + __file_exists :: (path: str) -> bool --- - __file_seek :: (handle: Handle, to: i32, whence: io.SeekFrom) -> io.Error --- - __file_tell :: (handle: Handle, out_position: ^u32) -> io.Error --- - __file_read :: (handle: Handle, output_buffer: [] u8, bytes_read: ^u32) -> io.Error --- - __file_write :: (handle: Handle, input_buffer: [] u8, bytes_wrote: ^u32) -> io.Error --- - __file_flush :: (handle: Handle) -> io.Error; - } + __file_seek :: (handle: FileData.Handle, to: i32, whence: io.SeekFrom) -> i32 --- + __file_tell :: (handle: FileData.Handle) -> u32 --- + __file_read :: (handle: FileData.Handle, output_buffer: [] u8, bytes_read: ^u64) -> io.Error --- + __file_write :: (handle: FileData.Handle, input_buffer: [] u8, bytes_wrote: ^u64) -> io.Error --- + __file_flush :: (handle: FileData.Handle) -> io.Error --- } __file_stream_vtable := io.Stream_Vtable.{ seek = (use fs: ^os.File, to: i32, whence: io.SeekFrom) -> io.Error { - return __file_seek(data.handle, to, whence); + now := __file_seek(data.handle, to, whence); + return (.None) if now >= 0 else .BadFile; }, tell = (use fs: ^os.File) -> (io.Error, u32) { - position: u32; - error := __file_tell(data.handle, ^position); - return error, position; + return .None, __file_tell(data.handle); }, read = (use fs: ^os.File, buffer: [] u8) -> (io.Error, u32) { - bytes_read: u32; + bytes_read: u64; error := __file_read(data.handle, buffer, ^bytes_read); - return error, bytes_read; + return error, ~~bytes_read; }, read_at = (use fs: ^os.File, at: u32, buffer: [] u8) -> (io.Error, u32) { __file_seek(data.handle, at, .Start); - bytes_read: u32; + bytes_read: u64; error := __file_read(data.handle, buffer, ^bytes_read); - return error, bytes_read; + return error, ~~bytes_read; }, read_byte = (use fs: ^os.File) -> (io.Error, u8) { byte: u8; error := __file_read(data.handle, ~~ cast([1] u8) ^byte, null); - return byte; + return error, byte; }, write = (use fs: ^os.File, buffer: [] u8) -> (io.Error, u32) { - bytes_wrote: u32; + bytes_wrote: u64; error := __file_write(data.handle, buffer, ^bytes_wrote); - return error, bytes_wrote; + return error, ~~bytes_wrote; }, write_at = (use fs: ^os.File, at: u32, buffer: [] u8) -> (io.Error, u32) { __file_seek(data.handle, at, .Start); - bytes_wrote: u32; + bytes_wrote: u64; error := __file_write(data.handle, buffer, ^bytes_wrote); - return error, bytes_wrote; + return error, ~~bytes_wrote; }, write_byte = (use fs: ^os.File, byte: u8) -> io.Error { diff --git a/core/std.onyx b/core/std.onyx index e951680e..04ece571 100644 --- a/core/std.onyx +++ b/core/std.onyx @@ -47,7 +47,8 @@ package core #if runtime.Runtime == runtime.Runtime_Onyx { #load "./runtime/onyx_run" - #load "core/os/process" + #load "./os/process" + #load "./os/onyx_fs" } #if runtime.Runtime == runtime.Runtime_Wasi { #load "./runtime/wasi" diff --git a/include/bh.h b/include/bh.h index 7483ff9c..66e86433 100644 --- a/include/bh.h +++ b/include/bh.h @@ -365,6 +365,7 @@ bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, const char* fi bh_file_error bh_file_new(bh_file* file, bh_file_descriptor fd, const char* filename); b32 bh_file_read_at(bh_file* file, i64 offset, void* buffer, isize buff_size, isize* bytes_read); b32 bh_file_write_at(bh_file* file, i64 offset, void const* buffer, isize buff_size, isize* bytes_wrote); +i64 bh_file_seek(bh_file* file, i64 offset, bh_file_whence whence); i64 bh_file_seek_to(bh_file* file, i64 offset); i64 bh_file_seek_to_end(bh_file* file); i64 bh_file_skip(bh_file* file, i64 bytes); @@ -372,6 +373,7 @@ i64 bh_file_tell(bh_file* file); bh_file_error bh_file_close(bh_file* file); i32 bh_file_read(bh_file* file, void* buffer, isize buff_size); i32 bh_file_write(bh_file* file, void* buffer, isize buff_size); +void bh_file_flush(bh_file* file); i64 bh_file_size(bh_file* file); b32 bh_file_exists(char const* filename); char* bh_path_get_full_name(char const* filename, bh_allocator a); @@ -1447,6 +1449,7 @@ b32 bh_file_write_at(bh_file* file, i64 offset, void const* buffer, isize buff_s bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_CURRENT, ¤t_offset); #if defined(_BH_WINDOWS) + if (current_offset != offset) bh_file_seek_to(file, offset); res = (isize) WriteFile(file->fd, buffer, buff_size, (i32 *) bytes_wrote, NULL); return res; @@ -1484,6 +1487,12 @@ static b32 bh__file_seek_wrapper(bh_file_descriptor fd, i64 offset, bh_file_when } // Returns new offset +i64 bh_file_seek(bh_file* file, i64 offset, bh_file_whence whence) { + i64 new_offset = -1; + bh__file_seek_wrapper(file->fd, offset, whence, &new_offset); + return new_offset; +} + i64 bh_file_seek_to(bh_file* file, i64 offset) { i64 new_offset = -1; bh__file_seek_wrapper(file->fd, offset, BH_FILE_WHENCE_BEGIN, &new_offset); @@ -1534,6 +1543,12 @@ b32 bh_file_write(bh_file* file, void* buffer, isize buff_size) { return bh_file_write_at(file, bh_file_tell(file), buffer, buff_size, NULL); } +void bh_file_flush(bh_file* file) { + #ifdef _BH_LINUX + fdatasync(file->fd); + #endif +} + i64 bh_file_size(bh_file* file) { i64 size = 0; i64 prev = bh_file_tell(file); diff --git a/modules/onyx_runtime/onyx_runtime.c b/modules/onyx_runtime/onyx_runtime.c index 7128cef4..f8d52d11 100644 --- a/modules/onyx_runtime/onyx_runtime.c +++ b/modules/onyx_runtime/onyx_runtime.c @@ -15,6 +15,133 @@ #include "types.h" // For POINTER_SIZE +#define ONYX_FILE_ERROR_NONE 0 +#define ONYX_FILE_ERROR_NOT_FOUND 1 +#define ONYX_FILE_ERROR_EXISTS 2 +#define ONYX_FILE_ERROR_PERMISSION 3 +#define ONYX_FILE_ERROR_BAD_FILE 4 +#define ONYX_FILE_ERROR_BAD_MODE 5 + +ONYX_DEF(__file_open_impl, (WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { + char *path_ptr = ONYX_PTR(params->data[0].of.i32); + int path_len = params->data[1].of.i32; + + char path[512] = {0}; + strncpy(path, path_ptr, path_len); + path[path_len] = 0; + + int mode = params->data[2].of.i32; + + bh_file_mode bh_mode; + switch (mode) { + case 1: bh_mode = BH_FILE_MODE_READ; break; + case 2: bh_mode = BH_FILE_MODE_WRITE; break; + case 3: bh_mode = BH_FILE_MODE_APPEND; break; + } + + bh_file file; + bh_file_error error = bh_file_open_mode(&file, bh_mode, path); + if (error == BH_FILE_ERROR_INVALID) { + results->data[0] = WASM_I32_VAL(ONYX_FILE_ERROR_NOT_FOUND); + return NULL; + } + + *(u64 *) ONYX_PTR(params->data[3].of.i32) = (u64) file.fd; + results->data[0] = WASM_I32_VAL(ONYX_FILE_ERROR_NONE); + return NULL; +} + +ONYX_DEF(__file_close, (WASM_I64), (WASM_I32)) { + i64 fd = params->data[0].of.i64; + + bh_file file = { (bh_file_descriptor) fd }; + bh_file_error error = bh_file_close(&file); + if (error == BH_FILE_ERROR_INVALID) { + results->data[0] = WASM_I32_VAL(ONYX_FILE_ERROR_NOT_FOUND); + return NULL; + } + + results->data[0] = WASM_I32_VAL(ONYX_FILE_ERROR_NONE); + return NULL; +} + +ONYX_DEF(__file_exists, (WASM_I32, WASM_I32), (WASM_I32)) { + char *path_ptr = ONYX_PTR(params->data[0].of.i32); + int path_len = params->data[1].of.i32; + + char path[512] = {0}; + strncpy(path, path_ptr, path_len); + path[path_len] = 0; + + results->data[0] = WASM_I32_VAL(bh_file_exists(path)); + return NULL; +} + +ONYX_DEF(__file_seek, (WASM_I64, WASM_I32, WASM_I32), (WASM_I32)) { + i64 fd = params->data[0].of.i64; + i32 offset = params->data[1].of.i32; + i32 whence = params->data[2].of.i32; + + bh_file file = { (bh_file_descriptor) fd }; + bh_file_whence bh_whence; + switch (whence) { + case 0: bh_whence = BH_FILE_WHENCE_BEGIN; break; + case 1: bh_whence = BH_FILE_WHENCE_CURRENT; break; + case 2: bh_whence = BH_FILE_WHENCE_END; break; + } + + i64 new_offset = bh_file_seek(&file, offset, whence); + results->data[0] = WASM_I32_VAL((i32) new_offset); + return NULL; +} + +ONYX_DEF(__file_tell, (WASM_I64), (WASM_I32)) { + i64 fd = params->data[0].of.i64; + bh_file file = { (bh_file_descriptor) fd }; + results->data[0] = WASM_I32_VAL(bh_file_tell(&file)); + return NULL; +} + +ONYX_DEF(__file_read, (WASM_I64, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { + i64 fd = params->data[0].of.i64; + bh_file file = { (bh_file_descriptor) fd }; + b32 success = bh_file_read_at(&file, + bh_file_tell(&file), + ONYX_PTR(params->data[1].of.i32), + params->data[2].of.i32, + (i64 *) ONYX_PTR(params->data[3].of.i32)); + + results->data[0] = WASM_I32_VAL(0); + if (!success) results->data[0] = WASM_I32_VAL(6); + return NULL; +} + +ONYX_DEF(__file_write, (WASM_I64, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) { + i64 fd = params->data[0].of.i64; + bh_file file = { (bh_file_descriptor) fd }; + b32 success = bh_file_write_at(&file, + bh_file_tell(&file), + ONYX_PTR(params->data[1].of.i32), + params->data[2].of.i32, + (i64 *) ONYX_PTR(params->data[3].of.i32)); + + results->data[0] = WASM_I32_VAL(0); + if (!success) results->data[0] = WASM_I32_VAL(6); + return NULL; +} + +ONYX_DEF(__file_flush, (WASM_I64), (WASM_I32)) { + i64 fd = params->data[0].of.i64; + bh_file file = { (bh_file_descriptor) fd }; + bh_file_flush(&file); + results->data[0] = WASM_I32_VAL(0); + return NULL; +} + + +// +// THREADS +// typedef struct OnyxThread { i32 id; i32 tls_base; @@ -143,6 +270,12 @@ ONYX_DEF(__kill_thread, (WASM_I32), (WASM_I32)) { return NULL; } + + + +// +// PROCESS +// #define ONYX_PROCESS_MAGIC_NUMBER 0xdeadfadebabecafe typedef struct OnyxProcess { u64 magic_number; @@ -458,6 +591,15 @@ ONYX_DEF(__process_destroy, (WASM_I64), ()) { } ONYX_LIBRARY { + ONYX_FUNC(__file_open_impl) + ONYX_FUNC(__file_close) + ONYX_FUNC(__file_exists) + ONYX_FUNC(__file_seek) + ONYX_FUNC(__file_tell) + ONYX_FUNC(__file_read) + ONYX_FUNC(__file_write) + ONYX_FUNC(__file_flush) + ONYX_FUNC(__spawn_thread) ONYX_FUNC(__kill_thread)