Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- data Literal
- data LitNumType
- mkMachInt :: DynFlags -> Integer -> Literal
- mkMachIntWrap :: DynFlags -> Integer -> Literal
- mkMachIntWrapC :: DynFlags -> Integer -> (Literal, Bool)
- mkMachWord :: DynFlags -> Integer -> Literal
- mkMachWordWrap :: DynFlags -> Integer -> Literal
- mkMachWordWrapC :: DynFlags -> Integer -> (Literal, Bool)
- mkMachInt64 :: Integer -> Literal
- mkMachInt64Wrap :: DynFlags -> Integer -> Literal
- mkMachWord64 :: Integer -> Literal
- mkMachWord64Wrap :: DynFlags -> Integer -> Literal
- mkMachFloat :: Rational -> Literal
- mkMachDouble :: Rational -> Literal
- mkMachChar :: Char -> Literal
- mkMachString :: String -> Literal
- mkLitInteger :: Integer -> Type -> Literal
- mkLitNatural :: Integer -> Type -> Literal
- mkLitNumber :: DynFlags -> LitNumType -> Integer -> Type -> Literal
- mkLitNumberWrap :: DynFlags -> LitNumType -> Integer -> Type -> Literal
- literalType :: Literal -> Type
- absentLiteralOf :: TyCon -> Maybe Literal
- pprLiteral :: (SDoc -> SDoc) -> Literal -> SDoc
- litNumIsSigned :: LitNumType -> Bool
- litNumCheckRange :: DynFlags -> LitNumType -> Integer -> Bool
- litIsDupable :: DynFlags -> Literal -> Bool
- litIsTrivial :: Literal -> Bool
- litIsLifted :: Literal -> Bool
- inIntRange :: DynFlags -> Integer -> Bool
- inWordRange :: DynFlags -> Integer -> Bool
- tARGET_MAX_INT :: DynFlags -> Integer
- inCharRange :: Char -> Bool
- isZeroLit :: Literal -> Bool
- litFitsInChar :: Literal -> Bool
- litValue :: Literal -> Integer
- isLitValue :: Literal -> Bool
- isLitValue_maybe :: Literal -> Maybe Integer
- mapLitValue :: DynFlags -> (Integer -> Integer) -> Literal -> Literal
- word2IntLit :: DynFlags -> Literal -> Literal
- int2WordLit :: DynFlags -> Literal -> Literal
- narrowLit :: forall a. Integral a => Proxy a -> Literal -> Literal
- narrow8IntLit :: Literal -> Literal
- narrow16IntLit :: Literal -> Literal
- narrow32IntLit :: Literal -> Literal
- narrow8WordLit :: Literal -> Literal
- narrow16WordLit :: Literal -> Literal
- narrow32WordLit :: Literal -> Literal
- char2IntLit :: Literal -> Literal
- int2CharLit :: Literal -> Literal
- float2IntLit :: Literal -> Literal
- int2FloatLit :: Literal -> Literal
- double2IntLit :: Literal -> Literal
- int2DoubleLit :: Literal -> Literal
- nullAddrLit :: Literal
- float2DoubleLit :: Literal -> Literal
- double2FloatLit :: Literal -> Literal
Main data type
So-called Literal
s are one of:
- An unboxed (machine) literal (
MachInt
,MachFloat
, etc.), which is presumed to be surrounded by appropriate constructors (Int#
, etc.), so that the overall thing makes sense.
We maintain the invariant that the Integer
the Mach{Int,Word}*
constructors are actually in the (possibly target-dependent) range.
The mkMach{Int,Word}*Wrap smart constructors ensure this by applying
the target machine's wrapping semantics. Use these in situations
where you know the wrapping semantics are correct.
- The literal derived from the label mentioned in a "foreign label"
declaration (
MachLabel
)
MachChar Char |
|
LitNumber !LitNumType !Integer Type | |
MachStr ByteString | A string-literal: stored and emitted
UTF-8 encoded, we'll arrange to decode it
at runtime. Also emitted with a |
MachNullAddr | The |
MachFloat Rational |
|
MachDouble Rational |
|
MachLabel FastString (Maybe Int) FunctionOrData | A label literal. Parameters: 1) The name of the symbol mentioned in the declaration 2) The size (in bytes) of the arguments
the label expects. Only applicable with
|
Instances
Eq Literal # | |
Data Literal # | |
Defined in Literal gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Literal -> c Literal Source # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Literal Source # toConstr :: Literal -> Constr Source # dataTypeOf :: Literal -> DataType Source # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Literal) Source # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Literal) Source # gmapT :: (forall b. Data b => b -> b) -> Literal -> Literal Source # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Literal -> r Source # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Literal -> r Source # gmapQ :: (forall d. Data d => d -> u) -> Literal -> [u] Source # gmapQi :: Int -> (forall d. Data d => d -> u) -> Literal -> u Source # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Literal -> m Literal Source # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Literal -> m Literal Source # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Literal -> m Literal Source # | |
Ord Literal # | |
Outputable Literal # | |
Binary Literal # | |
data LitNumType Source #
Numeric literal type
LitNumInteger |
|
LitNumNatural |
|
LitNumInt |
|
LitNumInt64 |
|
LitNumWord |
|
LitNumWord64 |
|
Instances
Creating Literals
mkMachIntWrap :: DynFlags -> Integer -> Literal Source #
Creates a Literal
of type Int#
.
If the argument is out of the (target-dependent) range, it is wrapped.
See Note [WordInt underflowoverflow]
mkMachWordWrap :: DynFlags -> Integer -> Literal Source #
Creates a Literal
of type Word#
.
If the argument is out of the (target-dependent) range, it is wrapped.
See Note [WordInt underflowoverflow]
mkMachInt64Wrap :: DynFlags -> Integer -> Literal Source #
Creates a Literal
of type Int64#
.
If the argument is out of the range, it is wrapped.
mkMachWord64Wrap :: DynFlags -> Integer -> Literal Source #
Creates a Literal
of type Word64#
.
If the argument is out of the range, it is wrapped.
mkMachString :: String -> Literal Source #
Creates a Literal
of type Addr#
, which is appropriate for passing to
e.g. some of the "error" functions in GHC.Err such as GHC.Err.runtimeError
mkLitNumber :: DynFlags -> LitNumType -> Integer -> Type -> Literal Source #
Create a numeric Literal
of the given type
mkLitNumberWrap :: DynFlags -> LitNumType -> Integer -> Type -> Literal Source #
Create a numeric Literal
of the given type
Operations on Literals
litNumIsSigned :: LitNumType -> Bool Source #
Indicate if a numeric literal type supports negative numbers
litNumCheckRange :: DynFlags -> LitNumType -> Integer -> Bool Source #
Check that a given number is in the range of a numeric literal
Predicates on Literals and their contents
litIsDupable :: DynFlags -> Literal -> Bool Source #
True if code space does not go bad if we duplicate this literal
litIsTrivial :: Literal -> Bool Source #
True if there is absolutely no penalty to duplicating the literal. False principally of strings.
"Why?", you say? I'm glad you asked. Well, for one duplicating strings would blow up code sizes. Not only this, it's also unsafe.
Consider a program that wants to traverse a string. One way it might do this is to first compute the Addr# pointing to the end of the string, and then, starting from the beginning, bump a pointer using eqAddr# to determine the end. For instance,
-- Given pointers to the start and end of a string, count how many zeros -- the string contains. countZeros :: Addr -> -> Int countZeros start end = go start 0 where go off n | off `addrEq#` end = n | otherwise = go (off `plusAddr#` 1) n' where n' | isTrue off 0 0#) = n + 1 | otherwise = n
Consider what happens if we considered strings to be trivial (and therefore
duplicable) and emitted a call like countZeros "hello"
. The beginning and end pointers do not belong to the same
string, meaning that an iteration like the above would blow up terribly.
This is what happened in #12757.plusAddr
# 5)
Ultimately the solution here is to make primitive strings a bit more structured, ensuring that the compiler can't inline in ways that will break user code. One approach to this is described in #8472.
litIsLifted :: Literal -> Bool Source #
tARGET_MAX_INT :: DynFlags -> Integer Source #
inCharRange :: Char -> Bool Source #
isZeroLit :: Literal -> Bool Source #
Tests whether the literal represents a zero of whatever type it is
litFitsInChar :: Literal -> Bool Source #
isLitValue :: Literal -> Bool Source #
Coercions
narrowLit :: forall a. Integral a => Proxy a -> Literal -> Literal Source #
Narrow a literal number (unchecked result range)
narrow8IntLit :: Literal -> Literal Source #
narrow16IntLit :: Literal -> Literal Source #
narrow32IntLit :: Literal -> Literal Source #
narrow8WordLit :: Literal -> Literal Source #
narrow16WordLit :: Literal -> Literal Source #
narrow32WordLit :: Literal -> Literal Source #
char2IntLit :: Literal -> Literal Source #
int2CharLit :: Literal -> Literal Source #
float2IntLit :: Literal -> Literal Source #
int2FloatLit :: Literal -> Literal Source #
double2IntLit :: Literal -> Literal Source #
int2DoubleLit :: Literal -> Literal Source #
float2DoubleLit :: Literal -> Literal Source #
double2FloatLit :: Literal -> Literal Source #