toolchain: ifc: mpc: add support for sending/receiving handles

This commit is contained in:
2026-03-06 20:15:29 +00:00
parent 1c89acddbf
commit faeefe28ab
5 changed files with 318 additions and 86 deletions

View File

@@ -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");
}
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, "&%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");
}
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");
}
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);

View File

@@ -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;
}

View File

@@ -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)) {

View File

@@ -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;
}

View File

@@ -5,6 +5,7 @@ enum type_id {
TYPE_NONE,
TYPE_INT,
TYPE_STRING,
TYPE_HANDLE,
TYPE_OTHER,
};