summaryrefslogtreecommitdiff
path: root/lib9p/protogen/c_marshal.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/protogen/c_marshal.py')
-rw-r--r--lib9p/protogen/c_marshal.py47
1 files changed, 32 insertions, 15 deletions
diff --git a/lib9p/protogen/c_marshal.py b/lib9p/protogen/c_marshal.py
index 74b64f5..4dab864 100644
--- a/lib9p/protogen/c_marshal.py
+++ b/lib9p/protogen/c_marshal.py
@@ -23,7 +23,7 @@ __all__ = ["gen_c_marshal"]
class OffsetExpr:
static: int
cond: dict[frozenset[str], "OffsetExpr"]
- rep: list[tuple[idlutil.Path, "OffsetExpr"]]
+ rep: list[tuple[idlutil.Path | int, "OffsetExpr"]]
def __init__(self) -> None:
self.static = 0
@@ -52,14 +52,20 @@ class OffsetExpr:
if self.static:
oneline.append(str(self.static))
for cnt, sub in self.rep:
+ if isinstance(cnt, int):
+ cnt_str = str(cnt)
+ cnt_typ = "size_t"
+ else:
+ cnt_str = cnt.c_str(root)
+ cnt_typ = c9util.typename(cnt.elems[-1].typ)
if not sub.cond and not sub.rep:
if sub.static == 1:
- oneline.append(cnt.c_str(root))
+ oneline.append(cnt_str)
else:
- oneline.append(f"({cnt.c_str(root)})*{sub.static}")
+ oneline.append(f"({cnt_str})*{sub.static}")
continue
loopvar = chr(ord("i") + loop_depth)
- multiline += f"{'\t'*indent_depth}for ({c9util.typename(cnt.elems[-1].typ)} {loopvar} = 0; {loopvar} < {cnt.c_str(root)}; {loopvar}++) {{\n"
+ multiline += f"{'\t'*indent_depth}for ({cnt_typ} {loopvar} = 0; {loopvar} < {cnt_str}; {loopvar}++) {{\n"
multiline += sub.gen_c("", dstvar, root, indent_depth + 1, loop_depth + 1)
multiline += f"{'\t'*indent_depth}}}\n"
for vers, sub in self.cond.items():
@@ -113,8 +119,12 @@ def get_offset_expr(typ: idl.UserType, recurse: OffsetExprRecursion) -> OffsetEx
member_path = expr_stack[-1].path
member = member_path.elems[-1]
assert member.cnt
- cnt_path = member_path.parent().add(member.cnt)
- expr_stack[-2].expr.rep.append((cnt_path, expr_stack[-1].expr))
+ cnt: idlutil.Path | int
+ if isinstance(member.cnt, int):
+ cnt = member.cnt
+ else:
+ cnt = member_path.parent().add(member.cnt)
+ expr_stack[-2].expr.rep.append((cnt, expr_stack[-1].expr))
expr_stack = expr_stack[:-1]
def handle(
@@ -268,11 +278,13 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str:
if not member.val:
continue
for tok in member.val.tokens:
- if not isinstance(tok, idl.ExprSym):
- continue
- if tok.symname == "end" or tok.symname.startswith("&"):
- if tok.symname not in offsets:
- offsets.append(tok.symname)
+ match tok:
+ case idl.ExprSym(symname="end"):
+ if tok.symname not in offsets:
+ offsets.append(tok.symname)
+ case idl.ExprOff():
+ if f"&{tok.membname}" not in offsets:
+ offsets.append(f"&{tok.membname}")
for name in offsets:
name_prefix = f"offsetof{''.join('_'+m.membname for m in path.elems)}_"
if name == "end":
@@ -313,15 +325,20 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str:
)
indent_stack.append(IndentLevel(ifdef=True))
if child.cnt:
- cnt_path = path.parent().add(child.cnt)
+ if isinstance(child.cnt, int):
+ cnt_str = str(child.cnt)
+ cnt_typ = "size_t"
+ else:
+ cnt_str = path.parent().add(child.cnt).c_str("val->")
+ cnt_typ = c9util.typename(child.cnt.typ)
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_path.c_str('val->')});\n"
+ ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES(ctx, {path.c_str('val->')[:-3]}, {cnt_str});\n"
else:
- ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES_ZEROCOPY(ctx, {path.c_str('val->')[:-3]}, {cnt_path.c_str('val->')});\n"
+ ret += f"{'\t'*indent_lvl()}MARSHAL_BYTES_ZEROCOPY(ctx, {path.c_str('val->')[:-3]}, {cnt_str});\n"
return idlutil.WalkCmd.KEEP_GOING, pop
loopvar = chr(ord("i") + loopdepth - 1)
- ret += f"{'\t'*indent_lvl()}for ({c9util.typename(child.cnt.typ)} {loopvar} = 0; {loopvar} < {cnt_path.c_str('val->')}; {loopvar}++) {{\n"
+ ret += f"{'\t'*indent_lvl()}for ({cnt_typ} {loopvar} = 0; {loopvar} < {cnt_str}; {loopvar}++) {{\n"
indent_stack.append(IndentLevel(ifdef=False))
if not isinstance(child.typ, idl.Struct):
if child.val: