From: Brendan Hansen Date: Wed, 9 Mar 2022 02:44:20 +0000 (-0600) Subject: added experimental cptr feature X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=d275a95e95794e9b2024937dcdcb4980e5af3ed5;p=onyx.git added experimental cptr feature --- diff --git a/core/onyx/cptr.onyx b/core/onyx/cptr.onyx new file mode 100644 index 00000000..d5e97df0 --- /dev/null +++ b/core/onyx/cptr.onyx @@ -0,0 +1,42 @@ +package core + +cptr :: struct (T: type_expr) { + data: u64; + + make :: (ptr: ^$T) -> cptr(T) { + return .{ __cptr_make(ptr) }; + } + + read :: (this: cptr($T)) -> T { + buf: [sizeof T] u8; + __cptr_read(this.data, ~~buf, sizeof T); + return *cast(^T) buf; + } + + read_u8 :: (this: cptr(u8)) => __cptr_read_u8(this.data); + read_u16 :: (this: cptr(u16)) => __cptr_read_u16(this.data); + read_u32 :: (this: cptr(u32)) => __cptr_read_u32(this.data); + read_u64 :: (this: cptr(u64)) => __cptr_read_u64(this.data); + read_i8 :: (this: cptr(i8)) => cast(i8) __cptr_read_u8(this.data); + read_i16 :: (this: cptr(i16)) => cast(i16) __cptr_read_u16(this.data); + read_i32 :: (this: cptr(i32)) => cast(i32) __cptr_read_u32(this.data); + read_i64 :: (this: cptr(i64)) => cast(i64) __cptr_read_u64(this.data); +} + +#local { + #foreign "onyx_runtime" { + __cptr_make :: (x: rawptr) -> u64 --- + __cptr_read :: (x: u64, dest: rawptr, size: u32) -> void --- + __cptr_read_u8 :: (x: u64) -> u8 --- + __cptr_read_u16 :: (x: u64) -> u16 --- + __cptr_read_u32 :: (x: u64) -> u32 --- + __cptr_read_u64 :: (x: u64) -> u64 --- + + // + // The equivalent write instructions are pusposefully left out. + // Until a VERY CONVINCING REASON as to why the must be included + // arises, having them in is more of a security vulnerability than + // I want to have. + // + } +} diff --git a/core/onyx/fs.onyx b/core/onyx/fs.onyx new file mode 100644 index 00000000..0585cb42 --- /dev/null +++ b/core/onyx/fs.onyx @@ -0,0 +1,101 @@ +package runtime.fs + +use package core + +FileData :: struct { + Handle :: #distinct i64 + + handle: Handle = -1; +} + +DirectoryData :: #distinct u64 + +__file_open :: (path: str, mode := os.OpenMode.Read) -> (FileData, os.FileError) { + handle: FileData.Handle; + error := __file_open_impl(path, mode, ^handle); + + fd := FileData.{ handle }; + return fd, error; +} + +#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_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_size :: (handle: FileData.Handle) -> u32 --- + + __dir_open :: (path: str, dir: ^DirectoryData) -> bool --- + __dir_close :: (dir: DirectoryData) -> void --- + __dir_read :: (dir: DirectoryData, out_entry: ^os.DirectoryEntry) -> bool --- +} + +__file_stream_vtable := io.Stream_Vtable.{ + seek = (use fs: ^os.File, to: i32, whence: io.SeekFrom) -> io.Error { + now := __file_seek(data.handle, to, whence); + return (.None) if now >= 0 else .BadFile; + }, + + tell = (use fs: ^os.File) -> (io.Error, u32) { + return .None, __file_tell(data.handle); + }, + + read = (use fs: ^os.File, buffer: [] u8) -> (io.Error, u32) { + bytes_read: u64; + error := __file_read(data.handle, buffer, ^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: u64; + error := __file_read(data.handle, buffer, ^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 error, byte; + }, + + write = (use fs: ^os.File, buffer: [] u8) -> (io.Error, u32) { + bytes_wrote: u64; + error := __file_write(data.handle, buffer, ^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: u64; + error := __file_write(data.handle, buffer, ^bytes_wrote); + return error, ~~bytes_wrote; + }, + + write_byte = (use fs: ^os.File, byte: u8) -> io.Error { + b := byte; + bytes_wrote: u64; + error := __file_write(data.handle, .{ ^b, 1 }, ^bytes_wrote); + return error; + }, + + close = (use fs: ^os.File) -> io.Error { + __file_close(data); + return .None; + }, + + flush = (use fs: ^os.File) -> io.Error { + return __file_flush(data.handle); + }, + + size = (use fs: ^os.File) -> i32 { + return __file_size(data.handle); + }, +}; + diff --git a/core/os/onyx_fs.onyx b/core/os/onyx_fs.onyx deleted file mode 100644 index 0585cb42..00000000 --- a/core/os/onyx_fs.onyx +++ /dev/null @@ -1,101 +0,0 @@ -package runtime.fs - -use package core - -FileData :: struct { - Handle :: #distinct i64 - - handle: Handle = -1; -} - -DirectoryData :: #distinct u64 - -__file_open :: (path: str, mode := os.OpenMode.Read) -> (FileData, os.FileError) { - handle: FileData.Handle; - error := __file_open_impl(path, mode, ^handle); - - fd := FileData.{ handle }; - return fd, error; -} - -#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_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_size :: (handle: FileData.Handle) -> u32 --- - - __dir_open :: (path: str, dir: ^DirectoryData) -> bool --- - __dir_close :: (dir: DirectoryData) -> void --- - __dir_read :: (dir: DirectoryData, out_entry: ^os.DirectoryEntry) -> bool --- -} - -__file_stream_vtable := io.Stream_Vtable.{ - seek = (use fs: ^os.File, to: i32, whence: io.SeekFrom) -> io.Error { - now := __file_seek(data.handle, to, whence); - return (.None) if now >= 0 else .BadFile; - }, - - tell = (use fs: ^os.File) -> (io.Error, u32) { - return .None, __file_tell(data.handle); - }, - - read = (use fs: ^os.File, buffer: [] u8) -> (io.Error, u32) { - bytes_read: u64; - error := __file_read(data.handle, buffer, ^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: u64; - error := __file_read(data.handle, buffer, ^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 error, byte; - }, - - write = (use fs: ^os.File, buffer: [] u8) -> (io.Error, u32) { - bytes_wrote: u64; - error := __file_write(data.handle, buffer, ^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: u64; - error := __file_write(data.handle, buffer, ^bytes_wrote); - return error, ~~bytes_wrote; - }, - - write_byte = (use fs: ^os.File, byte: u8) -> io.Error { - b := byte; - bytes_wrote: u64; - error := __file_write(data.handle, .{ ^b, 1 }, ^bytes_wrote); - return error; - }, - - close = (use fs: ^os.File) -> io.Error { - __file_close(data); - return .None; - }, - - flush = (use fs: ^os.File) -> io.Error { - return __file_flush(data.handle); - }, - - size = (use fs: ^os.File) -> i32 { - return __file_size(data.handle); - }, -}; - diff --git a/core/std.onyx b/core/std.onyx index 4c672e32..83d6aaf9 100644 --- a/core/std.onyx +++ b/core/std.onyx @@ -49,10 +49,12 @@ package core #if runtime.runtime == .Onyx { #load "./runtime/onyx_run" #load "./os/process" - #load "./os/onyx_fs" #load "./net/net" #load "./net/tcp" + + #load "./onyx/fs" + #load "./onyx/cptr" } #if runtime.runtime == .Wasi { #load "./wasi/wasi" diff --git a/modules/onyx_runtime/onyx_runtime.c b/modules/onyx_runtime/onyx_runtime.c index 9e348dc1..f3527c35 100644 --- a/modules/onyx_runtime/onyx_runtime.c +++ b/modules/onyx_runtime/onyx_runtime.c @@ -1018,6 +1018,45 @@ ONYX_DEF(__net_address_get_port, (WASM_I64), (WASM_I32)) { } + + +// +// C-Pointers +// +// These are wildly unsafe and break the core principles of the security +// of WebAssembly, so there should be a way to turn them off! +// +ONYX_DEF(__cptr_make, (WASM_I32), (WASM_I64)) { + wasm_val_init_ptr(&results->data[0], ONYX_PTR(params->data[0].of.i32)); + return NULL; +} + +ONYX_DEF(__cptr_read, (WASM_I64, WASM_I32, WASM_I32), ()) { + memcpy(ONYX_PTR(params->data[1].of.i32), (void *) params->data[0].of.i64, params->data[2].of.i32); + return NULL; +} + +ONYX_DEF(__cptr_read_u8, (WASM_I64), (WASM_I32)) { + results->data[0] = WASM_I32_VAL(*(u8 *) params->data[0].of.i64); + return NULL; +} + +ONYX_DEF(__cptr_read_u16, (WASM_I64), (WASM_I32)) { + results->data[0] = WASM_I32_VAL(*(u16 *) params->data[0].of.i64); + return NULL; +} + +ONYX_DEF(__cptr_read_u32, (WASM_I64), (WASM_I32)) { + results->data[0] = WASM_I32_VAL(*(u32 *) params->data[0].of.i64); + return NULL; +} + +ONYX_DEF(__cptr_read_u64, (WASM_I64), (WASM_I64)) { + results->data[0] = WASM_I64_VAL(*(u64 *) params->data[0].of.i64); + return NULL; +} + + ONYX_LIBRARY { ONYX_FUNC(__file_open_impl) ONYX_FUNC(__file_close) @@ -1064,5 +1103,12 @@ ONYX_LIBRARY { ONYX_FUNC(__net_address_get_address) ONYX_FUNC(__net_address_get_port) + ONYX_FUNC(__cptr_make) + ONYX_FUNC(__cptr_read) + ONYX_FUNC(__cptr_read_u8) + ONYX_FUNC(__cptr_read_u16) + ONYX_FUNC(__cptr_read_u32) + ONYX_FUNC(__cptr_read_u64) + NULL }; diff --git a/tests/struct_use_pointer_member b/tests/struct_use_pointer_member index a8fbd546..6d70f1cf 100644 --- a/tests/struct_use_pointer_member +++ b/tests/struct_use_pointer_member @@ -1,2 +1,2 @@ Hello, I am Billy! -Go away!! func[9] +Go away!! func[17]