diff --git a/FrontEnd/cwast.py b/FrontEnd/cwast.py index 304c032d..60fd5447 100755 --- a/FrontEnd/cwast.py +++ b/FrontEnd/cwast.py @@ -799,6 +799,8 @@ def NodeCommon(cls): # Typing ############################################################ +def align(x, a): + return (x + a - 1) // a * a @dataclasses.dataclass() class CanonType: @@ -813,7 +815,7 @@ class CanonType: children: List["CanonType"] = dataclasses.field(default_factory=list) # ast_node: Optional[Union["DefRec", "DefEnum"]] = None - # + # will be filled in by type_corpus. alignment: int = -1 size: int = -1 register_types: Optional[List[Any]] = None @@ -928,6 +930,10 @@ def contained_type(self) -> "CanonType": else: assert False, f"unexpected type: {self.name}" + def aligned_size(self) -> int: + # somtimes we need to round up. e.g. struct {int32, int8} needs 3 bytes padding + return align(self.size, self.alignment) + def array_dim(self): assert self.is_array() return self.dim @@ -3005,7 +3011,7 @@ def EliminateEphemeralsRecursively(node): child = getattr(node, f) if isinstance(child, EphemeralList): new_child = _MaybeFlattenEphemeralList([child]) - assert len(new_child) == 1 + assert len(new_child) == 1, f"{f} {node.__class__} {len(new_child)}" setattr(node, f, new_child[0]) EliminateEphemeralsRecursively(child) elif nfd.kind is NFK.LIST: diff --git a/FrontEnd/emit_ir.py b/FrontEnd/emit_ir.py index 9a261c4f..52633895 100755 --- a/FrontEnd/emit_ir.py +++ b/FrontEnd/emit_ir.py @@ -422,8 +422,9 @@ def EmitIRExpr(node, tc: type_corpus.TypeCorpus, id_gen: identifier.IdGenIR) -> ct: cwast.CanonType = node.expr1.x_type if node.pointer_expr_kind is cwast.POINTER_EXPR_KIND.INCP: assert ct.is_pointer() + #print ("@@@@@ ", ct, ct.underlying_pointer_type().size) offset = OffsetScaleToOffset( - node.expr2, ct.underlying_pointer_type().size, tc, id_gen) + node.expr2, ct.underlying_pointer_type().aligned_size(), tc, id_gen) kind = tc.get_data_address_reg_type() print(f"{TAB}lea {res}:{kind} = {base} {offset}") else: @@ -436,7 +437,7 @@ def EmitIRExpr(node, tc: type_corpus.TypeCorpus, id_gen: identifier.IdGenIR) -> f"{TAB}bitcast {res}:{node.type.x_type.get_single_register_type()} = {expr}") return res elif isinstance(node, cwast.ExprUnsafeCast): - return EmitIRExpr(node.expr, tc, id_gen) + return EmitIRExpr(node.expr, tc, id_gen) elif isinstance(node, cwast.ExprNarrow): if ct_dst.is_void_or_wrapped_void(): return None @@ -761,6 +762,7 @@ def _EmitMem(data, comment) -> int: assert False return len(data) + _BYTE_ZERO = b"\0" _BYTE_UNDEF = b"\0" _BYTE_PADDING = b"\x6f" # intentioanlly not zero? @@ -1036,7 +1038,6 @@ def GetIdGen(fun): eliminated_nodes.add(cwast.Expr3) mod_gen.body_mod += constant_pool.GetDefGlobals() - slice_to_struct_map = canonicalize_slice.MakeSliceTypeReplacementMap( mod_topo_order, tc) mod_gen.body_mod += [ diff --git a/FrontEnd/type_corpus.py b/FrontEnd/type_corpus.py index ca4cc660..e102e3c2 100644 --- a/FrontEnd/type_corpus.py +++ b/FrontEnd/type_corpus.py @@ -414,11 +414,7 @@ def _get_size_and_alignment(self, tc: cwast.CanonType): len_field_size = self._target_arch_config.uint_bitwidth // 8 return ptr_field_size + len_field_size, ptr_field_size elif tc.node is cwast.TypeArray: - alignment = tc.children[0].alignment - size = tc.children[0].size - # somtimes we need to round up. e.g. struct {int32, int8} needs 3 bytes padding - size = align(size, alignment) - return size * tc.dim, alignment + return tc.children[0].aligned_size() * tc.dim, tc.children[0].alignment elif tc.node is cwast.TypeUnion: return _get_size_and_offset_for_sum_type( tc, self._target_arch_config.typeid_bitwidth // 8,