diff options
Diffstat (limited to 'lib9p/idl.gen')
-rwxr-xr-x | lib9p/idl.gen | 43 |
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`. |