diff --git a/toolchain/ifc/backend/c-mpc/backend.c b/toolchain/ifc/backend/c-mpc/backend.c index dc2ec80..09a9daa 100644 --- a/toolchain/ifc/backend/c-mpc/backend.c +++ b/toolchain/ifc/backend/c-mpc/backend.c @@ -12,6 +12,7 @@ struct emit_ctx { b_stream *ctx_out; + size_t ctx_max_handle_params; }; static void emit(struct emit_ctx *ctx, const char *format, ...) @@ -77,18 +78,24 @@ static int emit_header_lib_impl(struct emit_ctx *ctx) emit(ctx, "kern_status_t msg_recv_generic(\n"); emit_indent(ctx); emit(ctx, - "kern_handle_t channel,\nmsgid_t *out_id,\nstruct msg_header " - "*out_hdr)\n"); + "kern_handle_t channel,\nstruct msg_endpoint *out_sender,\nstruct " + "msg_header *out_hdr,\nkern_msg_handle_t *out_handles,\nsize_t " + "out_handles_max)\n"); emit_unindent(ctx); emit(ctx, "{\n"); emit_indent(ctx); /* clang-format off */ emit(ctx, - "struct iovec iov = IOVEC(out_hdr, sizeof *out_hdr);\n" - "kern_status_t status = msg_recv(channel, out_id, &iov, 1);\n" + "kern_iovec_t iov = IOVEC(out_hdr, sizeof *out_hdr);\n" + "kern_msg_t msg = { .msg_data = &iov, .msg_data_count = 1, " + ".msg_handles = out_handles, .msg_handles_count = out_handles_max };\n" + "kern_status_t status = msg_recv(channel, &msg);\n" "if (status != KERN_OK) return status;\n" "if (out_hdr->hdr_magic != MSG_MAGIC) return KERN_INVALID_ARGUMENT;\n" + "out_sender->e_task = msg.msg_sender;\n" + "out_sender->e_port = msg.msg_endpoint;\n" + "out_sender->e_msg = msg.msg_id;\n" "return KERN_OK;\n"); /* clang-format on */ emit_unindent(ctx); @@ -97,17 +104,17 @@ static int emit_header_lib_impl(struct emit_ctx *ctx) emit(ctx, "kern_status_t msg_read_generic(\n"); emit_indent(ctx); emit(ctx, - "kern_handle_t channel,\nmsgid_t id,\nstruct msg_header " - "*out_hdr)\n"); + "kern_handle_t channel,\nconst struct msg_endpoint *sender,\n" + "struct msg_header *out_hdr)\n"); emit_unindent(ctx); emit(ctx, "{\n"); emit_indent(ctx); /* clang-format off */ emit(ctx, - "struct iovec iov = IOVEC(out_hdr, sizeof *out_hdr);\n" + "kern_iovec_t iov = IOVEC(out_hdr, sizeof *out_hdr);\n" "size_t r = 0;\n" - "kern_status_t status = msg_read(channel, id, 0, &iov, 1, &r);\n" + "kern_status_t status = msg_read(channel, sender->e_msg, 0, &iov, 1, &r);\n" "if (status != KERN_OK) return status;\n" "if (r != sizeof *out_hdr) return KERN_INVALID_ARGUMENT;\n" "if (out_hdr->hdr_magic != MSG_MAGIC) return KERN_INVALID_ARGUMENT;\n" @@ -120,8 +127,8 @@ static int emit_header_lib_impl(struct emit_ctx *ctx) emit(ctx, "kern_status_t msg_reply_generic(\n"); emit_indent(ctx); emit(ctx, - "kern_handle_t channel,\nmsgid_t id,\nconst struct msg_header " - "*msg, uint16_t status)\n"); + "kern_handle_t channel,\nconst struct msg_endpoint *sender,\n" + "const struct msg_header *msg_data,\nuint16_t status)\n"); emit_unindent(ctx); emit(ctx, "{\n"); emit_indent(ctx); @@ -135,17 +142,18 @@ static int emit_header_lib_impl(struct emit_ctx *ctx) emit_unindent(ctx); emit(ctx, "};\n"); emit(ctx, - "if (msg) {\n"); + "if (msg_data) {\n"); emit_indent(ctx); emit(ctx, - "resp_data.hdr_protocol = msg->hdr_protocol;\n" - "resp_data.hdr_func = msg->hdr_func;\n"); + "resp_data.hdr_protocol = msg_data->hdr_protocol;\n" + "resp_data.hdr_func = msg_data->hdr_func;\n"); emit_unindent(ctx); emit(ctx, "}\n"); emit(ctx, - "struct iovec iov = IOVEC(&resp_data, sizeof resp_data);\n" - "return msg_reply(channel, id, &iov, 1);\n"); + "kern_iovec_t iov = IOVEC(&resp_data, sizeof resp_data);\n" + "kern_msg_t reply = { .msg_data = &iov, .msg_data_count = 1 };\n" + "return msg_reply(channel, sender->e_msg, &reply);\n"); /* clang-format on */ emit_unindent(ctx); @@ -165,6 +173,16 @@ static int emit_header_lib_definitions(struct emit_ctx *ctx) emit(ctx, "#define MSG_MAGIC 0x9AB07D10U\n\n"); + emit(ctx, "struct msg_endpoint {\n"); + emit_indent(ctx); + + emit(ctx, "tid_t e_task;\n"); + emit(ctx, "koid_t e_port;\n"); + emit(ctx, "msgid_t e_msg;\n"); + + emit_unindent(ctx); + emit(ctx, "};\n\n"); + emit(ctx, "struct msg_header {\n"); emit_indent(ctx); @@ -189,25 +207,23 @@ static int emit_header_lib_definitions(struct emit_ctx *ctx) emit(ctx, "extern kern_status_t msg_recv_generic(\n"); emit_indent(ctx); emit(ctx, - "kern_handle_t channel,\nmsgid_t *out_id,\nstruct msg_header " - "*out_hdr);\n", - NULL); + "kern_handle_t channel,\nstruct msg_endpoint *out_sender,\nstruct " + "msg_header *out_hdr,\nkern_msg_handle_t *out_handles,\nsize_t " + "out_handles_max);\n"); emit_unindent(ctx); emit(ctx, "extern kern_status_t msg_read_generic(\n"); emit_indent(ctx); emit(ctx, - "kern_handle_t channel,\nmsgid_t id,\nstruct msg_header " - "*out_hdr);\n", - NULL); + "kern_handle_t channel,\nconst struct msg_endpoint *sender,\n" + "struct msg_header *out_hdr);\n"); emit_unindent(ctx); emit(ctx, "extern kern_status_t msg_reply_generic(\n"); emit_indent(ctx); emit(ctx, - "kern_handle_t channel,\nmsgid_t id,\nconst struct msg_header " - "*msg, uint16_t status);\n", - NULL); + "kern_handle_t channel,\nconst struct msg_endpoint *sender,\n" + "const struct msg_header *msg_data, uint16_t status);\n"); emit_unindent(ctx); emit(ctx, "#if defined(MSG_IMPLEMENTATION)\n\n"); @@ -218,6 +234,42 @@ static int emit_header_lib_definitions(struct emit_ctx *ctx) return 0; } +static size_t get_msg_handle_params(const struct msg_definition *msg) +{ + size_t count = 0; + b_queue_entry *entry = b_queue_first(&msg->msg_params); + while (entry) { + const struct msg_parameter *param + = b_unbox(struct msg_parameter, entry, p_entry); + if (param->p_type->ty_id == TYPE_HANDLE) { + count++; + } + + entry = b_queue_next(entry); + } + + return count; +} + +static size_t get_max_handle_params(const struct interface_definition *iface) +{ + size_t count = 0; + b_queue_entry *entry = b_queue_first(&iface->if_msg); + while (entry) { + const struct msg_definition *msg + = b_unbox(struct msg_definition, entry, msg_entry); + size_t msg_count = get_msg_handle_params(msg); + + if (msg_count > count) { + count = msg_count; + } + + entry = b_queue_next(entry); + } + + return count; +} + static int emit_interface_id_macros( struct emit_ctx *ctx, const struct interface_definition *iface) @@ -279,6 +331,9 @@ static int emit_msg_struct_member( case TYPE_INT: emit(ctx, "uint32_t %s;\n", param->p_name); break; + case TYPE_HANDLE: + emit(ctx, "kern_handle_t %s;\n", param->p_name); + break; case TYPE_STRING: emit(ctx, "uint16_t %s_offset;\n", param->p_name); emit(ctx, "uint16_t %s_len;\n", param->p_name); @@ -405,22 +460,25 @@ static int emit_interface_msg_function_send_impl( b_string_toupper(msg_ucase); emit(ctx, - "struct msg_%s_%s msg = {0};\n", + "struct msg_%s_%s msg_data = {0};\n", iface->if_name, msg->msg_name); - emit(ctx, "msg.msg_header.hdr_magic = MSG_MAGIC;\n"); + emit(ctx, "msg_data.msg_header.hdr_magic = MSG_MAGIC;\n"); emit(ctx, - "msg.msg_header.hdr_protocol = PROTOCOL_%s;\n", + "msg_data.msg_header.hdr_protocol = PROTOCOL_%s;\n", b_string_ptr(iface_ucase)); emit(ctx, - "msg.msg_header.hdr_func = MSG_%s_%s;\n\n", + "msg_data.msg_header.hdr_func = MSG_%s_%s;\n\n", b_string_ptr(iface_ucase), b_string_ptr(msg_ucase)); b_string_unref(iface_ucase); b_string_unref(msg_ucase); - emit(ctx, "uint16_t offset = sizeof msg;\n\n"); + emit(ctx, "uint16_t offset = sizeof msg_data;\n\n"); + + size_t nr_req_handles = 0; + size_t nr_resp_handles = 0; b_queue_entry *entry = b_queue_first(&msg->msg_params); while (entry) { @@ -429,20 +487,27 @@ static int emit_interface_msg_function_send_impl( switch (param->p_type->ty_id) { case TYPE_INT: emit(ctx, - "msg.msg_request.%s = %s;\n\n", + "msg_data.msg_request.%s = %s;\n\n", param->p_name, param->p_name); break; + case TYPE_HANDLE: + emit(ctx, + "msg_data.msg_request.%s = %zu;\n", + param->p_name, + nr_req_handles); + nr_req_handles++; + break; case TYPE_STRING: emit(ctx, - "msg.msg_request.%s_offset = offset;\n", + "msg_data.msg_request.%s_offset = offset;\n", param->p_name); emit(ctx, - "msg.msg_request.%s_len = strlen(%s);\n", + "msg_data.msg_request.%s_len = strlen(%s);\n", param->p_name, param->p_name); emit(ctx, - "offset += msg.msg_request.%s_len;\n", + "offset += msg_data.msg_request.%s_len;\n", param->p_name); break; default: @@ -459,10 +524,13 @@ static int emit_interface_msg_function_send_impl( switch (param->p_type->ty_id) { case TYPE_STRING: emit(ctx, - "msg.msg_request.%s_max = out_%s->str_max;\n", + "msg_data.msg_request.%s_max = out_%s->str_max;\n", param->p_name, param->p_name); break; + case TYPE_HANDLE: + nr_resp_handles++; + break; default: break; } @@ -470,9 +538,9 @@ static int emit_interface_msg_function_send_impl( entry = b_queue_next(entry); } - emit(ctx, "struct iovec req_iov[] = {\n"); + emit(ctx, "kern_iovec_t req_iov[] = {\n"); emit_indent(ctx); - emit(ctx, "IOVEC(&msg, sizeof msg),\n"); + emit(ctx, "IOVEC(&msg_data, sizeof msg_data),\n"); size_t nr_req_iov = 1; entry = b_queue_first(&msg->msg_params); @@ -485,7 +553,7 @@ static int emit_interface_msg_function_send_impl( } emit(ctx, - "IOVEC(%s, msg.msg_request.%s_len),\n", + "IOVEC(%s, msg_data.msg_request.%s_len),\n", param->p_name, param->p_name); @@ -496,9 +564,15 @@ static int emit_interface_msg_function_send_impl( emit_unindent(ctx); emit(ctx, "};\n\n"); - emit(ctx, "struct iovec resp_iov[] = {\n"); + if (nr_req_handles) { + emit(ctx, + "kern_msg_handle_t req_handles[%zu] = {0};\n", + nr_req_handles); + } + + emit(ctx, "kern_iovec_t resp_iov[] = {\n"); emit_indent(ctx); - emit(ctx, "IOVEC(&msg, sizeof msg),\n"); + emit(ctx, "IOVEC(&msg_data, sizeof msg_data),\n"); size_t nr_resp_iov = 1; entry = b_queue_first(&msg->msg_results); @@ -522,8 +596,46 @@ static int emit_interface_msg_function_send_impl( emit_unindent(ctx); emit(ctx, "};\n\n"); - emit(ctx, "kern_status_t status = msg_send(port, req_iov, %zu, resp_iov, %zu);\n", nr_req_iov, nr_resp_iov); + if (nr_resp_handles) { + emit(ctx, + "kern_msg_handle_t resp_handles[%zu] = {0};\n", + nr_resp_handles); + } + + emit(ctx, "kern_msg_t msg = {\n"); + emit_indent(ctx); + emit(ctx, ".msg_data = req_iov,\n.msg_data_count = %zu,\n", nr_req_iov); + + if (nr_req_handles) { + emit(ctx, + ".msg_handles = req_handles,\n.msg_handles_count = %zu.", + nr_req_handles); + } + + emit_unindent(ctx); + emit(ctx, "};\n\n"); + + emit(ctx, "kern_msg_t reply = {\n"); + emit_indent(ctx); + emit(ctx, + ".msg_data = resp_iov,\n.msg_data_count = %zu,\n", + nr_resp_iov); + + if (nr_resp_handles) { + emit(ctx, + ".msg_handles = resp_handles,\n.msg_handles_count = " + "%zu,\n", + nr_resp_handles); + } + + emit_unindent(ctx); + emit(ctx, "};\n\n"); + + emit(ctx, "kern_status_t status = msg_send(port, &msg, &reply);\n"); emit(ctx, "if (status != KERN_OK) return status;\n\n"); + emit(ctx, + "if (msg_data.msg_header.hdr_status != KERN_OK) return " + "msg_data.msg_header.hdr_status;\n\n"); entry = b_queue_first(&msg->msg_results); while (entry) { @@ -532,7 +644,8 @@ static int emit_interface_msg_function_send_impl( switch (param->p_type->ty_id) { case TYPE_STRING: emit(ctx, - "out_%s->str_len = msg.msg_response.%s_len;\n", + "out_%s->str_len = " + "msg_data.msg_response.%s_len;\n", param->p_name, param->p_name); emit(ctx, @@ -545,12 +658,24 @@ static int emit_interface_msg_function_send_impl( param->p_name, param->p_name); break; + case TYPE_HANDLE: + emit(ctx, "*out_%s = ", param->p_name); + emit(ctx, + "msg_data.msg_response.%s < %zu ", + param->p_name, + nr_resp_handles); + emit(ctx, + "? " + "resp_handles[msg_data.msg_response.%s].hnd_" + "value ", + param->p_name); + emit(ctx, ": KERN_HANDLE_INVALID;\n"); + break; default: emit(ctx, - "*out_%s = msg.msg_response.%s;\n", + "*out_%s = msg_data.msg_response.%s;\n", param->p_name, param->p_name); - break; } @@ -566,16 +691,20 @@ static int emit_interface_msg_function_recv_impl( const struct interface_definition *iface, const struct msg_definition *msg) { - emit(ctx, "struct msg_%s_%s msg;\n", iface->if_name, msg->msg_name); - emit(ctx, "struct iovec iov = IOVEC(&msg, sizeof msg);\n"); + emit(ctx, + "struct msg_%s_%s msg_data;\n", + iface->if_name, + msg->msg_name); + emit(ctx, "kern_iovec_t iov = IOVEC(&msg_data, sizeof msg_data);\n"); emit(ctx, "size_t r = 0;\n\n"); emit(ctx, - "kern_status_t status = msg_read(channel, id, 0, &iov, 1, " - "&r);\n"); + "kern_status_t status = msg_read(channel, sender->e_msg, 0, &iov, " + "1, &r);\n"); emit(ctx, "if (status != KERN_OK) return status;\n"); - emit(ctx, "if (r != sizeof msg) return KERN_INVALID_ARGUMENT;\n\n"); + emit(ctx, + "if (r != sizeof msg_data) return KERN_INVALID_ARGUMENT;\n\n"); b_queue_entry *entry = b_queue_first(&msg->msg_params); while (entry) { @@ -584,13 +713,23 @@ static int emit_interface_msg_function_recv_impl( switch (param->p_type->ty_id) { case TYPE_INT: emit(ctx, - "*out_%s = msg.msg_request.%s;\n", + "*out_%s = msg_data.msg_request.%s;\n", param->p_name, param->p_name); break; + case TYPE_HANDLE: + emit(ctx, "*out_%s = ", param->p_name); + emit(ctx, + "msg_data.msg_request.%s < nr_handles ", + param->p_name); + emit(ctx, + "? handles[msg_data.msg_request.%s].hnd_value ", + param->p_name); + emit(ctx, ": KERN_HANDLE_INVALID;\n", param->p_name); + break; case TYPE_STRING: emit(ctx, - "out_%s->str_len = msg.msg_request.%s_len;\n", + "out_%s->str_len = msg_data.msg_request.%s_len;\n", param->p_name, param->p_name); @@ -614,9 +753,9 @@ static int emit_interface_msg_function_recv_impl( emit(ctx, "status = msg_read(\n"); emit_indent(ctx); emit(ctx, "channel,\n"); - emit(ctx, "id,\n"); + emit(ctx, "sender->e_msg,\n"); emit(ctx, - "msg.msg_request.%s_offset,\n", + "msg_data.msg_request.%s_offset,\n", param->p_name); emit(ctx, "&iov,\n"); emit(ctx, "1,\n"); @@ -662,21 +801,23 @@ static int emit_interface_msg_function_reply_impl( b_string_toupper(msg_ucase); emit(ctx, - "struct msg_%s_%s msg = {0};\n", + "struct msg_%s_%s msg_data = {0};\n", iface->if_name, msg->msg_name); - emit(ctx, "msg.msg_header.hdr_magic = MSG_MAGIC;\n"); + emit(ctx, "msg_data.msg_header.hdr_magic = MSG_MAGIC;\n"); emit(ctx, - "msg.msg_header.hdr_protocol = PROTOCOL_%s;\n", + "msg_data.msg_header.hdr_protocol = PROTOCOL_%s;\n", b_string_ptr(iface_ucase)); emit(ctx, - "msg.msg_header.hdr_func = MSG_%s_%s;\n\n", + "msg_data.msg_header.hdr_func = MSG_%s_%s;\n\n", b_string_ptr(iface_ucase), b_string_ptr(msg_ucase)); b_string_unref(iface_ucase); b_string_unref(msg_ucase); + size_t handle_index = 0; + b_queue_entry *entry = b_queue_first(&msg->msg_results); while (entry) { struct msg_parameter *param @@ -684,13 +825,20 @@ static int emit_interface_msg_function_reply_impl( switch (param->p_type->ty_id) { case TYPE_INT: emit(ctx, - "msg.msg_response.%s = %s;\n\n", + "msg_data.msg_response.%s = %s;\n\n", param->p_name, param->p_name); break; + case TYPE_HANDLE: + emit(ctx, + "msg_data.msg_response.%s = %zu;\n\n", + param->p_name, + handle_index); + handle_index++; + break; case TYPE_STRING: emit(ctx, - "msg.msg_response.%s_len = strlen(%s);\n", + "msg_data.msg_response.%s_len = strlen(%s);\n", param->p_name, param->p_name); break; @@ -701,9 +849,9 @@ static int emit_interface_msg_function_reply_impl( entry = b_queue_next(entry); } - emit(ctx, "\nstruct iovec iov[] = {\n"); + emit(ctx, "\nkern_iovec_t iov[] = {\n"); emit_indent(ctx); - emit(ctx, "IOVEC(&msg, sizeof msg),\n"); + emit(ctx, "IOVEC(&msg_data, sizeof msg_data),\n"); size_t nr_iov = 1; entry = b_queue_first(&msg->msg_results); @@ -713,7 +861,7 @@ static int emit_interface_msg_function_reply_impl( switch (param->p_type->ty_id) { case TYPE_STRING: emit(ctx, - "IOVEC(%s, msg.msg_response.%s_len),\n", + "IOVEC(%s, msg_data.msg_response.%s_len),\n", param->p_name, param->p_name); nr_iov++; @@ -728,7 +876,45 @@ static int emit_interface_msg_function_reply_impl( emit_unindent(ctx); emit(ctx, "};\n\n"); - emit(ctx, "return msg_reply(channel, id, iov, %zu);\n", nr_iov); + if (handle_index) { + emit(ctx, "kern_msg_handle_t handles[] = {\n"); + emit_indent(ctx); + entry = b_queue_first(&msg->msg_results); + while (entry) { + struct msg_parameter *param + = b_unbox(struct msg_parameter, entry, p_entry); + switch (param->p_type->ty_id) { + case TYPE_HANDLE: + emit(ctx, + "{ .hnd_value = %s, .hnd_mode = " + "KERN_MSG_HANDLE_MOVE, },\n", + param->p_name); + break; + default: + break; + } + + entry = b_queue_next(entry); + } + + emit_unindent(ctx); + emit(ctx, "};\n\n"); + } + + emit(ctx, "kern_msg_t reply = {\n"); + emit_indent(ctx); + emit(ctx, ".msg_data = iov,\n.msg_data_count = %zu,\n", nr_iov); + + if (handle_index) { + emit(ctx, + ".msg_handles = handles,\n.msg_handles_count = %zu,\n", + handle_index); + } + + emit_unindent(ctx); + emit(ctx, "};\n\n"); + + emit(ctx, "return msg_reply(channel, sender->e_msg, &reply);\n"); return 0; } @@ -758,6 +944,9 @@ static int emit_interface_msg_function_send( case TYPE_INT: emit(ctx, "int %s", param->p_name); break; + case TYPE_HANDLE: + emit(ctx, "kern_handle_t %s", param->p_name); + break; case TYPE_STRING: emit(ctx, "const char *%s", param->p_name); break; @@ -776,6 +965,9 @@ static int emit_interface_msg_function_send( case TYPE_INT: emit(ctx, "int *out_%s", param->p_name); break; + case TYPE_HANDLE: + emit(ctx, "kern_handle_t *out_%s", param->p_name); + break; case TYPE_STRING: emit(ctx, "struct msg_string *out_%s", param->p_name); break; @@ -818,7 +1010,9 @@ static int emit_interface_msg_function_recv( emit_indent(ctx); - emit(ctx, "kern_handle_t channel,\nmsgid_t id"); + emit(ctx, + "kern_handle_t channel,\nconst struct msg_endpoint *sender,\n" + "kern_msg_handle_t *handles,\nsize_t nr_handles"); b_queue_entry *entry = b_queue_first(&msg->msg_params); while (entry) { @@ -829,6 +1023,9 @@ static int emit_interface_msg_function_recv( case TYPE_INT: emit(ctx, "int *out_%s", param->p_name); break; + case TYPE_HANDLE: + emit(ctx, "kern_handle_t *out_%s", param->p_name); + break; case TYPE_STRING: emit(ctx, "struct msg_string *out_%s", param->p_name); break; @@ -874,7 +1071,7 @@ static int emit_interface_msg_function_reply( emit_indent(ctx); - emit(ctx, "kern_handle_t channel,\nmsgid_t id"); + emit(ctx, "kern_handle_t channel,\nconst struct msg_endpoint *sender"); b_queue_entry *entry = b_queue_first(&msg->msg_results); while (entry) { @@ -885,6 +1082,9 @@ static int emit_interface_msg_function_reply( case TYPE_INT: emit(ctx, "int %s", param->p_name); break; + case TYPE_HANDLE: + emit(ctx, "kern_handle_t %s", param->p_name); + break; case TYPE_STRING: emit(ctx, "const char *%s", param->p_name); break; @@ -949,7 +1149,7 @@ static int emit_interface_dispatcher_impl_msg( const struct msg_definition *msg) { emit(ctx, - "if (!vtable->%s) return msg_reply_generic(channel, id, msg, " + "if (!vtable->%s) return msg_reply_generic(channel, sender, msg, " "KERN_UNIMPLEMENTED);\n", msg->msg_name); b_queue_entry *entry = b_queue_first(&msg->msg_params); @@ -997,6 +1197,9 @@ static int emit_interface_dispatcher_impl_msg( case TYPE_INT: emit(ctx, "int %s;\n", param->p_name); break; + case TYPE_HANDLE: + emit(ctx, "kern_handle_t %s;\n", param->p_name); + break; case TYPE_STRING: emit(ctx, "struct msg_string %s = {0};\n", @@ -1028,7 +1231,7 @@ static int emit_interface_dispatcher_impl_msg( emit(ctx, "status = %s_%s_recv(\n", iface->if_name, msg->msg_name); emit_indent(ctx); - emit(ctx, "channel,\nid"); + emit(ctx, "channel,\nsender,\nhandles,\nnr_handles"); entry = b_queue_first(&msg->msg_params); while (entry) { struct msg_parameter *param @@ -1043,7 +1246,7 @@ static int emit_interface_dispatcher_impl_msg( emit(ctx, "if (status != KERN_OK) {\n"); emit_indent(ctx); - emit(ctx, "msg_reply_generic(channel, id, msg, status);\n"); + emit(ctx, "msg_reply_generic(channel, sender, msg, status);\n"); emit(ctx, "return status;\n"); emit_unindent(ctx); emit(ctx, "}\n"); @@ -1083,7 +1286,7 @@ static int emit_interface_dispatcher_impl_msg( emit(ctx, "status = %s_%s_recv(\n", iface->if_name, msg->msg_name); emit_indent(ctx); - emit(ctx, "channel,\nid"); + emit(ctx, "channel,\nsender,\nhandles,\nnr_handles"); entry = b_queue_first(&msg->msg_params); while (entry) { struct msg_parameter *param @@ -1098,7 +1301,7 @@ static int emit_interface_dispatcher_impl_msg( emit(ctx, "if (status != KERN_OK) {\n"); emit_indent(ctx); emit_string_destructor_list(ctx, b_queue_last(&msg->msg_params)); - emit(ctx, "msg_reply_generic(channel, id, msg, status);\n"); + emit(ctx, "msg_reply_generic(channel, sender, msg, status);\n"); emit(ctx, "return status;\n"); emit_unindent(ctx); emit(ctx, "}\n"); @@ -1109,18 +1312,18 @@ static int emit_interface_dispatcher_impl_msg( emit(ctx, "status = vtable->%s(\n", msg->msg_name); emit_indent(ctx); + emit(ctx, "sender"); size_t i = 0; entry = b_queue_first(&msg->msg_params); while (entry) { struct msg_parameter *param = b_unbox(struct msg_parameter, entry, p_entry); - if (i > 0) { - emit(ctx, ",\n"); - } + emit(ctx, ",\n"); switch (param->p_type->ty_id) { case TYPE_INT: + case TYPE_HANDLE: emit(ctx, "%s", param->p_name); break; case TYPE_STRING: @@ -1138,9 +1341,7 @@ static int emit_interface_dispatcher_impl_msg( while (entry) { struct msg_parameter *param = b_unbox(struct msg_parameter, entry, p_entry); - if (i > 0) { - emit(ctx, ",\n"); - } + emit(ctx, ",\n"); emit(ctx, "&%s", param->p_name); @@ -1148,6 +1349,12 @@ static int emit_interface_dispatcher_impl_msg( entry = b_queue_next(entry); } + if (i > 0) { + emit(ctx, ",\n"); + } + + emit(ctx, "arg"); + emit(ctx, ");\n"); emit_unindent(ctx); @@ -1161,14 +1368,14 @@ static int emit_interface_dispatcher_impl_msg( emit(ctx, "if (status != KERN_OK) {\n"); emit_indent(ctx); - emit(ctx, "msg_reply_generic(channel, id, msg, status);\n"); + emit(ctx, "msg_reply_generic(channel, sender, msg, status);\n"); emit(ctx, "return status;\n"); emit_unindent(ctx); emit(ctx, "}\n\n"); emit(ctx, "status = %s_%s_reply(\n", iface->if_name, msg->msg_name); emit_indent(ctx); - emit(ctx, "channel,\nid"); + emit(ctx, "channel,\nsender"); entry = b_queue_first(&msg->msg_results); while (entry) { struct msg_parameter *param @@ -1176,6 +1383,7 @@ static int emit_interface_dispatcher_impl_msg( switch (param->p_type->ty_id) { case TYPE_INT: + case TYPE_HANDLE: emit(ctx, ",\n%s", param->p_name); break; case TYPE_STRING: @@ -1258,8 +1466,11 @@ static int emit_interface_dispatcher( emit_indent(ctx); emit(ctx, "kern_handle_t channel,\n"); emit(ctx, "const struct %s_vtable *vtable,\n", iface->if_name); - emit(ctx, "msgid_t id,\n"); - emit(ctx, "const struct msg_header *msg)", iface->if_name); + emit(ctx, "const struct msg_endpoint *sender,\n"); + emit(ctx, "const struct msg_header *msg,\n"); + emit(ctx, "kern_msg_handle_t *handles,\n"); + emit(ctx, "size_t nr_handles,\n\n"); + emit(ctx, "void *arg)\n\n"); emit_unindent(ctx); if (prototype_only) { @@ -1303,7 +1514,9 @@ static int emit_interface_vtable_entry( const struct interface_definition *iface, const struct msg_definition *msg) { - emit(ctx, "kern_status_t(*%s)(\n", msg->msg_name); + emit(ctx, + "kern_status_t(*%s)(\nconst struct msg_endpoint *sender\n", + msg->msg_name); emit_indent(ctx); size_t i = 0; @@ -1311,14 +1524,15 @@ static int emit_interface_vtable_entry( while (entry) { struct msg_parameter *param = b_unbox(struct msg_parameter, entry, p_entry); - if (i > 0) { - emit(ctx, ",\n"); - } + emit(ctx, ",\n"); switch (param->p_type->ty_id) { case TYPE_INT: emit(ctx, "int %s", param->p_name); break; + case TYPE_HANDLE: + emit(ctx, "kern_handle_t %s", param->p_name); + break; case TYPE_STRING: emit(ctx, "const char *%s", param->p_name); break; @@ -1334,14 +1548,15 @@ static int emit_interface_vtable_entry( while (entry) { struct msg_parameter *param = b_unbox(struct msg_parameter, entry, p_entry); - if (i > 0) { - emit(ctx, ",\n"); - } + emit(ctx, ",\n"); switch (param->p_type->ty_id) { case TYPE_INT: emit(ctx, "int *out_%s", param->p_name); break; + case TYPE_HANDLE: + emit(ctx, "kern_handle_t *out_%s", param->p_name); + break; case TYPE_STRING: emit(ctx, "struct msg_string *out_%s", param->p_name); break; @@ -1353,6 +1568,12 @@ static int emit_interface_vtable_entry( entry = b_queue_next(entry); } + if (i > 0) { + emit(ctx, ",\n"); + } + + emit(ctx, "void *arg"); + emit(ctx, ");\n", msg->msg_name); emit_unindent(ctx); @@ -1393,6 +1614,7 @@ static int emit_header( emit_include(ctx, "stdlib.h", true); emit(ctx, "#endif\n"); emit_include(ctx, "mango/msg.h", true); + emit_include(ctx, "mango/types.h", true); emit(ctx, "\n"); emit_header_lib_definitions(ctx); @@ -1430,6 +1652,7 @@ static int emit_interface(const struct interface_definition *iface) struct emit_ctx ctx = { .ctx_out = file, + .ctx_max_handle_params = get_max_handle_params(iface), }; int err = emit_header(&ctx, iface); diff --git a/toolchain/ifc/ctx.c b/toolchain/ifc/ctx.c index 3ece174..a397bb6 100644 --- a/toolchain/ifc/ctx.c +++ b/toolchain/ifc/ctx.c @@ -39,6 +39,10 @@ const struct type *ctx_get_type(struct ctx *ctx, const char *name) return ctx_get_builtin_type(ctx, TYPE_INT); } + if (!strcmp(name, "handle")) { + return ctx_get_builtin_type(ctx, TYPE_HANDLE); + } + return NULL; } diff --git a/toolchain/ifc/parse.c b/toolchain/ifc/parse.c index 0a9b52c..d187d0e 100644 --- a/toolchain/ifc/parse.c +++ b/toolchain/ifc/parse.c @@ -195,6 +195,7 @@ struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex) msg_definition_add_result(msg, type, result_name); free(result_name); + i++; } if (!parse_symbol(lex, SYM_SEMICOLON)) { diff --git a/toolchain/ifc/type.c b/toolchain/ifc/type.c index 9e48103..761b038 100644 --- a/toolchain/ifc/type.c +++ b/toolchain/ifc/type.c @@ -11,6 +11,9 @@ void type_print(const struct type *ty) case TYPE_STRING: printf("string"); break; + case TYPE_HANDLE: + printf("handle"); + break; default: break; } diff --git a/toolchain/ifc/type.h b/toolchain/ifc/type.h index 2dd4ae6..593897a 100644 --- a/toolchain/ifc/type.h +++ b/toolchain/ifc/type.h @@ -5,6 +5,7 @@ enum type_id { TYPE_NONE, TYPE_INT, TYPE_STRING, + TYPE_HANDLE, TYPE_OTHER, };