autogen: fix packed args structs (#13274)

* autogen: fix packed args structs

* and test this
This commit is contained in:
nimlgen
2025-11-14 20:24:06 +08:00
committed by GitHub
parent 14eb48b13a
commit c80d459d99
2 changed files with 41 additions and 1 deletions

View File

@@ -44,4 +44,42 @@ class TestAutogen(unittest.TestCase):
test.argtypes = [Baz]
self.assertEqual(test(b), b.a + b.b + b.c + b.d)
@unittest.skipIf(WIN, "doesn't compile on windows")
def test_packed_structs(self):
NvU32 = ctypes.c_uint32
NvU64 = ctypes.c_uint64
class FWSECLIC_READ_VBIOS_DESC(Struct): pass
FWSECLIC_READ_VBIOS_DESC._packed_ = True
FWSECLIC_READ_VBIOS_DESC._fields_ = [
('version', NvU32),
('size', NvU32),
('gfwImageOffset', NvU64),
('gfwImageSize', NvU32),
('flags', NvU32),
]
class FWSECLIC_FRTS_REGION_DESC(Struct): pass
FWSECLIC_FRTS_REGION_DESC._packed_ = True
FWSECLIC_FRTS_REGION_DESC._fields_ = [
('version', NvU32),
('size', NvU32),
('frtsRegionOffset4K', NvU32),
('frtsRegionSize', NvU32),
('frtsRegionMediaType', NvU32),
]
class FWSECLIC_FRTS_CMD(Struct): pass
FWSECLIC_FRTS_CMD._packed_ = True
FWSECLIC_FRTS_CMD._fields_ = [
('readVbiosDesc', FWSECLIC_READ_VBIOS_DESC),
('frtsRegionDesc', FWSECLIC_FRTS_REGION_DESC),
]
read_vbios_desc = FWSECLIC_READ_VBIOS_DESC(version=0x1, size=ctypes.sizeof(FWSECLIC_READ_VBIOS_DESC), flags=2)
frst_reg_desc = FWSECLIC_FRTS_REGION_DESC(version=0x1, size=ctypes.sizeof(FWSECLIC_FRTS_REGION_DESC),
frtsRegionOffset4K=0xdead, frtsRegionSize=0x100, frtsRegionMediaType=2)
frts_cmd = FWSECLIC_FRTS_CMD(readVbiosDesc=read_vbios_desc, frtsRegionDesc=frst_reg_desc)
assert int.from_bytes(frts_cmd, 'little') == 0x2000001000000dead0000001400000001000000020000000000000000000000000000001800000001
assert int.from_bytes(frts_cmd.readVbiosDesc, 'little') == int.from_bytes(read_vbios_desc, 'little')
assert int.from_bytes(frts_cmd.frtsRegionDesc, 'little') == int.from_bytes(frst_reg_desc, 'little')
assert frts_cmd.readVbiosDesc.__class__ is FWSECLIC_READ_VBIOS_DESC
assert frts_cmd.frtsRegionDesc.__class__ is FWSECLIC_FRTS_REGION_DESC
if __name__ == "__main__": unittest.main()

View File

@@ -59,7 +59,9 @@ else:
mask = (1 << (sz:=ctypes.sizeof(ty)*8 if bf == 0 else bf)) - 1
def fget(self, mask, off, ty): return ((int.from_bytes(self._data, sys.byteorder)>>off)&mask if issubclass(ty, _SimpleCData) else
ty.from_buffer(memoryview(self._data)[(st:=off//8):st+ctypes.sizeof(ty)]))
def fset(self, val, mask, off): self._data[:] = (((int.from_bytes(self._data, sys.byteorder) & ~(mask<<off))|((val&mask)<<off))
def fset(self, val, mask, off):
if val.__class__ is not int: val = int.from_bytes(val, sys.byteorder)
self._data[:] = (((int.from_bytes(self._data, sys.byteorder) & ~(mask<<off))|((val&mask)<<off))
.to_bytes(len(self._data), sys.byteorder))
setattr(cls, nm, property(functools.partial(fget, mask=mask, off=offset, ty=ty), functools.partial(fset, mask=mask, off=offset)))
offset += sz