aboutsummaryrefslogtreecommitdiff
path: root/mirai.old/invocations/kata/postman.zig
diff options
context:
space:
mode:
Diffstat (limited to 'mirai.old/invocations/kata/postman.zig')
-rw-r--r--mirai.old/invocations/kata/postman.zig80
1 files changed, 80 insertions, 0 deletions
diff --git a/mirai.old/invocations/kata/postman.zig b/mirai.old/invocations/kata/postman.zig
new file mode 100644
index 0000000..6bea674
--- /dev/null
+++ b/mirai.old/invocations/kata/postman.zig
@@ -0,0 +1,80 @@
+//! Postman invocation - Letter passing between parent and child Kata
+
+const copy = @import("../../utils/mem/copy.zig");
+const handler = @import("../handler.zig");
+const heap = @import("../../memory/heap.zig");
+const int = @import("../../utils/types/int.zig");
+const kata_constants = @import("../../common/constants/kata.zig");
+const kata_limits = @import("../../common/limits/kata.zig");
+const kata_mod = @import("../../kata/kata.zig");
+const memory_limits = @import("../../common/limits/memory.zig");
+const result = @import("../../utils/types/result.zig");
+const sensei = @import("../../kata/sensei/sensei.zig");
+const slice = @import("../../utils/mem/slice.zig");
+
+pub fn invoke(ctx: *handler.InvocationContext) void {
+ switch (ctx.rdi) {
+ kata_constants.POSTMAN_SEND => send_letter(ctx),
+ kata_constants.POSTMAN_READ => read_letter(ctx),
+ else => result.set_error(ctx),
+ }
+}
+
+fn send_letter(ctx: *handler.InvocationContext) void {
+ const letter_type = int.u8_of(ctx.rsi);
+ const data_ptr = ctx.rdx;
+ const data_len = int.u16_of(ctx.r10);
+
+ if (data_len > kata_limits.MAX_LETTER_LENGTH) return result.set_error(ctx);
+ if (data_len > 0 and !memory_limits.is_valid_kata_pointer(data_ptr)) return result.set_error(ctx);
+
+ const sender = sensei.get_current_kata() orelse return result.set_error(ctx);
+ const parent = kata_mod.get_kata(sender.parent_id) orelse return result.set_error(ctx);
+
+ parent.letter_type = letter_type;
+ parent.letter_len = data_len;
+
+ if (data_len > 0) {
+ if (parent.letter_capacity < data_len) {
+ if (parent.letter_data) |old| {
+ heap.free(@ptrCast(old), parent.letter_capacity);
+ }
+ const new_buf = heap.alloc(data_len) orelse return result.set_error(ctx);
+ parent.letter_data = new_buf;
+ parent.letter_capacity = data_len;
+ }
+ copy.from_ptr(parent.letter_data.?[0..data_len], data_ptr, data_len);
+ }
+
+ result.set_ok(ctx);
+}
+
+fn read_letter(ctx: *handler.InvocationContext) void {
+ const buffer_ptr = ctx.rsi;
+ const buffer_len = ctx.rdx;
+
+ const kata = sensei.get_current_kata() orelse return result.set_error(ctx);
+
+ if (kata.letter_type == kata_constants.LETTER_NONE) {
+ return result.set_value(ctx, 0);
+ }
+
+ if (kata.letter_len > 0) {
+ if (!memory_limits.is_valid_kata_pointer(buffer_ptr)) return result.set_error(ctx);
+ if (kata.letter_len > buffer_len) return result.set_error(ctx);
+
+ if (kata.letter_data) |data| {
+ copy.to_ptr(buffer_ptr, data[0..kata.letter_len]);
+ }
+
+ if (kata.letter_len < buffer_len) {
+ slice.byte_ptr(buffer_ptr)[kata.letter_len] = 0;
+ }
+ }
+
+ const letter_type = kata.letter_type;
+ kata.letter_type = kata_constants.LETTER_NONE;
+ kata.letter_len = 0;
+
+ result.set_value(ctx, letter_type);
+}