Literal

ghc-8.2.2: The GHC API

Safe Haskell | None
Language | Haskell2010

Literal

Contents

- Main data type
  - Creating Literals
  - Operations on Literals
  - Predicates on Literals and their contents
  - Coercions

Synopsis

- data Literal
  - = MachChar Char
  - | MachStr ByteString
  - | MachNullAddr
  - | MachInt Integer
  - | MachInt64 Integer
  - | MachWord Integer
  - | MachWord64 Integer
  - | MachFloat Rational
  - | MachDouble Rational
  - | MachLabel FastString (Maybe Int) FunctionOrData
  - | LitInteger Integer Type
- mkMachInt :: DynFlags -> Integer -> Literal
- mkMachIntWrap :: DynFlags -> Integer -> Literal
- mkMachWord :: DynFlags -> Integer -> Literal
- mkMachWordWrap :: DynFlags -> Integer -> Literal
- mkMachInt64 :: Integer -> Literal
- mkMachInt64Wrap :: Integer -> Literal
- mkMachWord64 :: Integer -> Literal
- mkMachWord64Wrap :: Integer -> Literal
- mkMachFloat :: Rational -> Literal
- mkMachDouble :: Rational -> Literal
- mkMachChar :: Char -> Literal
- mkMachString :: String -> Literal
- mkLitInteger :: Integer -> Type -> Literal
- literalType :: Literal -> Type
- absentLiteralOf :: TyCon -> Maybe Literal
- pprLiteral :: (SDoc -> SDoc) -> Literal -> SDoc
- 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
- 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

data Literal Source #

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`)

Constructors

MachChar Char | `Char#` - at least 31 bits. Create with `mkMachChar`
MachStr ByteString | A string-literal: stored and emitted UTF-8 encoded, we'll arrange to decode it at runtime. Also emitted with a `'\0'` terminator. Create with `mkMachString`
MachNullAddr | The `NULL` pointer, the only pointer value that can be represented as a Literal. Create with `nullAddrLit`
MachInt Integer | `Int#` - according to target machine
MachInt64 Integer | `Int64#` - exactly 64 bits
MachWord Integer | `Word#` - according to target machine
MachWord64 Integer | `Word64#` - exactly 64 bits
MachFloat Rational | `Float#`. Create with `mkMachFloat`
MachDouble Rational | `Double#`. Create with `mkMachDouble`
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 `stdcall` labels. `Just x` => `<x>` will be appended to label name when emitting assembly.
LitInteger Integer Type |

Instances

Eq Literal # |
Methods (==) :: Literal -> Literal -> Bool # (/=) :: Literal -> Literal -> Bool #
Data Literal # |
Methods 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 # |
Methods compare :: Literal -> Literal -> Ordering # (<) :: Literal -> Literal -> Bool # (<=) :: Literal -> Literal -> Bool # (>) :: Literal -> Literal -> Bool # (>=) :: Literal -> Literal -> Bool # max :: Literal -> Literal -> Literal # min :: Literal -> Literal -> Literal #
Outputable Literal # |
Methods ppr :: Literal -> SDoc Source # pprPrec :: Rational -> Literal -> SDoc Source #
Binary Literal # |
Methods put_ :: BinHandle -> Literal -> IO () Source # put :: BinHandle -> Literal -> IO (Bin * Literal) Source # get :: BinHandle -> IO Literal Source #

## Creating Literals

mkMachInt :: DynFlags -> Integer -> Literal Source #

Creates a `Literal` of type `Int#`

mkMachIntWrap :: DynFlags -> Integer -> Literal Source #

Creates a `Literal` of type `Int#`. If the argument is out of the (target-dependent) range, it is wrapped.

mkMachWord :: DynFlags -> Integer -> Literal Source #

Creates a `Literal` of type `Word#`

mkMachWordWrap :: DynFlags -> Integer -> Literal Source #

Creates a `Literal` of type `Word#`. If the argument is out of the (target-dependent) range, it is wrapped.

mkMachInt64 :: Integer -> Literal Source #

Creates a `Literal` of type `Int64#`

mkMachInt64Wrap :: Integer -> Literal Source #

Creates a `Literal` of type `Int64#`. If the argument is out of the range, it is wrapped.

mkMachWord64 :: Integer -> Literal Source #

Creates a `Literal` of type `Word64#`

mkMachWord64Wrap :: Integer -> Literal Source #

Creates a `Literal` of type `Word64#`. If the argument is out of the range, it is wrapped.

mkMachFloat :: Rational -> Literal Source #

Creates a `Literal` of type `Float#`

mkMachDouble :: Rational -> Literal Source #

Creates a `Literal` of type `Double#`

mkMachChar :: Char -> Literal Source #

Creates a `Literal` of type `Char#`

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`

mkLitInteger :: Integer -> Type -> Literal Source #

## Operations on Literals

literalType :: Literal -> Type Source #

Find the Haskell `Type` the literal occupies

absentLiteralOf :: TyCon -> Maybe Literal Source #

pprLiteral :: (SDoc -> SDoc) -> Literal -> SDoc Source #

## Predicates on Literals and their contents

litIsDupable :: DynFlags -> Literal -> Bool Source #

True if code space does not go bad if we duplicate this literal Currently we treat it just like `litIsTrivial`

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" `plusAddr`# 5)`. 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.

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 #

inIntRange :: DynFlags -> Integer -> Bool Source #

inWordRange :: DynFlags -> Integer -> 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 #

litValue :: Literal -> Integer Source #

Returns the `Integer` contained in the `Literal`, for when that makes sense, i.e. for `Char`, `Int`, `Word` and `LitInteger`.

isLitValue :: Literal -> Bool Source #

Indicate if the `Literal` contains an `Integer` value, e.g. `Char`, `Int`, `Word` and `LitInteger`.

isLitValue_maybe :: Literal -> Maybe Integer Source #

Returns the `Integer` contained in the `Literal`, for when that makes sense, i.e. for `Char`, `Int`, `Word` and `LitInteger`.

mapLitValue :: DynFlags -> (Integer -> Integer) -> Literal -> Literal Source #

Apply a function to the `Integer` contained in the `Literal`, for when that makes sense, e.g. for `Char`, `Int`, `Word` and `LitInteger`. For fixed-size integral literals, the result will be wrapped in accordance with the semantics of the target type.

## Coercions

word2IntLit :: DynFlags -> Literal -> Literal Source #

int2WordLit :: DynFlags -> Literal -> Literal Source #

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 #

nullAddrLit :: Literal Source #

float2DoubleLit :: Literal -> Literal Source #

double2FloatLit :: Literal -> Literal Source #