--- /dev/null
+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.
+ //
+ }
+}
--- /dev/null
+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);
+ },
+};
+
+++ /dev/null
-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);
- },
-};
-
#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"
}
+
+
+//
+// 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)
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
};
Hello, I am Billy!
-Go away!! func[9]
+Go away!! func[17]