From 9fc8825764cb9d860a26ac3eab59a4ff164cca71 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Tue, 28 Jan 2025 01:35:57 -0700 Subject: lib9p: Don't copy byte-arrays when unmarshaling --- lib9p/idl.gen | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'lib9p/idl.gen') diff --git a/lib9p/idl.gen b/lib9p/idl.gen index 9a8260a..f2b4f13 100755 --- a/lib9p/idl.gen +++ b/lib9p/idl.gen @@ -831,7 +831,10 @@ LM_ALWAYS_INLINE static bool validate_8(struct _validate_ctx *ctx) { return _val if member.in_versions != typ.in_versions: ret += "( " + c_ver_cond(member.in_versions) + " && " if member.cnt is not None: - ret += f"_validate_list(ctx, {member.cnt.name}, validate_{member.typ.name}, sizeof({c_typename(member.typ)}))" + if member.typ.static_size == 1: # SPECIAL (zerocopy) + ret += f"_validate_size_net(ctx, {member.cnt.name})" + else: + ret += f"_validate_list(ctx, {member.cnt.name}, validate_{member.typ.name}, sizeof({c_typename(member.typ)}))" if typ.name == "s": # SPECIAL (string) ret += f'\n\t || ({{ (!is_valid_utf8_without_nul(&ctx->net_bytes[ctx->net_offset-len], len)) && lib9p_error(ctx->ctx, LINUX_EBADMSG, "message contains invalid UTF-8"); }})' else: @@ -935,13 +938,15 @@ LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *o if member.in_versions != typ.in_versions: ret += "{\n" ret += prefix - ret += f"out->{member.name} = ctx->extra;\n" - ret += f"{prefix}ctx->extra += sizeof(out->{member.name}[0]) * out->{member.cnt.name};\n" - ret += f"{prefix}for (typeof(out->{member.cnt.name}) i = 0; i < out->{member.cnt.name}; i++)\n" - if member.typ.static_size == 1: # SPECIAL (string) - # Special-case is that we cast from `char` to `uint8_t`. - ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, (uint8_t *)&out->{member.name}[i]);\n" + if member.typ.static_size == 1: # SPECIAL (string, zerocopy) + ret += f"out->{member.name} = (char *)&ctx->net_bytes[ctx->net_offset];\n" + ret += ( + f"{prefix}ctx->net_offset += out->{member.cnt.name};\n" + ) else: + ret += f"out->{member.name} = ctx->extra;\n" + ret += f"{prefix}ctx->extra += sizeof(out->{member.name}[0]) * out->{member.cnt.name};\n" + ret += f"{prefix}for (typeof(out->{member.cnt.name}) i = 0; i < out->{member.cnt.name}; i++)\n" ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, &out->{member.name}[i]);\n" if member.in_versions != typ.in_versions: ret += "\t}\n" -- cgit v1.2.3-2-g168b