diff --git a/examples/hello_c/hello.c b/examples/hello_c/hello.c index 6a1e4b4..5364273 100644 --- a/examples/hello_c/hello.c +++ b/examples/hello_c/hello.c @@ -4,23 +4,37 @@ #include #include #include +#include #define PROTOCOL_FUNCTION __attribute__((import_module("typst_env"))) extern "C" #else #include #include #include +#include #define PROTOCOL_FUNCTION __attribute__((import_module("typst_env"))) extern #endif +// === +// Functions for the protocol + PROTOCOL_FUNCTION void wasm_minimal_protocol_send_result_to_host(const uint8_t *ptr, size_t len); PROTOCOL_FUNCTION void wasm_minimal_protocol_write_args_to_buffer(uint8_t *ptr); +EMSCRIPTEN_KEEPALIVE void wasm_minimal_protocol_free_byte_buffer(uint8_t *ptr, + size_t len) { + free(ptr); +} + +// === + EMSCRIPTEN_KEEPALIVE int32_t hello(void) { - const char message[] = "Hello world !"; - wasm_minimal_protocol_send_result_to_host((uint8_t *)message, - sizeof(message) - 1); + const char static_message[] = "Hello world !"; + const size_t length = sizeof(static_message); + char *message = malloc(length); + memcpy((void *)message, (void *)static_message, length); + wasm_minimal_protocol_send_result_to_host((uint8_t *)message, length - 1); return 0; } @@ -36,7 +50,6 @@ int32_t double_it(size_t arg_len) { alloc_result[arg_len + i] = alloc_result[i]; } wasm_minimal_protocol_send_result_to_host(alloc_result, result_len); - free(alloc_result); return 0; } @@ -66,7 +79,6 @@ int32_t concatenate(size_t arg1_len, size_t arg2_len) { wasm_minimal_protocol_send_result_to_host(result, total_len + 1); - free(result); free(args); return 0; } @@ -102,24 +114,27 @@ int32_t shuffle(size_t arg1_len, size_t arg2_len, size_t arg3_len) { wasm_minimal_protocol_send_result_to_host(result, result_len); - free(result); free(args); return 0; } EMSCRIPTEN_KEEPALIVE int32_t returns_ok() { - const char message[] = "This is an `Ok`"; - wasm_minimal_protocol_send_result_to_host((uint8_t *)message, - sizeof(message) - 1); + const char static_message[] = "This is an `Ok`"; + const size_t length = sizeof(static_message); + char *message = malloc(length); + memcpy((void *)message, (void *)static_message, length); + wasm_minimal_protocol_send_result_to_host((uint8_t *)message, length - 1); return 0; } EMSCRIPTEN_KEEPALIVE int32_t returns_err() { - const char message[] = "This is an `Err`"; - wasm_minimal_protocol_send_result_to_host((uint8_t *)message, - sizeof(message) - 1); + const char static_message[] = "This is an `Err`"; + const size_t length = sizeof(static_message); + char *message = malloc(length); + memcpy((void *)message, (void *)static_message, length); + wasm_minimal_protocol_send_result_to_host((uint8_t *)message, length - 1); return 1; } diff --git a/examples/hello_zig/hello.zig b/examples/hello_zig/hello.zig index cd92a95..b6bfdf9 100644 --- a/examples/hello_zig/hello.zig +++ b/examples/hello_zig/hello.zig @@ -1,23 +1,36 @@ const std = @import("std"); const allocator = std.heap.page_allocator; +// === +// Functions for the protocol + extern "typst_env" fn wasm_minimal_protocol_send_result_to_host(ptr: [*]const u8, len: usize) void; extern "typst_env" fn wasm_minimal_protocol_write_args_to_buffer(ptr: [*]u8) void; +export fn wasm_minimal_protocol_free_byte_buffer(ptr: [*]u8, len: usize) void { + var slice: []u8 = undefined; + slice.ptr = ptr; + slice.len = len; + allocator.free(slice); +} + +// === + export fn hello() i32 { const message = "Hello world !"; - wasm_minimal_protocol_send_result_to_host(message.ptr, message.len); + var result = allocator.alloc(u8, message.len) catch return 1; + @memcpy(result, message); + wasm_minimal_protocol_send_result_to_host(result.ptr, result.len); return 0; } export fn double_it(arg1_len: usize) i32 { - var alloc_result = allocator.alloc(u8, arg1_len * 2) catch return 1; - defer allocator.free(alloc_result); - wasm_minimal_protocol_write_args_to_buffer(alloc_result.ptr); + var result = allocator.alloc(u8, arg1_len * 2) catch return 1; + wasm_minimal_protocol_write_args_to_buffer(result.ptr); for (0..arg1_len) |i| { - alloc_result[i + arg1_len] = alloc_result[i]; + result[i + arg1_len] = result[i]; } - wasm_minimal_protocol_send_result_to_host(alloc_result.ptr, alloc_result.len); + wasm_minimal_protocol_send_result_to_host(result.ptr, result.len); return 0; } @@ -27,7 +40,6 @@ export fn concatenate(arg1_len: usize, arg2_len: usize) i32 { wasm_minimal_protocol_write_args_to_buffer(args.ptr); var result = allocator.alloc(u8, arg1_len + arg2_len + 1) catch return 1; - defer allocator.free(result); for (0..arg1_len) |i| { result[i] = args[i]; } @@ -49,27 +61,30 @@ export fn shuffle(arg1_len: usize, arg2_len: usize, arg3_len: usize) i32 { var arg2 = args[arg1_len .. arg1_len + arg2_len]; var arg3 = args[arg1_len + arg2_len .. args.len]; - var result: std.ArrayList(u8) = std.ArrayList(u8).initCapacity(allocator, args_len + 2) catch return 1; - defer result.deinit(); - result.appendSlice(arg3) catch return 1; - result.append('-') catch return 1; - result.appendSlice(arg1) catch return 1; - result.append('-') catch return 1; - result.appendSlice(arg2) catch return 1; + var result = allocator.alloc(u8, arg1_len + arg2_len + arg3_len + 2) catch return 1; + @memcpy(result[0..arg3.len], arg3); + result[arg3.len] = '-'; + @memcpy(result[arg3.len + 1 ..][0..arg1.len], arg1); + result[arg3.len + arg1.len + 1] = '-'; + @memcpy(result[arg3.len + arg1.len + 2 ..][0..arg2.len], arg2); - wasm_minimal_protocol_send_result_to_host(result.items.ptr, result.items.len); + wasm_minimal_protocol_send_result_to_host(result.ptr, result.len); return 0; } export fn returns_ok() i32 { const message = "This is an `Ok`"; - wasm_minimal_protocol_send_result_to_host(message.ptr, message.len); + var result = allocator.alloc(u8, message.len) catch return 1; + @memcpy(result, message); + wasm_minimal_protocol_send_result_to_host(result.ptr, result.len); return 0; } export fn returns_err() i32 { const message = "This is an `Err`"; - wasm_minimal_protocol_send_result_to_host(message.ptr, message.len); + var result = allocator.alloc(u8, message.len) catch return 1; + @memcpy(result, message); + wasm_minimal_protocol_send_result_to_host(result.ptr, result.len); return 1; }