From 19ea0858c82c9219a6ddad2f3928fbc47edfb33d Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Fri, 30 Jun 2023 22:58:33 -0500 Subject: [PATCH] changed: heap functions are exported for libraries to use --- core/alloc/heap.onyx | 6 +++++ core/onyx/cbindgen.onyx | 19 +++++++++++---- docs/ideas/platform_layer.md | 16 ++++++++++++ shared/include/onyx_library.h | 46 +++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/core/alloc/heap.onyx b/core/alloc/heap.onyx index bc2c887e..992fd46b 100644 --- a/core/alloc/heap.onyx +++ b/core/alloc/heap.onyx @@ -52,6 +52,12 @@ get_freed_size :: () => { return total; } +#if !#defined(runtime.vars.Dont_Export_Heap_Functions) { + // heap_alloc is not exported because you can use __heap_resize(NULL, size) + #export "__heap_resize" heap_resize + #export "__heap_free" heap_free +} + #local { use core.intrinsics.wasm { memory_size, memory_grow, diff --git a/core/onyx/cbindgen.onyx b/core/onyx/cbindgen.onyx index f2802ead..0e7dc118 100644 --- a/core/onyx/cbindgen.onyx +++ b/core/onyx/cbindgen.onyx @@ -273,6 +273,10 @@ compile_c_file :: ( case "f32" do io.write_format(writer, " results->data[0] = WASM_F32_VAL({}({}));\n", method_name, call_str[0..call_str.count-2]); case "f64" do io.write_format(writer, " results->data[0] = WASM_F64_VAL({}({}));\n", method_name, call_str[0..call_str.count-2]); case "cptr" do io.write_format(writer, " results->data[0] = WASM_I64_VAL((int64_t) {}({}));\n", method_name, call_str[0..call_str.count-2]); + case "ptr" { + printf("Returning a pointer-like object from C to Onyx in '{}'.\nWhile this is not an error, be careful with what you are doing, as this pointer MUST be allocated in Onyx's memory space, not in external memory. Use cptr(...) if the memory lives elsewhere.\n\n", method_name); + io.write_format(writer, " int out = ONYX_UNPTR({}({}));\n results->data[0] = WASM_I32_VAL(out);\n", method_name, call_str[0..call_str.count-2]); + } } io.write_format(writer, " return NULL;\n"); @@ -297,18 +301,19 @@ compile_c_file :: ( case f32 do return "f32"; case f64 do return "f64"; - case rawptr do return "i32"; // This will have to depend on the pointer size... + case rawptr do return "ptr"; case i8x16, i16x8, i32x4, i64x2, f32x4, f64x2, v128 do return "v128"; case type_expr do return "i32"; } - case .Pointer do return "i32"; // This will also have to depend on the pointer size... - case .Multi_Pointer do return "i32"; // This will also have to depend on the pointer size... + case .Pointer do return "ptr"; + case .Multi_Pointer do return "ptr"; + case .Array do return "ptr"; + case .Function do assert(false, "Passing functions between wasm and c is not yet supported."); - case .Array do return "i32"; - case .Slice do assert(false, "ASDFASDF"); + case .Slice do assert(false, "Passing a slice from c to wasm is not yet supported."); case .Enum do return type_to_wasm_type((cast(&Type_Info_Enum) param_info).backing_type); case .Distinct do return type_to_wasm_type((cast(&Type_Info_Distinct) param_info).base_type); @@ -325,6 +330,10 @@ compile_c_file :: ( assert(false, "Passing structures between wasm and c is not yet supported."); } + + case .Union { + assert(false, "Passing unions between wasm and c is not yet supported."); + } } return ""; diff --git a/docs/ideas/platform_layer.md b/docs/ideas/platform_layer.md index de0b39a6..f74eeb05 100644 --- a/docs/ideas/platform_layer.md +++ b/docs/ideas/platform_layer.md @@ -27,6 +27,9 @@ this document will serve as that "header file" - `Supports_Networking :: bool` - `Supports_Type_Info :: bool` - `Supports_Threads :: bool` +- `Supports_Env_Vars :: bool` +- `Supports_Futexes :: bool` +- `Supports_TTY :: bool` ## Files @@ -132,4 +135,17 @@ this document will serve as that "header file" - `__get_env(key: str) -> str` +## Futexes + +### Procedures +- `__futex_wait(addr: rawptr, expected: i32, timeout: i32) -> i32` +- `__futex_wake(addr: rawptr, maximum: i32) -> i32` + + +## TTY + +### Procedures +- `__tty_get(state: &core.os.TTY_State) -> void` +- `__tty_set(state: &core.os.TTY_State) -> bool` + diff --git a/shared/include/onyx_library.h b/shared/include/onyx_library.h index feb859dd..ef4db7c8 100644 --- a/shared/include/onyx_library.h +++ b/shared/include/onyx_library.h @@ -1,3 +1,5 @@ +#ifndef ONYX_LIBRARY_H +#define ONYX_LIBRARY_H #include "wasm.h" @@ -102,3 +104,47 @@ typedef struct WasmFuncDefinition { #endif #define ONYX_PTR(p) ((void*) (p != 0 ? (runtime->wasm_memory_data(runtime->wasm_memory) + p) : NULL)) +#define ONYX_UNPTR(p) ((int) (p != NULL ? ((char *) p - runtime->wasm_memory_data(runtime->wasm_memory)) : 0)) + + +#ifdef ONYX_HEAP_FUNCTIONS + +static wasm_func_t* __onyx_heap_resize_function = NULL; +static void *__onyx_heap_resize(void* ptr, int size) { + if (__onyx_heap_resize_function == NULL) { + wasm_extern_t *__extern = runtime->wasm_extern_lookup_by_name(runtime->wasm_module, runtime->wasm_instance, "__heap_resize"); + __onyx_heap_resize_function = runtime->wasm_extern_as_func(__extern); + } + + int onyx_ptr = ONYX_UNPTR(ptr); + + wasm_val_t args[] = { WASM_I32_VAL(onyx_ptr), WASM_I32_VAL(size) }; + wasm_val_t results[1]; + wasm_val_vec_t args_arr = WASM_ARRAY_VEC(args); + wasm_val_vec_t results_arr = WASM_ARRAY_VEC(results); + + runtime->wasm_func_call(__onyx_heap_resize_function, &args_arr, &results_arr); + return ONYX_PTR(results[0].of.i32); +} + +static wasm_func_t* __onyx_heap_free_function = NULL; +static void __onyx_heap_free(void *ptr) { + if (__onyx_heap_free_function == NULL) { + wasm_extern_t *__extern = runtime->wasm_extern_lookup_by_name(runtime->wasm_module, runtime->wasm_instance, "__heap_free"); + __onyx_heap_free_function = runtime->wasm_extern_as_func(__extern); + } + + if (ptr == NULL) return; + int onyx_ptr = ONYX_UNPTR(ptr); + + wasm_val_t args[] = { WASM_I32_VAL(onyx_ptr) }; + wasm_val_vec_t results = {0,0}; + wasm_val_vec_t args_arr = WASM_ARRAY_VEC(args); + + runtime->wasm_func_call(__onyx_heap_free_function, &args_arr, &results); +} + + +#endif + +#endif -- 2.25.1