diff options
Diffstat (limited to 'lib9p/core_gen')
-rw-r--r-- | lib9p/core_gen/c9util.py | 2 | ||||
-rw-r--r-- | lib9p/core_gen/c_marshal.py | 3 | ||||
-rw-r--r-- | lib9p/core_gen/c_unmarshal.py | 9 | ||||
-rw-r--r-- | lib9p/core_gen/h.py | 13 |
4 files changed, 25 insertions, 2 deletions
diff --git a/lib9p/core_gen/c9util.py b/lib9p/core_gen/c9util.py index 84fdee4..a304ff4 100644 --- a/lib9p/core_gen/c9util.py +++ b/lib9p/core_gen/c9util.py @@ -91,6 +91,8 @@ def typename(typ: idl.Type, parent: idl.StructMember | None = None) -> str: match typ: case idl.Primitive(): if typ.value == 1 and parent and parent.cnt: # SPECIAL (string) + if parent.membname == "data": # SPECIAL (iovec) + return f"struct {ident('_iovec')}" return "[[gnu::nonstring]] char" return f"uint{typ.value*8}_t" case idl.Number(): diff --git a/lib9p/core_gen/c_marshal.py b/lib9p/core_gen/c_marshal.py index 86d82e4..af8d582 100644 --- a/lib9p/core_gen/c_marshal.py +++ b/lib9p/core_gen/c_marshal.py @@ -334,6 +334,9 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str: if child.typ.static_size == 1: # SPECIAL (zerocopy) if path.root.typname == "stat": # SPECIAL (stat) ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES(ctx, {path.c_str('val->')[:-3]}, {cnt_str});\n" + elif c9util.typename(child.typ, child) == f"struct {c9util.ident("_iovec")}": # SPECIAL (iovec) + ret += f"{'\t'*indent_lvl()}for (int iov_i = 0; iov_i < {path.c_str('val->')[:-3]}->iovcnt; iov_i++)\n" + ret += f"{'\t'*(indent_lvl()+1)}MARSHAL_BYTES_ZEROCOPY(ctx, {path.c_str('val->')[:-3]}->iov[iov_i].iov_base, {path.c_str('val->')[:-3]}->iov[iov_i].iov_len);\n" else: ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES_ZEROCOPY(ctx, {path.c_str('val->')[:-3]}, {cnt_str});\n" return idlutil.WalkCmd.KEEP_GOING, pop diff --git a/lib9p/core_gen/c_unmarshal.py b/lib9p/core_gen/c_unmarshal.py index 206a85b..c510e44 100644 --- a/lib9p/core_gen/c_unmarshal.py +++ b/lib9p/core_gen/c_unmarshal.py @@ -100,7 +100,14 @@ def gen_c_unmarshal(versions: set[str], typs: list[idl.UserType]) -> str: cnt_str = path.parent().add(child.cnt).c_str("out->") cnt_typ = c9util.typename(child.cnt.typ) if child.typ.static_size == 1: # SPECIAL (zerocopy) - ret += f"{'\t'*indent_lvl()}UNMARSHAL_BYTES(ctx, {path.c_str('out->')[:-3]}, {cnt_str});\n" + if c9util.typename(child.typ, child) == f"struct {c9util.ident('_iovec')}": # SPECIAL (iovec) + ret += f"{'\t'*indent_lvl()}out->{child.membname}.iov = ctx->extra;\n" + ret += f"{'\t'*indent_lvl()}ctx->extra += sizeof(out->{child.membname}.iov[0]);\n" + ret += f"{'\t'*indent_lvl()}out->{child.membname}.iov->iov_base = &ctx->net_bytes[ctx->net_offset];\n" + ret += f"{'\t'*indent_lvl()}out->{child.membname}.iov->iov_len = out->{child.cnt.membname};\n" + ret += f"{'\t'*indent_lvl()}out->{child.membname}.iovcnt = 1;\n" + else: + ret += f"{'\t'*indent_lvl()}UNMARSHAL_BYTES(ctx, {path.c_str('out->')[:-3]}, {cnt_str});\n" return idlutil.WalkCmd.KEEP_GOING, pop ret += f"{'\t'*indent_lvl()}{path.c_str('out->')[:-3]} = extra;\n" ret += f"{'\t'*indent_lvl()}extra += sizeof({path.c_str('out->')[:-3]}[0]) * {cnt_str};\n" diff --git a/lib9p/core_gen/h.py b/lib9p/core_gen/h.py index 8c381f8..6ead5ba 100644 --- a/lib9p/core_gen/h.py +++ b/lib9p/core_gen/h.py @@ -162,6 +162,11 @@ def gen_h(versions: set[str], typs: list[idl.UserType]) -> str: #ifndef _LIB9P_CORE_H_ \t#error Do not include <lib9p/_core_generated.h> directly; include <lib9p/core.h> instead #endif + +struct {c9util.ident('_iovec_list')} {{ +\tstruct iovec *iov; +\tint iovcnt; +}}; """ id2typ: dict[int, idl.Message] = {} for msg in [msg for msg in typs if isinstance(msg, idl.Message)]: @@ -523,7 +528,13 @@ def gen_struct(typ: idl.Struct) -> str: # and idl.Message if member.val: continue ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) - ret += f"\t{c9util.typename(member.typ, member):<{typewidth}} {'*' if member.cnt else ' '}{member.membname};\n" + ptr = bool(member.cnt) + if ( + c9util.typename(member.typ, member) + == f"struct {c9util.ident('_iovec')}" + ): # SPECIAL (zerocopy) + ptr = False + ret += f"\t{c9util.typename(member.typ, member):<{typewidth}} {'*' if ptr else ' '}{member.membname};\n" ret += cutil.ifdef_pop(1) ret += "};\n" return ret |