#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 {
FileData :: struct {
Handle :: #distinct i64
- handle: Handle;
+ handle: Handle = -1;
}
__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 {
#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"
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);
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);
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;
}
// 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);
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);
#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;
return NULL;
}
+
+
+
+//
+// PROCESS
+//
#define ONYX_PROCESS_MAGIC_NUMBER 0xdeadfadebabecafe
typedef struct OnyxProcess {
u64 magic_number;
}
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)