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;
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);
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);
}
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
#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.
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)
ONYX_FUNC(__cptr_read_u16)
ONYX_FUNC(__cptr_read_u32)
ONYX_FUNC(__cptr_read_u64)
+ ONYX_FUNC(__cptr_extract_str)
NULL
};