{- Generated by DrIFT (Automatic class derivations for Haskell) -} {-# LINE 1 "src/C/Prims.hs" #-} {-# LANGUAGE OverloadedStrings #-} module C.Prims where import Data.Binary import Data.Monoid(Monoid(..)) import Data.Typeable import qualified Data.Set as Set import Doc.DocLike import Doc.PPrint import PackedString import StringTable.Atom import qualified Cmm.Op as Op import GHC.Exts data CallConv = CCall | StdCall | CApi | Primitive | DotNet deriving(Eq,Ord,Show) {-! derive: Binary !-} data Safety = Safe | Unsafe deriving(Eq,Ord,Show) {-! derive: Binary !-} newtype ExtType = ExtType PackedString deriving(Binary,IsString,Eq,Ord) instance Show ExtType where show (ExtType p) = unpackPS p instance Show Requires where show (Requires s) = show (Set.toList s) newtype Requires = Requires (Set.Set (CallConv,PackedString)) deriving(Eq,Ord,Monoid,Binary) data DotNetPrim = DotNetField | DotNetCtor | DotNetMethod deriving(Typeable, Eq, Ord, Show) {-! derive: Binary !-} primReqs p = f p where f CConst {} = primRequires p f Func {} = primRequires p f IFunc {} = primRequires p f AddrOf {} = primRequires p f _ = mempty data Prim = PrimPrim Atom -- Special primitive implemented in the compiler somehow. | CConst { primRequires :: Requires, primConst :: !PackedString } -- C code which evaluates to a constant | Func { primRequires :: Requires, funcName :: !PackedString, primArgTypes :: [ExtType], primRetType :: ExtType, primRetArgs :: [ExtType], primSafety :: Safety } -- function call with C calling convention | IFunc { primRequires :: Requires, primArgTypes :: [ExtType], primRetType :: ExtType } -- indirect function call with C calling convention | AddrOf { primRequires :: Requires, primConst :: !PackedString -- address of linker name } | Peek { primArgTy :: Op.Ty } -- read value from memory | Poke { primArgTy :: Op.Ty } -- write value to memory | PrimTypeInfo { primArgTy :: Op.Ty, primRetTy :: Op.Ty, primTypeInfo :: !PrimTypeInfo } | PrimString !PackedString -- address of a raw string. encoded in utf8. | PrimDotNet { primStatic :: !Bool, primDotNet :: !DotNetPrim, primIOLike :: !Bool, primAssembly :: !PackedString, primDotNetName :: !PackedString } | Op { primCOp :: Op.Op Op.Ty, primRetTy :: Op.Ty } deriving(Typeable, Eq, Ord, Show) {-! derive: Binary !-} data PrimTypeInfo = PrimSizeOf | PrimMaxBound | PrimMinBound | PrimAlignmentOf | PrimUMaxBound deriving(Typeable, Eq, Ord, Show) {-! derive: Binary !-} primStaticTypeInfo :: Op.Ty -> PrimTypeInfo -> Maybe Integer primStaticTypeInfo (Op.TyBits (Op.Bits b) _) w = Just ans where bits = toInteger b ans = case w of PrimSizeOf -> bits `div` 8 PrimAlignmentOf -> bits `div` 8 PrimMinBound -> negate $ 2^(bits - 1) PrimMaxBound -> 2^(bits - 1) - 1 PrimUMaxBound -> 2^bits - 1 primStaticTypeInfo _ _ = Nothing -- | These primitives may safely be duplicated without affecting performance or -- correctness too adversly. either because they are cheap to begin with, or -- will be recombined in a later pass. primIsCheap :: Prim -> Bool primIsCheap AddrOf {} = True primIsCheap CConst {} = True primIsCheap PrimString {} = True primIsCheap PrimTypeInfo {} = True primIsCheap Op { primCOp = op } = Op.isCheap op primIsCheap _ = False -- | whether a primitive represents a constant expression (assuming all its arguments are constant) -- TODO needs grin support primIsConstant :: Prim -> Bool primIsConstant CConst {} = True primIsConstant AddrOf {} = True primIsConstant PrimString {} = True primIsConstant PrimTypeInfo {} = True primIsConstant Op { primCOp = op } = Op.isEagerSafe op primIsConstant _ = False -- | whether a primitive can be eagarly evaluated. -- TODO needs grin support primEagerSafe :: Prim -> Bool primEagerSafe CConst {} = True primEagerSafe PrimString {} = True primEagerSafe AddrOf {} = True primEagerSafe PrimTypeInfo {} = True primEagerSafe Op { primCOp = op } = Op.isEagerSafe op primEagerSafe _ = False primPrim s = PrimPrim $ toAtom s instance DocLike d => PPrint d ExtType where pprint t = tshow t --instance DocLike d => PPrint d PackedString where -- pprint t = text $ unpackPS t instance DocLike d => PPrint d Prim where pprint (PrimPrim t) = text (fromAtom t) pprint (CConst _ s) = parens (text $ unpackPS s) pprint Func { .. } = parens (tshow primRetType) <> text (unpackPS funcName) <> tupled (map pprint primArgTypes) pprint IFunc { .. } = parens (tshow primRetType) <> parens (char '*') <> tupled (map pprint primArgTypes) pprint (AddrOf _ s) = char '&' <> text (unpackPS s) pprint (PrimString s) = tshow s <> char '#' pprint (Peek t) = char '*' <> tshow t pprint (Poke t) = char '=' <> tshow t pprint Op { primCOp = Op.BinOp bo ta tb, primRetTy = rt } | rt == ta && rt == tb = parens (pprint rt) <> tshow bo pprint Op { primCOp = Op.UnOp bo ta, primRetTy = rt } | rt == ta = parens (pprint rt) <> tshow bo pprint Op { primCOp = op, primRetTy = rt } = parens (pprint rt) <> pprint op pprint PrimDotNet { primDotNet = dn, primDotNetName = nn} = parens (text (unpackPS nn)) pprint PrimTypeInfo { primArgTy = at, primTypeInfo = PrimSizeOf } = text "sizeof" <> parens (tshow at) pprint PrimTypeInfo { primArgTy = at, primTypeInfo = PrimAlignmentOf } = text "alignmentof" <> parens (tshow at) pprint PrimTypeInfo { primArgTy = at, primTypeInfo = PrimMaxBound } = text "max" <> parens (tshow at) pprint PrimTypeInfo { primArgTy = at, primTypeInfo = PrimUMaxBound } = text "umax" <> parens (tshow at) pprint PrimTypeInfo { primArgTy = at, primTypeInfo = PrimMinBound } = text "min" <> parens (tshow at) instance DocLike d => PPrint d Op.Ty where pprintAssoc _ n p = text (showsPrec n p "") instance (DocLike d,Show v) => PPrint d (Op.Op v) where pprintAssoc _ n p = text (showsPrec n p "") parseDotNetFFI :: Monad m => String -> m Prim parseDotNetFFI s = ans where init = PrimDotNet { primIOLike = False, primStatic = False, primDotNet = DotNetField, primAssembly = packString "", primDotNetName = packString "" } ans = case words s of ("static":rs) -> f rs init { primStatic = True } rs -> f rs init f ("field":rs) dn = g dn { primDotNet = DotNetField } rs f ("ctor":rs) dn = g dn { primDotNet = DotNetCtor } rs f ("method":rs) dn = g dn { primDotNet = DotNetMethod } rs f _ _ = fail "invalid .NET ffi specification" g dn ['[':rs] | (as,']':nm) <- span (/= ']') rs = return dn { primAssembly = packString as, primDotNetName = packString nm } g dn [n] = return dn { primDotNetName = packString n } g _ _ = fail "invalid .NET ffi specification" {-* Generated by DrIFT : Look, but Don't Touch. *-} instance Data.Binary.Binary CallConv where put CCall = do Data.Binary.putWord8 0 put StdCall = do Data.Binary.putWord8 1 put CApi = do Data.Binary.putWord8 2 put Primitive = do Data.Binary.putWord8 3 put DotNet = do Data.Binary.putWord8 4 get = do h <- Data.Binary.getWord8 case h of 0 -> do return CCall 1 -> do return StdCall 2 -> do return CApi 3 -> do return Primitive 4 -> do return DotNet _ -> fail "invalid binary data found" instance Data.Binary.Binary Safety where put Safe = do Data.Binary.putWord8 0 put Unsafe = do Data.Binary.putWord8 1 get = do h <- Data.Binary.getWord8 case h of 0 -> do return Safe 1 -> do return Unsafe _ -> fail "invalid binary data found" instance Data.Binary.Binary DotNetPrim where put DotNetField = do Data.Binary.putWord8 0 put DotNetCtor = do Data.Binary.putWord8 1 put DotNetMethod = do Data.Binary.putWord8 2 get = do h <- Data.Binary.getWord8 case h of 0 -> do return DotNetField 1 -> do return DotNetCtor 2 -> do return DotNetMethod _ -> fail "invalid binary data found" instance Data.Binary.Binary Prim where put (PrimPrim aa) = do Data.Binary.putWord8 0 Data.Binary.put aa put (CConst ab ac) = do Data.Binary.putWord8 1 Data.Binary.put ab Data.Binary.put ac put (Func ad ae af ag ah ai) = do Data.Binary.putWord8 2 Data.Binary.put ad Data.Binary.put ae Data.Binary.put af Data.Binary.put ag Data.Binary.put ah Data.Binary.put ai put (IFunc aj ak al) = do Data.Binary.putWord8 3 Data.Binary.put aj Data.Binary.put ak Data.Binary.put al put (AddrOf am an) = do Data.Binary.putWord8 4 Data.Binary.put am Data.Binary.put an put (Peek ao) = do Data.Binary.putWord8 5 Data.Binary.put ao put (Poke ap) = do Data.Binary.putWord8 6 Data.Binary.put ap put (PrimTypeInfo aq ar as) = do Data.Binary.putWord8 7 Data.Binary.put aq Data.Binary.put ar Data.Binary.put as put (PrimString at) = do Data.Binary.putWord8 8 Data.Binary.put at put (PrimDotNet au av aw ax ay) = do Data.Binary.putWord8 9 Data.Binary.put au Data.Binary.put av Data.Binary.put aw Data.Binary.put ax Data.Binary.put ay put (Op az aA) = do Data.Binary.putWord8 10 Data.Binary.put az Data.Binary.put aA get = do h <- Data.Binary.getWord8 case h of 0 -> do aa <- Data.Binary.get return (PrimPrim aa) 1 -> do ab <- Data.Binary.get ac <- Data.Binary.get return (CConst ab ac) 2 -> do ad <- Data.Binary.get ae <- Data.Binary.get af <- Data.Binary.get ag <- Data.Binary.get ah <- Data.Binary.get ai <- Data.Binary.get return (Func ad ae af ag ah ai) 3 -> do aj <- Data.Binary.get ak <- Data.Binary.get al <- Data.Binary.get return (IFunc aj ak al) 4 -> do am <- Data.Binary.get an <- Data.Binary.get return (AddrOf am an) 5 -> do ao <- Data.Binary.get return (Peek ao) 6 -> do ap <- Data.Binary.get return (Poke ap) 7 -> do aq <- Data.Binary.get ar <- Data.Binary.get as <- Data.Binary.get return (PrimTypeInfo aq ar as) 8 -> do at <- Data.Binary.get return (PrimString at) 9 -> do au <- Data.Binary.get av <- Data.Binary.get aw <- Data.Binary.get ax <- Data.Binary.get ay <- Data.Binary.get return (PrimDotNet au av aw ax ay) 10 -> do az <- Data.Binary.get aA <- Data.Binary.get return (Op az aA) _ -> fail "invalid binary data found" instance Data.Binary.Binary PrimTypeInfo where put PrimSizeOf = do Data.Binary.putWord8 0 put PrimMaxBound = do Data.Binary.putWord8 1 put PrimMinBound = do Data.Binary.putWord8 2 put PrimAlignmentOf = do Data.Binary.putWord8 3 put PrimUMaxBound = do Data.Binary.putWord8 4 get = do h <- Data.Binary.getWord8 case h of 0 -> do return PrimSizeOf 1 -> do return PrimMaxBound 2 -> do return PrimMinBound 3 -> do return PrimAlignmentOf 4 -> do return PrimUMaxBound _ -> fail "invalid binary data found" -- Imported from other files :-