~jojo/Carth

86dd9f1b9942ce69ad22495504266be9fb6dad22 — JoJo 1 year, 6 months ago 3f71c01
Handle unit and other zero-sized types in alignmentof & sizeof
2 files changed, 10 insertions(+), 4 deletions(-)

M src/Abi.hs
M src/Codegen.hs
M src/Abi.hs => src/Abi.hs +7 -2
@@ 171,14 171,19 @@ sizeof = \case
    toBytesCeil nbits = div (nbits + 7) 8
    addMember accSize u = do
        align <- alignmentof u
        let padding = mod (align - accSize) align
        let padding = if align == 0 then 0 else mod (align - accSize) align
        size <- sizeof u
        pure (accSize + padding + size)

alignmentof :: Type -> Gen' Word64
alignmentof = \case
    NamedTypeReference x -> alignmentof =<< lookupDatatype x
    StructureType _ us -> fmap maximum (traverse alignmentof us)
    StructureType _ [] -> pure 0
    t@(StructureType _ us) -> do
        as <- traverse alignmentof us
        if null as
            then ice ("alignmentof: alignments empty for struct " ++ pretty t)
            else pure (maximum as)
    VectorType _ u -> alignmentof u
    ArrayType _ u -> alignmentof u
    t -> sizeof t

M src/Codegen.hs => src/Codegen.hs +3 -2
@@ 115,8 115,9 @@ defineDataTypes tds = do
            let totVariants = length vs
            ts <- mapM (genVariantType (fromIntegral totVariants)) vs
            sizedTs <- mapM (\t -> fmap (\s -> (s, t)) (sizeof t)) ts
            let (_, tmax) = maximum sizedTs
            pure (n, tmax)
            if null sizedTs
                then ice ("defineDataTypes: sizedTs empty for def " ++ show n)
                else pure (n, snd (maximum sizedTs))

runGen' :: Gen' a -> a
runGen' g = runReader