module DDC.Core.Lite.Layout
(
HeapObject(..)
, heapObjectOfDataCtor
, payloadSizeOfDataCtor
, fieldOffsetsOfDataCtor)
where
import DDC.Core.Lite.Name
import DDC.Core.Lite.Env
import DDC.Core.Salt.Platform
import DDC.Type.DataDef
import DDC.Type.Exp
import Control.Monad
import Data.Maybe
import qualified DDC.Core.Salt.Name as A
data HeapObject
= HeapObjectBoxed
| HeapObjectMixed
| HeapObjectRaw
| HeapObjectRawSmall
deriving (Eq, Show)
heapObjectOfDataCtor :: Platform -> DataCtor Name -> Maybe HeapObject
heapObjectOfDataCtor pp ctor
| tsFields <- dataCtorFieldTypes ctor
, all isBoxedType tsFields
= Just HeapObjectBoxed
| [TCon tc] <- dataCtorFieldTypes ctor
, TyConBound (UPrim n _) _ <- tc
, NamePrimTyCon ptc <- n
, isJust $ A.primTyConWidth pp ptc
= Just HeapObjectRawSmall
| otherwise
= Nothing
payloadSizeOfDataCtor :: Platform -> DataCtor Name -> Maybe Integer
payloadSizeOfDataCtor platform ctor
= liftM sum
$ sequence
$ map (fieldSizeOfType platform)
$ dataCtorFieldTypes ctor
fieldOffsetsOfDataCtor :: Platform -> DataCtor Name -> Maybe [Integer]
fieldOffsetsOfDataCtor platform ctor
= liftM (init . scanl (+) 0)
$ sequence
$ map (fieldSizeOfType platform)
$ dataCtorFieldTypes ctor
fieldSizeOfType :: Platform -> Type Name -> Maybe Integer
fieldSizeOfType platform tt
= case tt of
TVar{} -> Just $ platformAddrBytes platform
TCon tc
-> case tc of
TyConBound (UPrim n _) _ -> fieldSizeOfPrim platform n
TyConBound _ _ -> Just $ platformAddrBytes platform
_ -> Nothing
TForall{} -> Nothing
TApp{} -> Just $ platformAddrBytes platform
TSum{} -> Nothing
fieldSizeOfPrim :: Platform -> Name -> Maybe Integer
fieldSizeOfPrim platform nn
= case nn of
NameDataTyCon{} -> Just $ platformAddrBytes platform
NamePrimTyCon tc -> fieldSizeOfPrimTyCon platform tc
_ -> Nothing
fieldSizeOfPrimTyCon :: Platform -> PrimTyCon -> Maybe Integer
fieldSizeOfPrimTyCon platform tc
= case tc of
PrimTyConVoid -> Nothing
PrimTyConPtr -> Nothing
PrimTyConAddr -> Just $ platformAddrBytes platform
PrimTyConNat -> Just $ platformNatBytes platform
PrimTyConInt -> Just $ platformNatBytes platform
PrimTyConTag -> Just $ platformTagBytes platform
PrimTyConBool -> Just $ 1
PrimTyConWord bits
| bits `rem` 8 == 0 -> Just $ fromIntegral $ bits `div` 8
| otherwise -> Nothing
PrimTyConFloat bits
| bits `rem` 8 == 0 -> Just $ fromIntegral $ bits `div` 8
| otherwise -> Nothing
PrimTyConVec{} -> Nothing
PrimTyConString -> Nothing