| 807 | |
| 808 | #[pyfunction] |
| 809 | fn alignment(tp: Either<PyTypeRef, PyObjectRef>, vm: &VirtualMachine) -> PyResult<usize> { |
| 810 | use crate::builtins::PyType; |
| 811 | |
| 812 | let obj = match &tp { |
| 813 | Either::A(t) => t.as_object(), |
| 814 | Either::B(o) => o.as_ref(), |
| 815 | }; |
| 816 | |
| 817 | // 1. Check TypeDataSlot on class (for instances) |
| 818 | if let Some(stg_info) = obj.class().stg_info_opt() { |
| 819 | return Ok(stg_info.align); |
| 820 | } |
| 821 | |
| 822 | // 2. Check TypeDataSlot on type itself (for type objects) |
| 823 | if let Some(type_obj) = obj.downcast_ref::<PyType>() |
| 824 | && let Some(stg_info) = type_obj.stg_info_opt() |
| 825 | { |
| 826 | return Ok(stg_info.align); |
| 827 | } |
| 828 | |
| 829 | // 3. Fallback for simple types |
| 830 | if obj.fast_isinstance(PyCSimple::static_type()) |
| 831 | && let Ok(stg) = obj.class().stg_info(vm) |
| 832 | { |
| 833 | return Ok(stg.align); |
| 834 | } |
| 835 | if obj.fast_isinstance(PyCArray::static_type()) |
| 836 | && let Ok(stg) = obj.class().stg_info(vm) |
| 837 | { |
| 838 | return Ok(stg.align); |
| 839 | } |
| 840 | if obj.fast_isinstance(PyCStructure::static_type()) { |
| 841 | // Calculate alignment from _fields_ |
| 842 | let cls = obj.class(); |
| 843 | return alignment(Either::A(cls.to_owned()), vm); |
| 844 | } |
| 845 | if obj.fast_isinstance(PyCPointer::static_type()) { |
| 846 | // Pointer alignment is always pointer size |
| 847 | return Ok(core::mem::align_of::<usize>()); |
| 848 | } |
| 849 | if obj.fast_isinstance(PyCUnion::static_type()) { |
| 850 | // Calculate alignment from _fields_ |
| 851 | let cls = obj.class(); |
| 852 | return alignment(Either::A(cls.to_owned()), vm); |
| 853 | } |
| 854 | |
| 855 | // Get the type object to check |
| 856 | let type_obj: PyObjectRef = match &tp { |
| 857 | Either::A(t) => t.clone().into(), |
| 858 | Either::B(obj) => obj.class().to_owned().into(), |
| 859 | }; |
| 860 | |
| 861 | // For type objects, try to get alignment from _type_ attribute |
| 862 | if let Ok(type_attr) = type_obj.get_attr("_type_", vm) { |
| 863 | // Array/Pointer: _type_ is the element type (a PyType) |
| 864 | if let Ok(elem_type) = type_attr.clone().downcast::<crate::builtins::PyType>() { |
| 865 | return alignment(Either::A(elem_type), vm); |
| 866 | } |