From: Brendan Hansen Date: Wed, 31 Aug 2022 02:52:57 +0000 (-0500) Subject: improvements to cbindgen and cptr X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=c78581c5b20679dec6d887fe48d5768fc7b0168f;p=onyx.git improvements to cbindgen and cptr --- diff --git a/core/onyx/cbindgen.onyx b/core/onyx/cbindgen.onyx index 01ec30ae..76c67282 100644 --- a/core/onyx/cbindgen.onyx +++ b/core/onyx/cbindgen.onyx @@ -231,8 +231,8 @@ compile_c_file :: ( print_body :: (writer, method_name, method_info, cast_map) => { use runtime.info; - call := io.dynamic_string_stream_make(); - defer io.dynamic_string_stream_free(^call); + call := io.buffer_stream_make(); + defer io.buffer_stream_free(^call); callw := io.writer_make(^call); param_num := 0; @@ -261,20 +261,21 @@ compile_c_file :: ( param_num += 1; } - call_str := call->to_str(); - wasm_return_type := type_to_wasm_type(method_info.return_type); + call_str := io.buffer_stream_to_str(^call); + wasm_return_type := type_to_wasm_type(method_info.return_type, for_return=true); switch wasm_return_type { - case "" do io.write_format(writer, " {}({});\n", method_name, call_str[0..call_str.count-2]); - case "i32" do io.write_format(writer, " results->data[0] = WASM_I32_VAL({}({}));\n", method_name, call_str[0..call_str.count-2]); - case "i64" do io.write_format(writer, " results->data[0] = WASM_I64_VAL({}({}));\n", method_name, call_str[0..call_str.count-2]); - 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 "" do io.write_format(writer, " {}({});\n", method_name, call_str[0..call_str.count-2]); + case "i32" do io.write_format(writer, " results->data[0] = WASM_I32_VAL({}({}));\n", method_name, call_str[0..call_str.count-2]); + case "i64" do io.write_format(writer, " results->data[0] = WASM_I64_VAL({}({}));\n", method_name, call_str[0..call_str.count-2]); + 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]); } io.write_format(writer, " return NULL;\n"); } - type_to_wasm_type :: (t: type_expr) -> str { + type_to_wasm_type :: (t: type_expr, for_return := false) -> str { use runtime.info; param_info := get_type_info(t); @@ -309,6 +310,11 @@ compile_c_file :: ( case .Struct { s_info := cast(^Type_Info_Struct) param_info; + + if s_info.constructed_from == cptr && for_return { + return "cptr"; + } + if s_info.members.count == 1 { return type_to_wasm_type(s_info.members[0].type); } diff --git a/core/onyx/cptr.onyx b/core/onyx/cptr.onyx index d8e91311..f1713f00 100644 --- a/core/onyx/cptr.onyx +++ b/core/onyx/cptr.onyx @@ -24,6 +24,14 @@ cptr :: struct (T: type_expr) { read_i32 :: (this: cptr(i32)) => cast(i32) __cptr_read_u32(this.data); read_i64 :: (this: cptr(i64)) => cast(i64) __cptr_read_u64(this.data); + // When given a non-zero-sized dest, this procedure + // fills the dest buffer with the contents of the string + // up to the number bytes in the dest buffer. This + // procedure returns the length of the string as given + // by strlen(). This exists because iterating byte by byte + // using __cptr_read_u8 would be slow compared to strlen(). + extract_str :: (this: cptr(u8), dest: [] u8) => __cptr_extract_str(this.data, dest); + to_rawptr :: (this: cptr($T)) -> ^T { // I'm treating NULL as more of a concept, than as an actual value here, // because if something returns a NULL pointer, it should logically map @@ -50,12 +58,13 @@ cptr :: struct (T: type_expr) { #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 --- + __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 --- + __cptr_extract_str :: (x: u64, dest: [] u8) -> u32 --- // // The equivalent write instructions are pusposefully left out. diff --git a/src/onyx_runtime.c b/src/onyx_runtime.c index 8a7473e8..893e6989 100644 --- a/src/onyx_runtime.c +++ b/src/onyx_runtime.c @@ -1341,6 +1341,16 @@ ONYX_DEF(__cptr_read_u64, (WASM_I64), (WASM_I64)) { return NULL; } +ONYX_DEF(__cptr_extract_str, (WASM_I64, WASM_I32, WASM_I32), (WASM_I32)) { + unsigned int len = strlen((char *) params->data[0].of.i64); + + if (params->data[2].of.i32 != 0) { + strncpy(ONYX_PTR(params->data[1].of.i32), (char *) params->data[0].of.i64, params->data[2].of.i32); + } + + results->data[0] = WASM_I32_VAL(len); + return NULL; +} ONYX_LIBRARY { ONYX_FUNC(__file_open_impl) @@ -1409,6 +1419,7 @@ ONYX_LIBRARY { ONYX_FUNC(__cptr_read_u16) ONYX_FUNC(__cptr_read_u32) ONYX_FUNC(__cptr_read_u64) + ONYX_FUNC(__cptr_extract_str) NULL };