summaryrefslogtreecommitdiff
path: root/lib9p/idl.gen
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/idl.gen')
-rwxr-xr-xlib9p/idl.gen43
1 files changed, 40 insertions, 3 deletions
diff --git a/lib9p/idl.gen b/lib9p/idl.gen
index 05d78be..f9db2d5 100755
--- a/lib9p/idl.gen
+++ b/lib9p/idl.gen
@@ -23,6 +23,9 @@ import idl
idprefix = "lib9p_"
+u32max = (1 << 32) - 1
+u64max = (1 << 64) - 1
+
def tab_ljust(s: str, width: int) -> str:
cur = len(s.expandtabs(tabsize=8))
@@ -222,9 +225,43 @@ enum {idprefix}version {{
ret += """
/* payload types **************************************************************/
"""
+
+ def per_version_comment(
+ typ: idl.Type, fn: typing.Callable[[idl.Type, str], str]
+ ) -> str:
+ lines: dict[str, str] = {}
+ for version in sorted(typ.in_versions):
+ lines[version] = fn(typ, version)
+ if len(set(lines.values())) == 1:
+ for _, line in lines.items():
+ return f"/* {line} */\n"
+ assert False
+ else:
+ ret = ""
+ v_width = max(len(c_ver_enum(v)) for v in typ.in_versions)
+ for version, line in lines.items():
+ ret += f"/* {c_ver_enum(version).ljust(v_width)}: {line} */\n"
+ return ret
+
for typ in topo_sorted(typs):
ret += "\n"
ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
+
+ def sum_size(typ: idl.Type, version: str) -> str:
+ min_size = typ.min_size(version)
+ max_size = typ.max_size(version)
+ assert min_size <= max_size and max_size < u64max
+ ret = ""
+ if min_size == max_size:
+ ret += f"size = {min_size:,}"
+ else:
+ ret += f"min_size = {min_size:,} ; max_size = {max_size:,}"
+ if max_size > u32max:
+ ret += " (warning: >UINT32_MAX)"
+ return ret
+
+ ret += per_version_comment(typ, sum_size)
+
match typ:
case idl.Number():
ret += f"typedef {c_typename(typ.prim)} {c_typename(typ)};\n"
@@ -618,8 +655,8 @@ LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *o
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};\n"
- ret += f"{prefix}for (typeof(out->{member.cnt}) i = 0; i < out->{member.cnt}; i++)\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 typ.name in ["d", "s"]: # SPECIAL
# 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"
@@ -721,7 +758,7 @@ LM_ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val)
ret += f"({{ _{member.name}_offset = ctx->net_offset; "
if member.cnt:
ret += "({ bool err = false;\n"
- ret += f"\t for (typeof(val->{member.cnt}) i = 0; i < val->{member.cnt} && !err; i++)\n"
+ ret += f"\t for (typeof(val->{member.cnt.name}) i = 0; i < val->{member.cnt.name} && !err; i++)\n"
ret += "\t \terr = "
if typ.name in ["d", "s"]: # SPECIAL
# Special-case is that we cast from `char` to `uint8_t`.