feat(gen): 支持 t.BigEndian / t.LittleEndian 字节序描述符(注解识别 X|marker 并把字节序登记到 FieldEntry.ByteOrder,暂不生成 bswap)
This commit is contained in:
1 parent
3ca2165fd9
commit
5d15d01e21
5 files changed
+53
No files matched your search
@@ -162,9 +162,13 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# Field const-object flag buffer (1 = annotation has t.CConst and the type is not
|
||||
# a pointer), parallel to field_volatile_buf with values 0/1.
|
||||
field_const_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX)
|
||||
# Field byte-order buffer (0 = native, 1 = t.BigEndian, 2 = t.LittleEndian), parallel
|
||||
# to field_volatile_buf; from the `X | t.BigEndian` annotation union.
|
||||
field_byteorder_buf: sizet* = pool.alloc(8 * GenTypes.FIELD_MAX)
|
||||
if field_names_buf is None or field_types_buf is None or field_defaults_buf is None: return 0
|
||||
if field_annot_buf is None or field_volatile_buf is None: return 0
|
||||
if field_pointee_volatile_buf is None or field_const_buf is None: return 0
|
||||
if field_byteorder_buf is None: return 0
|
||||
string.memset(field_names_buf, 0, 8 * GenTypes.FIELD_MAX)
|
||||
string.memset(field_types_buf, 0, 8 * GenTypes.FIELD_MAX)
|
||||
string.memset(field_defaults_buf, 0, 8 * GenTypes.FIELD_MAX)
|
||||
@@ -172,6 +176,7 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
string.memset(field_volatile_buf, 0, 8 * GenTypes.FIELD_MAX)
|
||||
string.memset(field_pointee_volatile_buf, 0, 8 * GenTypes.FIELD_MAX)
|
||||
string.memset(field_const_buf, 0, 8 * GenTypes.FIELD_MAX)
|
||||
string.memset(field_byteorder_buf, 0, 8 * GenTypes.FIELD_MAX)
|
||||
|
||||
field_count: int = 0
|
||||
|
||||
@@ -221,6 +226,8 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
field_pointee_volatile_buf[field_count] = sizet(pfe.PointeeVolatile)
|
||||
# Inherit the const-object flag (unchanged after flattening)
|
||||
field_const_buf[field_count] = sizet(pfe.IsConst)
|
||||
# Inherit the byte-order flag (unchanged after flattening)
|
||||
field_byteorder_buf[field_count] = sizet(pfe.ByteOrder)
|
||||
field_count += 1
|
||||
|
||||
children: list[ast.AST*]* = cd.children
|
||||
@@ -340,11 +347,17 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
# through the object fail-fasts, matching TPC's Gen.field_const_flags.
|
||||
if self.Gen.TypeGenErr.is_const_object_marker(aa.annotation, field_ty) != 0: field_const_buf[field_count] = 1
|
||||
else: field_const_buf[field_count] = 0
|
||||
# Byte-order marker (t.BigEndian / t.LittleEndian) -> 1 / 2; annotation `|`
|
||||
# means "and", so `X | t.BigEndian` is a BigEndian-encoded X field.
|
||||
if self.Gen.TypeGenErr.has_decorator_marker(aa.annotation, "BigEndian", 0) != 0: field_byteorder_buf[field_count] = 1
|
||||
elif self.Gen.TypeGenErr.has_decorator_marker(aa.annotation, "LittleEndian", 0) != 0: field_byteorder_buf[field_count] = 2
|
||||
else: field_byteorder_buf[field_count] = 0
|
||||
else:
|
||||
field_annot_buf[field_count] = 0
|
||||
field_volatile_buf[field_count] = 0
|
||||
field_pointee_volatile_buf[field_count] = 0
|
||||
field_const_buf[field_count] = 0
|
||||
field_byteorder_buf[field_count] = 0
|
||||
field_count += 1
|
||||
|
||||
if field_count == 0:
|
||||
@@ -518,6 +531,10 @@ novirtual class ClassGenDef(ClassGenBase.ClassGenBase):
|
||||
if fidx_add >= 0 and field_pointee_volatile_buf[fi] != 0:
|
||||
fe_pv: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(entry, fidx_add)
|
||||
if fe_pv is not None: fe_pv.PointeeVolatile = 1
|
||||
# byte-order field flag (field_byteorder_buf[fi] corresponds 1:1 with add_field order)
|
||||
if fidx_add >= 0 and field_byteorder_buf[fi] != 0:
|
||||
fe_bo: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(entry, fidx_add)
|
||||
if fe_bo is not None: fe_bo.ByteOrder = int(field_byteorder_buf[fi])
|
||||
# const object field flag (field_const_buf[fi] corresponds 1:1 with add_field order)
|
||||
if fidx_add >= 0 and field_const_buf[fi] != 0:
|
||||
fe_c: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(entry, fidx_add)
|
||||
|
||||
@@ -106,6 +106,10 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
if string.strcmp(name, "CRef") == 0: return 1
|
||||
if string.strcmp(name, "CTempRef") == 0: return 1
|
||||
if string.strcmp(name, "CAutoPtr") == 0: return 1
|
||||
# Byte-order markers (t.BigEndian / t.LittleEndian): decorator markers used as
|
||||
# `X | t.BigEndian`; recognized here so they are not taken for an unregistered class.
|
||||
if string.strcmp(name, "BigEndian") == 0: return 1
|
||||
if string.strcmp(name, "LittleEndian") == 0: return 1
|
||||
return 0
|
||||
def _attr_module_path_str(self, pool: memhub.MemBuddy*, node: ast.AST*) -> str:
|
||||
"""Convert a module-reference AST into a dotted module path; None for non-module forms."""
|
||||
|
||||
@@ -121,6 +121,10 @@ class FieldEntry:
|
||||
# 1=this field is a const object (annotation has t.CConst and the type is not a pointer):
|
||||
# assigning it via an object fails fast, same as VarEntry.IsConst.
|
||||
IsConst: int
|
||||
# Byte order of this field, from the `X | t.BigEndian` / `X | t.LittleEndian` annotation
|
||||
# union: 0=native (no marker), 1=BigEndian, 2=LittleEndian. Appended at the end so offsets
|
||||
# are unchanged; consumers bswap on field load/store when 1 (16/32/64-bit ints only).
|
||||
ByteOrder: int
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -2493,6 +2493,8 @@ novirtual class StructGenMixin:
|
||||
|
||||
# Explicitly zero the const flag (not relying on the entry's zero-init): ClassGenDef sets it to 1 only for a confirmed const object, so explicit zeroing prevents a false "uninitialized read as 1".
|
||||
fe.IsConst = 0
|
||||
# Byte order is filled in by ClassGenDef from the field annotation (0 = native here).
|
||||
fe.ByteOrder = 0
|
||||
struct_entry.FieldCount = idx + 1
|
||||
return idx
|
||||
|
||||
|
||||
@@ -1443,6 +1443,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
return mlirlite.Int1(pool)
|
||||
# ptrdiff_t
|
||||
elif string.strcmp(type_name, "CPtrDiffT") == 0: return mlirlite.Int64(pool)
|
||||
# Byte-order markers written alone (no real type on the other side) degrade to CInt,
|
||||
# matching TPC: `t.BigEndian` alone -> BaseType=CInt() + ByteOrder='big'.
|
||||
elif string.strcmp(type_name, "BigEndian") == 0: return mlirlite.Int32(pool)
|
||||
elif string.strcmp(type_name, "LittleEndian") == 0: return mlirlite.Int32(pool)
|
||||
|
||||
# stdint.vp aliases (INT/BYTE/DWORD/int8_t/size_t/_Bool ...) now come from its
|
||||
# CTypedef declarations; lowercase bare char/float/double stay here, int/bool use Name.
|
||||
@@ -1486,6 +1490,11 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if self._is_t_attr(node, "CRef", imported_modules) != 0: return 1
|
||||
if self._is_t_attr(node, "CTempRef", imported_modules) != 0: return 1
|
||||
return 0
|
||||
def _is_byteorder_marker(self, node: ast.AST*, imported_modules: str) -> int:
|
||||
"""Whether a node is a byte-order marker: 0=none / 1=BigEndian / 2=LittleEndian."""
|
||||
if self._is_t_attr(node, "BigEndian", imported_modules) != 0: return 1
|
||||
if self._is_t_attr(node, "LittleEndian", imported_modules) != 0: return 2
|
||||
return 0
|
||||
def _ref_marker_name_mode(self, node: ast.AST*) -> int:
|
||||
"""Syntactic value-reference marker test (no import context): 0=none / 1=CRef / 2=CTempRef."""
|
||||
if node is None: return 0
|
||||
@@ -1640,6 +1649,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if string.strcmp(name, "CExport") == 0: return 1
|
||||
if string.strcmp(name, "CExtern") == 0: return 1
|
||||
if string.strcmp(name, "CInline") == 0: return 1
|
||||
# Byte-order markers are decorators, not types: never let them be extracted as a
|
||||
# class name (which would make the field degrade to an unknown struct lookup).
|
||||
if string.strcmp(name, "BigEndian") == 0: return 1
|
||||
if string.strcmp(name, "LittleEndian") == 0: return 1
|
||||
return 0
|
||||
|
||||
def extract_class_name_from_annotation(self, node: ast.AST*, imported_modules: str, pool: memhub.MemBuddy* = None, from_imports: str = None) -> str:
|
||||
@@ -2332,6 +2345,19 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
if k == ast.ASTKind.BinOp:
|
||||
bop: ast.BinOp* = ast.BinOp*(node)
|
||||
if bop.op == ast.OpKind.BitOr:
|
||||
# Byte-order markers: annotation `|` means "and", so `ActualType | t.BigEndian`
|
||||
# yields the actual type; the byte order itself is recorded on the field entry
|
||||
# (see ClassGenDef field_byteorder_buf), not carried in the LLVM type.
|
||||
left_bo: int = self._is_byteorder_marker(bop.left, imported_modules)
|
||||
right_bo: int = self._is_byteorder_marker(bop.right, imported_modules)
|
||||
if left_bo != 0 or right_bo != 0:
|
||||
other_node_bo: ast.AST* = bop.right
|
||||
if right_bo != 0: other_node_bo = bop.left
|
||||
if other_node_bo is not None:
|
||||
other_ty_bo: mlirlite.LLVMType* = self.resolve_annotation_type(pool, other_node_bo, imported_modules, from_imports, trans, depth + 1)
|
||||
if other_ty_bo is not None: return other_ty_bo
|
||||
# Markers on both sides (e.g. `t.BigEndian | t.LittleEndian`) -> CInt.
|
||||
return mlirlite.Int32(pool)
|
||||
# Detect the t.CPtr marker (supports t.CPtr and the bare from t import CPtr name).
|
||||
# CRef/CTempRef (value-reference parameter markers) resolve identically here: the
|
||||
# parameter ABI is Ptr(other); the ref/temp distinction only drives call-site auto-address.
|
||||
|
||||
Reference in new issue
Block a user