added experimental cptr feature
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 9 Mar 2022 02:44:20 +0000 (20:44 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 9 Mar 2022 02:44:20 +0000 (20:44 -0600)
core/onyx/cptr.onyx [new file with mode: 0644]
core/onyx/fs.onyx [new file with mode: 0644]
core/os/onyx_fs.onyx [deleted file]
core/std.onyx
modules/onyx_runtime/onyx_runtime.c
tests/struct_use_pointer_member

diff --git a/core/onyx/cptr.onyx b/core/onyx/cptr.onyx
new file mode 100644 (file)
index 0000000..d5e97df
--- /dev/null
@@ -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 (file)
index 0000000..0585cb4
--- /dev/null
@@ -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 (file)
index 0585cb4..0000000
+++ /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);
-    },
-};
-
index 4c672e32f170108eae5c865939a9f3872a1392a3..83d6aaf95824f36da53d436cce0ad402d314af03 100644 (file)
@@ -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"
index 9e348dc15361c57b24ec9bd9a20b684f4dc83ad5..f3527c35e9513ea534e4d38c048eb7194baa917f 100644 (file)
@@ -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
 };
index a8fbd54615d01de00fd7857d373a150f8b8faa65..6d70f1cf45897b592898b850f3a610e9b11f6e77 100644 (file)
@@ -1,2 +1,2 @@
 Hello, I am Billy!
-Go away!! func[9]
+Go away!! func[17]