-- text between curly brackets. This is a kludge to enable
-- processors of this file to easily get hold of simple info
-- (eg, out_of_line), whilst avoiding parsing complex expressions
--- needed for strictness and usage info.
+-- needed for strictness info.
defaults
has_side_effects = False
needs_wrapper = False
can_fail = False
strictness = { \ arity -> mkStrictSig (mkTopDmdType (replicate arity lazyDmd) TopRes) }
- usage = { nomangle other }
-- Currently, documentation is produced using latex, so contents of
-- description fields should be legal latex. Descriptions can contain
primops are fixed, but their {\it types} vary according to
the value of {\tt WORD\_SIZE\_IN\_BITS}. For example, if word
size is at least 32 bits then an operator like
- \texttt{indexInt32Array\#} has type {\tt ByteArr\# -> Int\#
- -> Int\#}; otherwise it has type {\tt ByteArr\# -> Int\# ->
+ \texttt{indexInt32Array\#} has type {\tt ByteArray\# -> Int\#
+ -> Int\#}; otherwise it has type {\tt ByteArray\# -> Int\# ->
Int32\#}. This approach confines the necessary {\tt
\#if}-defs to this file; no conditional compilation is needed
in the files that expose these primops.
{Satisfies \texttt{(quotInt\# x y) *\# y +\# (remInt\# x y) == x}.}
with can_fail = True
-primop IntGcdOp "gcdInt#" Dyadic Int# -> Int# -> Int#
- with out_of_line = True
-
primop IntNegOp "negateInt#" Monadic Int# -> Int#
primop IntAddCOp "addIntC#" GenPrimOp Int# -> Int# -> (# Int#, Int# #)
{Add with carry. First member of result is (wrapped) sum;
primop Int2FloatOp "int2Float#" GenPrimOp Int# -> Float#
primop Int2DoubleOp "int2Double#" GenPrimOp Int# -> Double#
-primop Int2IntegerOp "int2Integer#"
- GenPrimOp Int# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
primop ISllOp "uncheckedIShiftL#" GenPrimOp Int# -> Int# -> Int#
{Shift left. Result undefined if shift amount is not
in the range 0 to word size - 1 inclusive.}
primop Word2IntOp "word2Int#" GenPrimOp Word# -> Int#
-primop Word2IntegerOp "word2Integer#" GenPrimOp
- Word# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
primop WordGtOp "gtWord#" Compare Word# -> Word# -> Bool
primop WordGeOp "geWord#" Compare Word# -> Word# -> Bool
primop WordEqOp "eqWord#" Compare Word# -> Word# -> Bool
primtype Int32#
-primop Int32ToIntegerOp "int32ToInteger#" GenPrimOp
- Int32# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
-
------------------------------------------------------------------------
section "Word32#"
{Operations on 32-bit unsigned words. This type is only used
primtype Word32#
-primop Word32ToIntegerOp "word32ToInteger#" GenPrimOp
- Word32# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
-
#endif
primtype Int64#
-primop Int64ToIntegerOp "int64ToInteger#" GenPrimOp
- Int64# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
------------------------------------------------------------------------
section "Word64#"
{Operations on 64-bit unsigned words. This type is only used
primtype Word64#
-primop Word64ToIntegerOp "word64ToInteger#" GenPrimOp
- Word64# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
#endif
------------------------------------------------------------------------
-section "Integer#"
- {Operations on arbitrary-precision integers. These operations are
-implemented via the GMP package. An integer is represented as a pair
-consisting of an {\tt Int\#} representing the number of 'limbs' in use and
-the sign, and a {\tt ByteArr\#} containing the 'limbs' themselves. Such pairs
-are returned as unboxed pairs, but must be passed as separate
-components.
-
-For .NET these operations are implemented by foreign imports, so the
-primops are omitted.}
-------------------------------------------------------------------------
-
-#ifndef ILX
-
-primop IntegerAddOp "plusInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
- with commutable = True
- out_of_line = True
-
-primop IntegerSubOp "minusInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
-primop IntegerMulOp "timesInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
- with commutable = True
- out_of_line = True
-
-primop IntegerGcdOp "gcdInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
- {Greatest common divisor.}
- with commutable = True
- out_of_line = True
-
-primop IntegerIntGcdOp "gcdIntegerInt#" GenPrimOp
- Int# -> ByteArr# -> Int# -> Int#
- {Greatest common divisor, where second argument is an ordinary {\tt Int\#}.}
- with out_of_line = True
-
-primop IntegerDivExactOp "divExactInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
- {Divisor is guaranteed to be a factor of dividend.}
- with out_of_line = True
-
-primop IntegerQuotOp "quotInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
- {Rounds towards zero.}
- with out_of_line = True
-
-primop IntegerRemOp "remInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
- {Satisfies \texttt{plusInteger\# (timesInteger\# (quotInteger\# x y) y) (remInteger\# x y) == x}.}
- with out_of_line = True
-
-primop IntegerCmpOp "cmpInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> Int#
- {Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument.}
- with needs_wrapper = True
- out_of_line = True
-
-primop IntegerCmpIntOp "cmpIntegerInt#" GenPrimOp
- Int# -> ByteArr# -> Int# -> Int#
- {Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument, which
- is an ordinary Int\#.}
- with needs_wrapper = True
- out_of_line = True
-
-primop IntegerQuotRemOp "quotRemInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr#, Int#, ByteArr# #)
- {Compute quot and rem simulaneously.}
- with can_fail = True
- out_of_line = True
-
-primop IntegerDivModOp "divModInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr#, Int#, ByteArr# #)
- {Compute div and mod simultaneously, where div rounds towards negative infinity
- and\texttt{(q,r) = divModInteger\#(x,y)} implies \texttt{plusInteger\# (timesInteger\# q y) r = x}.}
- with can_fail = True
- out_of_line = True
-
-primop Integer2IntOp "integer2Int#" GenPrimOp
- Int# -> ByteArr# -> Int#
- with needs_wrapper = True
- out_of_line = True
-
-primop Integer2WordOp "integer2Word#" GenPrimOp
- Int# -> ByteArr# -> Word#
- with needs_wrapper = True
- out_of_line = True
-
-#if WORD_SIZE_IN_BITS < 32
-primop IntegerToInt32Op "integerToInt32#" GenPrimOp
- Int# -> ByteArr# -> Int32#
-
-primop IntegerToWord32Op "integerToWord32#" GenPrimOp
- Int# -> ByteArr# -> Word32#
-#endif
-
-primop IntegerAndOp "andInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
-primop IntegerOrOp "orInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
-primop IntegerXorOp "xorInteger#" GenPrimOp
- Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
-primop IntegerComplementOp "complementInteger#" GenPrimOp
- Int# -> ByteArr# -> (# Int#, ByteArr# #)
- with out_of_line = True
-
-#endif /* ndef ILX */
-
-------------------------------------------------------------------------
section "Double#"
{Operations on double-precision (64 bit) floating-point numbers.}
------------------------------------------------------------------------
primop DoubleNegOp "negateDouble#" Monadic Double# -> Double#
primop Double2IntOp "double2Int#" GenPrimOp Double# -> Int#
+ {Truncates a {\tt Double#} value to the nearest {\tt Int#}.
+ Results are undefined if the truncation if truncation yields
+ a value outside the range of {\tt Int#}.}
+
primop Double2FloatOp "double2Float#" GenPrimOp Double# -> Float#
primop DoubleExpOp "expDouble#" Monadic
{Exponentiation.}
with needs_wrapper = True
-primop DoubleDecodeOp "decodeDouble#" GenPrimOp
- Double# -> (# Int#, Int#, ByteArr# #)
- {Convert to arbitrary-precision integer.
- First {\tt Int\#} in result is the exponent; second {\tt Int\#} and {\tt ByteArr\#}
- represent an {\tt Integer\#} holding the mantissa.}
+primop DoubleDecode_2IntOp "decodeDouble_2Int#" GenPrimOp
+ Double# -> (# Int#, Word#, Word#, Int# #)
+ {Convert to integer.
+ First component of the result is -1 or 1, indicating the sign of the
+ mantissa. The next two are the high and low 32 bits of the mantissa
+ respectively, and the last is the exponent.}
with out_of_line = True
------------------------------------------------------------------------
primop FloatNegOp "negateFloat#" Monadic Float# -> Float#
primop Float2IntOp "float2Int#" GenPrimOp Float# -> Int#
+ {Truncates a {\tt Float#} value to the nearest {\tt Int#}.
+ Results are undefined if the truncation if truncation yields
+ a value outside the range of {\tt Int#}.}
primop FloatExpOp "expFloat#" Monadic
Float# -> Float#
primop Float2DoubleOp "float2Double#" GenPrimOp Float# -> Double#
-primop FloatDecodeOp "decodeFloat#" GenPrimOp
- Float# -> (# Int#, Int#, ByteArr# #)
- {Convert to arbitrary-precision integer.
- First {\tt Int\#} in result is the exponent; second {\tt Int\#} and {\tt ByteArr\#}
- represent an {\tt Integer\#} holding the mantissa.}
+primop FloatDecode_IntOp "decodeFloat_Int#" GenPrimOp
+ Float# -> (# Int#, Int# #)
+ {Convert to integers.
+ First {\tt Int\#} in result is the mantissa; second is the exponent.}
with out_of_line = True
------------------------------------------------------------------------
primtype Array# a
-primtype MutArr# s a
+primtype MutableArray# s a
primop NewArrayOp "newArray#" GenPrimOp
- Int# -> a -> State# s -> (# State# s, MutArr# s a #)
+ Int# -> a -> State# s -> (# State# s, MutableArray# s a #)
{Create a new mutable array of specified size (in bytes),
in the specified state thread,
with each element containing the specified initial value.}
with
- usage = { mangle NewArrayOp [mkP, mkM, mkP] mkM }
out_of_line = True
+ has_side_effects = True
primop SameMutableArrayOp "sameMutableArray#" GenPrimOp
- MutArr# s a -> MutArr# s a -> Bool
- with
- usage = { mangle SameMutableArrayOp [mkP, mkP] mkM }
+ MutableArray# s a -> MutableArray# s a -> Bool
primop ReadArrayOp "readArray#" GenPrimOp
- MutArr# s a -> Int# -> State# s -> (# State# s, a #)
+ MutableArray# s a -> Int# -> State# s -> (# State# s, a #)
{Read from specified index of mutable array. Result is not yet evaluated.}
with
- usage = { mangle ReadArrayOp [mkM, mkP, mkP] mkM }
+ has_side_effects = True
primop WriteArrayOp "writeArray#" GenPrimOp
- MutArr# s a -> Int# -> a -> State# s -> State# s
+ MutableArray# s a -> Int# -> a -> State# s -> State# s
{Write to specified index of mutable array.}
with
- usage = { mangle WriteArrayOp [mkM, mkP, mkM, mkP] mkR }
has_side_effects = True
primop IndexArrayOp "indexArray#" GenPrimOp
Array# a -> Int# -> (# a #)
{Read from specified index of immutable array. Result is packaged into
an unboxed singleton; the result itself is not yet evaluated.}
- with
- usage = { mangle IndexArrayOp [mkM, mkP] mkM }
primop UnsafeFreezeArrayOp "unsafeFreezeArray#" GenPrimOp
- MutArr# s a -> State# s -> (# State# s, Array# a #)
+ MutableArray# s a -> State# s -> (# State# s, Array# a #)
{Make a mutable array immutable, without copying.}
with
- usage = { mangle UnsafeFreezeArrayOp [mkM, mkP] mkM }
has_side_effects = True
primop UnsafeThawArrayOp "unsafeThawArray#" GenPrimOp
- Array# a -> State# s -> (# State# s, MutArr# s a #)
+ Array# a -> State# s -> (# State# s, MutableArray# s a #)
{Make an immutable array mutable, without copying.}
with
- usage = { mangle UnsafeThawArrayOp [mkM, mkP] mkM }
out_of_line = True
+ has_side_effects = True
------------------------------------------------------------------------
section "Byte Arrays"
{Operations on {\tt ByteArray\#}. A {\tt ByteArray\#} is a just a region of
- raw memory in the garbage-collected heap, which is not scanned
- for pointers. It carries its own size (in bytes). There are
- three sets of operations for accessing byte array contents:
- index for reading from immutable byte arrays, and read/write
- for mutable byte arrays. Each set contains operations for
- a range of useful primitive data types. Each operation takes
- an offset measured in terms of the size fo the primitive type
- being read or written.}
+ raw memory in the garbage-collected heap, which is not
+ scanned for pointers. It carries its own size (in bytes,
+ rounded up to the nearest multiple of a word). There are
+ three sets of operations for accessing byte array contents:
+ index for reading from immutable byte arrays, and read/write
+ for mutable byte arrays. Each set contains operations for a
+ range of useful primitive data types. Each operation takes
+ an offset measured in terms of the size fo the primitive type
+ being read or written.}
------------------------------------------------------------------------
-primtype ByteArr#
+primtype ByteArray#
-primtype MutByteArr# s
+primtype MutableByteArray# s
primop NewByteArrayOp_Char "newByteArray#" GenPrimOp
- Int# -> State# s -> (# State# s, MutByteArr# s #)
+ Int# -> State# s -> (# State# s, MutableByteArray# s #)
{Create a new mutable byte array of specified size (in bytes), in
the specified state thread.}
with out_of_line = True
+ has_side_effects = True
primop NewPinnedByteArrayOp_Char "newPinnedByteArray#" GenPrimOp
- Int# -> State# s -> (# State# s, MutByteArr# s #)
+ Int# -> State# s -> (# State# s, MutableByteArray# s #)
{Create a mutable byte array that the GC guarantees not to move.}
with out_of_line = True
+ has_side_effects = True
+
+primop NewAlignedPinnedByteArrayOp_Char "newAlignedPinnedByteArray#" GenPrimOp
+ Int# -> Int# -> State# s -> (# State# s, MutableByteArray# s #)
+ {Create a mutable byte array, aligned by the specified amount, that the GC guarantees not to move.}
+ with out_of_line = True
+ has_side_effects = True
primop ByteArrayContents_Char "byteArrayContents#" GenPrimOp
- ByteArr# -> Addr#
+ ByteArray# -> Addr#
{Intended for use with pinned arrays; otherwise very unsafe!}
primop SameMutableByteArrayOp "sameMutableByteArray#" GenPrimOp
- MutByteArr# s -> MutByteArr# s -> Bool
+ MutableByteArray# s -> MutableByteArray# s -> Bool
primop UnsafeFreezeByteArrayOp "unsafeFreezeByteArray#" GenPrimOp
- MutByteArr# s -> State# s -> (# State# s, ByteArr# #)
+ MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
{Make a mutable byte array immutable, without copying.}
with
has_side_effects = True
primop SizeofByteArrayOp "sizeofByteArray#" GenPrimOp
- ByteArr# -> Int#
+ ByteArray# -> Int#
+ {Return the size of the array in bytes, rounded up to the nearest multiple
+ of a word.}
primop SizeofMutableByteArrayOp "sizeofMutableByteArray#" GenPrimOp
- MutByteArr# s -> Int#
-
+ MutableByteArray# s -> Int#
+ {Return the size of the array in bytes, rounded up to the nearest multiple
+ of a word.}
primop IndexByteArrayOp_Char "indexCharArray#" GenPrimOp
- ByteArr# -> Int# -> Char#
+ ByteArray# -> Int# -> Char#
{Read 8-bit character; offset in bytes.}
primop IndexByteArrayOp_WideChar "indexWideCharArray#" GenPrimOp
- ByteArr# -> Int# -> Char#
+ ByteArray# -> Int# -> Char#
{Read 31-bit character; offset in 4-byte words.}
primop IndexByteArrayOp_Int "indexIntArray#" GenPrimOp
- ByteArr# -> Int# -> Int#
+ ByteArray# -> Int# -> Int#
primop IndexByteArrayOp_Word "indexWordArray#" GenPrimOp
- ByteArr# -> Int# -> Word#
+ ByteArray# -> Int# -> Word#
primop IndexByteArrayOp_Addr "indexAddrArray#" GenPrimOp
- ByteArr# -> Int# -> Addr#
+ ByteArray# -> Int# -> Addr#
primop IndexByteArrayOp_Float "indexFloatArray#" GenPrimOp
- ByteArr# -> Int# -> Float#
+ ByteArray# -> Int# -> Float#
primop IndexByteArrayOp_Double "indexDoubleArray#" GenPrimOp
- ByteArr# -> Int# -> Double#
+ ByteArray# -> Int# -> Double#
primop IndexByteArrayOp_StablePtr "indexStablePtrArray#" GenPrimOp
- ByteArr# -> Int# -> StablePtr# a
+ ByteArray# -> Int# -> StablePtr# a
primop IndexByteArrayOp_Int8 "indexInt8Array#" GenPrimOp
- ByteArr# -> Int# -> Int#
+ ByteArray# -> Int# -> Int#
primop IndexByteArrayOp_Int16 "indexInt16Array#" GenPrimOp
- ByteArr# -> Int# -> Int#
+ ByteArray# -> Int# -> Int#
primop IndexByteArrayOp_Int32 "indexInt32Array#" GenPrimOp
- ByteArr# -> Int# -> INT32
+ ByteArray# -> Int# -> INT32
primop IndexByteArrayOp_Int64 "indexInt64Array#" GenPrimOp
- ByteArr# -> Int# -> INT64
+ ByteArray# -> Int# -> INT64
primop IndexByteArrayOp_Word8 "indexWord8Array#" GenPrimOp
- ByteArr# -> Int# -> Word#
+ ByteArray# -> Int# -> Word#
primop IndexByteArrayOp_Word16 "indexWord16Array#" GenPrimOp
- ByteArr# -> Int# -> Word#
+ ByteArray# -> Int# -> Word#
primop IndexByteArrayOp_Word32 "indexWord32Array#" GenPrimOp
- ByteArr# -> Int# -> WORD32
+ ByteArray# -> Int# -> WORD32
primop IndexByteArrayOp_Word64 "indexWord64Array#" GenPrimOp
- ByteArr# -> Int# -> WORD64
+ ByteArray# -> Int# -> WORD64
primop ReadByteArrayOp_Char "readCharArray#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Char# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
{Read 8-bit character; offset in bytes.}
+ with has_side_effects = True
primop ReadByteArrayOp_WideChar "readWideCharArray#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Char# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
{Read 31-bit character; offset in 4-byte words.}
+ with has_side_effects = True
primop ReadByteArrayOp_Int "readIntArray#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Int# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
+ with has_side_effects = True
primop ReadByteArrayOp_Word "readWordArray#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Word# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
+ with has_side_effects = True
primop ReadByteArrayOp_Addr "readAddrArray#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Addr# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #)
+ with has_side_effects = True
primop ReadByteArrayOp_Float "readFloatArray#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Float# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #)
+ with has_side_effects = True
primop ReadByteArrayOp_Double "readDoubleArray#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Double# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #)
+ with has_side_effects = True
primop ReadByteArrayOp_StablePtr "readStablePtrArray#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, StablePtr# a #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, StablePtr# a #)
+ with has_side_effects = True
primop ReadByteArrayOp_Int8 "readInt8Array#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Int# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
+ with has_side_effects = True
primop ReadByteArrayOp_Int16 "readInt16Array#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Int# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
+ with has_side_effects = True
primop ReadByteArrayOp_Int32 "readInt32Array#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, INT32 #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, INT32 #)
+ with has_side_effects = True
primop ReadByteArrayOp_Int64 "readInt64Array#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, INT64 #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, INT64 #)
+ with has_side_effects = True
primop ReadByteArrayOp_Word8 "readWord8Array#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Word# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
+ with has_side_effects = True
primop ReadByteArrayOp_Word16 "readWord16Array#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, Word# #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
+ with has_side_effects = True
primop ReadByteArrayOp_Word32 "readWord32Array#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, WORD32 #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD32 #)
+ with has_side_effects = True
primop ReadByteArrayOp_Word64 "readWord64Array#" GenPrimOp
- MutByteArr# s -> Int# -> State# s -> (# State# s, WORD64 #)
+ MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD64 #)
+ with has_side_effects = True
primop WriteByteArrayOp_Char "writeCharArray#" GenPrimOp
- MutByteArr# s -> Int# -> Char# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
{Write 8-bit character; offset in bytes.}
with has_side_effects = True
primop WriteByteArrayOp_WideChar "writeWideCharArray#" GenPrimOp
- MutByteArr# s -> Int# -> Char# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
{Write 31-bit character; offset in 4-byte words.}
with has_side_effects = True
primop WriteByteArrayOp_Int "writeIntArray#" GenPrimOp
- MutByteArr# s -> Int# -> Int# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Word "writeWordArray#" GenPrimOp
- MutByteArr# s -> Int# -> Word# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Addr "writeAddrArray#" GenPrimOp
- MutByteArr# s -> Int# -> Addr# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Addr# -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Float "writeFloatArray#" GenPrimOp
- MutByteArr# s -> Int# -> Float# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Float# -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Double "writeDoubleArray#" GenPrimOp
- MutByteArr# s -> Int# -> Double# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Double# -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_StablePtr "writeStablePtrArray#" GenPrimOp
- MutByteArr# s -> Int# -> StablePtr# a -> State# s -> State# s
+ MutableByteArray# s -> Int# -> StablePtr# a -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Int8 "writeInt8Array#" GenPrimOp
- MutByteArr# s -> Int# -> Int# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Int16 "writeInt16Array#" GenPrimOp
- MutByteArr# s -> Int# -> Int# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Int32 "writeInt32Array#" GenPrimOp
- MutByteArr# s -> Int# -> INT32 -> State# s -> State# s
+ MutableByteArray# s -> Int# -> INT32 -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Int64 "writeInt64Array#" GenPrimOp
- MutByteArr# s -> Int# -> INT64 -> State# s -> State# s
+ MutableByteArray# s -> Int# -> INT64 -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Word8 "writeWord8Array#" GenPrimOp
- MutByteArr# s -> Int# -> Word# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Word16 "writeWord16Array#" GenPrimOp
- MutByteArr# s -> Int# -> Word# -> State# s -> State# s
+ MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Word32 "writeWord32Array#" GenPrimOp
- MutByteArr# s -> Int# -> WORD32 -> State# s -> State# s
+ MutableByteArray# s -> Int# -> WORD32 -> State# s -> State# s
with has_side_effects = True
primop WriteByteArrayOp_Word64 "writeWord64Array#" GenPrimOp
- MutByteArr# s -> Int# -> WORD64 -> State# s -> State# s
+ MutableByteArray# s -> Int# -> WORD64 -> State# s -> State# s
with has_side_effects = True
------------------------------------------------------------------------
primop ReadOffAddrOp_Char "readCharOffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Char# #)
{Reads 8-bit character; offset in bytes.}
+ with has_side_effects = True
primop ReadOffAddrOp_WideChar "readWideCharOffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Char# #)
{Reads 31-bit character; offset in 4-byte words.}
+ with has_side_effects = True
primop ReadOffAddrOp_Int "readIntOffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Int# #)
+ with has_side_effects = True
primop ReadOffAddrOp_Word "readWordOffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Word# #)
+ with has_side_effects = True
primop ReadOffAddrOp_Addr "readAddrOffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Addr# #)
+ with has_side_effects = True
primop ReadOffAddrOp_Float "readFloatOffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Float# #)
+ with has_side_effects = True
primop ReadOffAddrOp_Double "readDoubleOffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Double# #)
+ with has_side_effects = True
primop ReadOffAddrOp_StablePtr "readStablePtrOffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, StablePtr# a #)
+ with has_side_effects = True
primop ReadOffAddrOp_Int8 "readInt8OffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Int# #)
+ with has_side_effects = True
primop ReadOffAddrOp_Int16 "readInt16OffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Int# #)
+ with has_side_effects = True
primop ReadOffAddrOp_Int32 "readInt32OffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, INT32 #)
+ with has_side_effects = True
primop ReadOffAddrOp_Int64 "readInt64OffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, INT64 #)
+ with has_side_effects = True
primop ReadOffAddrOp_Word8 "readWord8OffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Word# #)
+ with has_side_effects = True
primop ReadOffAddrOp_Word16 "readWord16OffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, Word# #)
+ with has_side_effects = True
primop ReadOffAddrOp_Word32 "readWord32OffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, WORD32 #)
+ with has_side_effects = True
primop ReadOffAddrOp_Word64 "readWord64OffAddr#" GenPrimOp
Addr# -> Int# -> State# s -> (# State# s, WORD64 #)
+ with has_side_effects = True
primop WriteOffAddrOp_Char "writeCharOffAddr#" GenPrimOp
a -> State# s -> (# State# s, MutVar# s a #)
{Create {\tt MutVar\#} with specified initial value in specified state thread.}
with
- usage = { mangle NewMutVarOp [mkM, mkP] mkM }
out_of_line = True
+ has_side_effects = True
primop ReadMutVarOp "readMutVar#" GenPrimOp
MutVar# s a -> State# s -> (# State# s, a #)
{Read contents of {\tt MutVar\#}. Result is not yet evaluated.}
with
- usage = { mangle ReadMutVarOp [mkM, mkP] mkM }
+ has_side_effects = True
primop WriteMutVarOp "writeMutVar#" GenPrimOp
MutVar# s a -> a -> State# s -> State# s
{Write contents of {\tt MutVar\#}.}
with
- usage = { mangle WriteMutVarOp [mkM, mkM, mkP] mkR }
has_side_effects = True
primop SameMutVarOp "sameMutVar#" GenPrimOp
MutVar# s a -> MutVar# s a -> Bool
- with
- usage = { mangle SameMutVarOp [mkP, mkP] mkM }
-- not really the right type, but we don't know about pairs here. The
-- correct type is
primop AtomicModifyMutVarOp "atomicModifyMutVar#" GenPrimOp
MutVar# s a -> (a -> b) -> State# s -> (# State# s, c #)
with
- usage = { mangle AtomicModifyMutVarOp [mkP, mkM, mkP] mkM }
- has_side_effects = True
out_of_line = True
+ has_side_effects = True
------------------------------------------------------------------------
section "Exceptions"
-- Catch is actually strict in its first argument
-- but we don't want to tell the strictness
-- analyser about that!
- usage = { mangle CatchOp [mkM, mkM . (inFun CatchOp mkM mkM), mkP] mkM }
- -- [mkO, mkO . (inFun mkM mkO)] mkO
-- might use caught action multiply
out_of_line = True
+ has_side_effects = True
primop RaiseOp "raise#" GenPrimOp
a -> b
with
- strictness = { \ arity -> mkStrictSig (mkTopDmdType [lazyDmd] BotRes) }
+ strictness = { \ _arity -> mkStrictSig (mkTopDmdType [lazyDmd] BotRes) }
-- NB: result is bottom
- usage = { mangle RaiseOp [mkM] mkM }
out_of_line = True
-- raiseIO# needs to be a primop, because exceptions in the IO monad
a -> State# RealWorld -> (# State# RealWorld, b #)
with
out_of_line = True
+ has_side_effects = True
primop BlockAsyncExceptionsOp "blockAsyncExceptions#" GenPrimOp
(State# RealWorld -> (# State# RealWorld, a #))
-> (State# RealWorld -> (# State# RealWorld, a #))
with
out_of_line = True
+ has_side_effects = True
primop UnblockAsyncExceptionsOp "unblockAsyncExceptions#" GenPrimOp
(State# RealWorld -> (# State# RealWorld, a #))
-> (State# RealWorld -> (# State# RealWorld, a #))
with
out_of_line = True
+ has_side_effects = True
+
+primop AsyncExceptionsBlockedOp "asyncExceptionsBlocked#" GenPrimOp
+ State# RealWorld -> (# State# RealWorld, Int# #)
+ with
+ out_of_line = True
+ has_side_effects = True
------------------------------------------------------------------------
section "STM-accessible Mutable Variables"
{Create a new {\tt TVar\#} holding a specified initial value.}
with
out_of_line = True
+ has_side_effects = True
primop ReadTVarOp "readTVar#" GenPrimOp
TVar# s a
{Read contents of {\tt TVar\#}. Result is not yet evaluated.}
with
out_of_line = True
+ has_side_effects = True
+
+primop ReadTVarIOOp "readTVarIO#" GenPrimOp
+ TVar# s a
+ -> State# s -> (# State# s, a #)
+ {Read contents of {\tt TVar\#} outside an STM transaction}
+ with
+ out_of_line = True
+ has_side_effects = True
primop WriteTVarOp "writeTVar#" GenPrimOp
TVar# s a
State# s -> (# State# s, MVar# s a #)
{Create new {\tt MVar\#}; initially empty.}
with
- usage = { mangle NewMVarOp [mkP] mkR }
out_of_line = True
+ has_side_effects = True
primop TakeMVarOp "takeMVar#" GenPrimOp
MVar# s a -> State# s -> (# State# s, a #)
{If {\tt MVar\#} is empty, block until it becomes full.
Then remove and return its contents, and set it empty.}
with
- usage = { mangle TakeMVarOp [mkM, mkP] mkM }
- has_side_effects = True
out_of_line = True
+ has_side_effects = True
primop TryTakeMVarOp "tryTakeMVar#" GenPrimOp
MVar# s a -> State# s -> (# State# s, Int#, a #)
{If {\tt MVar\#} is empty, immediately return with integer 0 and value undefined.
Otherwise, return with integer 1 and contents of {\tt MVar\#}, and set {\tt MVar\#} empty.}
with
- usage = { mangle TryTakeMVarOp [mkM, mkP] mkM }
- has_side_effects = True
out_of_line = True
+ has_side_effects = True
primop PutMVarOp "putMVar#" GenPrimOp
MVar# s a -> a -> State# s -> State# s
{If {\tt MVar\#} is full, block until it becomes empty.
Then store value arg as its new contents.}
with
- usage = { mangle PutMVarOp [mkM, mkM, mkP] mkR }
- has_side_effects = True
out_of_line = True
+ has_side_effects = True
primop TryPutMVarOp "tryPutMVar#" GenPrimOp
MVar# s a -> a -> State# s -> (# State# s, Int# #)
{If {\tt MVar\#} is full, immediately return with integer 0.
Otherwise, store value arg as {\tt MVar\#}'s new contents, and return with integer 1.}
with
- usage = { mangle TryPutMVarOp [mkM, mkM, mkP] mkR }
- has_side_effects = True
out_of_line = True
+ has_side_effects = True
primop SameMVarOp "sameMVar#" GenPrimOp
MVar# s a -> MVar# s a -> Bool
- with
- usage = { mangle SameMVarOp [mkP, mkP] mkM }
primop IsEmptyMVarOp "isEmptyMVar#" GenPrimOp
MVar# s a -> State# s -> (# State# s, Int# #)
{Return 1 if {\tt MVar\#} is empty; 0 otherwise.}
with
- usage = { mangle IsEmptyMVarOp [mkP, mkP] mkM }
out_of_line = True
+ has_side_effects = True
------------------------------------------------------------------------
section "Delay/wait operations"
------------------------------------------------------------------------
primtype State# s
- { {\tt State#} is the primitive, unlifted type of states. It has
+ { {\tt State\#} is the primitive, unlifted type of states. It has
one type parameter, thus {\tt State\# RealWorld}, or {\tt State\# s},
where s is a type variable. The only purpose of the type parameter
is to keep different state threads separate. It is represented by
primtype RealWorld
{ {\tt RealWorld} is deeply magical. It is {\it primitive}, but it is not
{\it unlifted} (hence {\tt ptrArg}). We never manipulate values of type
- {\tt RealWorld}; it's only used in the type system, to parameterise {\tt State#}. }
+ {\tt RealWorld}; it's only used in the type system, to parameterise {\tt State\#}. }
primtype ThreadId#
{(In a non-concurrent implementation, this can be a singleton
primop ForkOp "fork#" GenPrimOp
a -> State# RealWorld -> (# State# RealWorld, ThreadId# #)
with
- usage = { mangle ForkOp [mkO, mkP] mkR }
has_side_effects = True
out_of_line = True
primop ForkOnOp "forkOn#" GenPrimOp
Int# -> a -> State# RealWorld -> (# State# RealWorld, ThreadId# #)
with
- usage = { mangle ForkOnOp [mkO, mkP] mkR }
has_side_effects = True
out_of_line = True
primop KillThreadOp "killThread#" GenPrimOp
ThreadId# -> a -> State# RealWorld -> State# RealWorld
with
- usage = { mangle KillThreadOp [mkP, mkM, mkP] mkR }
has_side_effects = True
out_of_line = True
State# RealWorld -> (# State# RealWorld, ThreadId# #)
with
out_of_line = True
+ has_side_effects = True
primop LabelThreadOp "labelThread#" GenPrimOp
ThreadId# -> Addr# -> State# RealWorld -> State# RealWorld
State# RealWorld -> (# State# RealWorld, Int# #)
with
out_of_line = True
+ has_side_effects = True
+
+primop NoDuplicateOp "noDuplicate#" GenPrimOp
+ State# RealWorld -> State# RealWorld
+ with
+ out_of_line = True
+ has_side_effects = True
+
+primop ThreadStatusOp "threadStatus#" GenPrimOp
+ ThreadId# -> State# RealWorld -> (# State# RealWorld, Int# #)
+ with
+ out_of_line = True
+ has_side_effects = True
------------------------------------------------------------------------
section "Weak pointers"
primop MkWeakOp "mkWeak#" GenPrimOp
o -> b -> c -> State# RealWorld -> (# State# RealWorld, Weak# b #)
with
- usage = { mangle MkWeakOp [mkZ, mkM, mkM, mkP] mkM }
+ has_side_effects = True
+ out_of_line = True
+
+primop MkWeakForeignEnvOp "mkWeakForeignEnv#" GenPrimOp
+ o -> b -> Addr# -> Addr# -> Int# -> Addr# -> State# RealWorld -> (# State# RealWorld, Weak# b #)
+ with
has_side_effects = True
out_of_line = True
primop DeRefWeakOp "deRefWeak#" GenPrimOp
Weak# a -> State# RealWorld -> (# State# RealWorld, Int#, a #)
with
- usage = { mangle DeRefWeakOp [mkM, mkP] mkM }
has_side_effects = True
out_of_line = True
Weak# a -> State# RealWorld -> (# State# RealWorld, Int#,
(State# RealWorld -> (# State# RealWorld, () #)) #)
with
- usage = { mangle FinalizeWeakOp [mkM, mkP]
- (mkR . (inUB FinalizeWeakOp
- [id,id,inFun FinalizeWeakOp mkR mkM])) }
has_side_effects = True
out_of_line = True
primop MakeStablePtrOp "makeStablePtr#" GenPrimOp
a -> State# RealWorld -> (# State# RealWorld, StablePtr# a #)
with
- usage = { mangle MakeStablePtrOp [mkM, mkP] mkM }
has_side_effects = True
out_of_line = True
primop DeRefStablePtrOp "deRefStablePtr#" GenPrimOp
StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #)
with
- usage = { mangle DeRefStablePtrOp [mkM, mkP] mkM }
needs_wrapper = True
has_side_effects = True
out_of_line = True
primop EqStablePtrOp "eqStablePtr#" GenPrimOp
StablePtr# a -> StablePtr# a -> Int#
with
- usage = { mangle EqStablePtrOp [mkP, mkP] mkR }
has_side_effects = True
primop MakeStableNameOp "makeStableName#" GenPrimOp
a -> State# RealWorld -> (# State# RealWorld, StableName# a #)
with
- usage = { mangle MakeStableNameOp [mkZ, mkP] mkR }
needs_wrapper = True
has_side_effects = True
out_of_line = True
primop EqStableNameOp "eqStableName#" GenPrimOp
StableName# a -> StableName# a -> Int#
- with
- usage = { mangle EqStableNameOp [mkP, mkP] mkR }
primop StableNameToIntOp "stableNameToInt#" GenPrimOp
StableName# a -> Int#
- with
- usage = { mangle StableNameToIntOp [mkP] mkR }
------------------------------------------------------------------------
section "Unsafe pointer equality"
primop ReallyUnsafePtrEqualityOp "reallyUnsafePtrEquality#" GenPrimOp
a -> a -> Int#
- with
- usage = { mangle ReallyUnsafePtrEqualityOp [mkZ, mkZ] mkR }
------------------------------------------------------------------------
section "Parallelism"
primop ParOp "par#" GenPrimOp
a -> Int#
with
- usage = { mangle ParOp [mkO] mkR }
-- Note that Par is lazy to avoid that the sparked thing
-- gets evaluted strictly, which it should *not* be
has_side_effects = True
+primop GetSparkOp "getSpark#" GenPrimOp
+ State# s -> (# State# s, Int#, a #)
+ with
+ has_side_effects = True
+ out_of_line = True
+
-- HWL: The first 4 Int# in all par... annotations denote:
-- name, granularity info, size of result, degree of parallelism
-- Same structure as _seq_ i.e. returns Int#
primop ParGlobalOp "parGlobal#" GenPrimOp
a -> Int# -> Int# -> Int# -> Int# -> b -> Int#
with
- usage = { mangle ParGlobalOp [mkO, mkP, mkP, mkP, mkP, mkM] mkM }
has_side_effects = True
primop ParLocalOp "parLocal#" GenPrimOp
a -> Int# -> Int# -> Int# -> Int# -> b -> Int#
with
- usage = { mangle ParLocalOp [mkO, mkP, mkP, mkP, mkP, mkM] mkM }
has_side_effects = True
primop ParAtOp "parAt#" GenPrimOp
b -> a -> Int# -> Int# -> Int# -> Int# -> c -> Int#
with
- usage = { mangle ParAtOp [mkO, mkZ, mkP, mkP, mkP, mkP, mkM] mkM }
has_side_effects = True
primop ParAtAbsOp "parAtAbs#" GenPrimOp
a -> Int# -> Int# -> Int# -> Int# -> Int# -> b -> Int#
with
- usage = { mangle ParAtAbsOp [mkO, mkP, mkP, mkP, mkP, mkM] mkM }
has_side_effects = True
primop ParAtRelOp "parAtRel#" GenPrimOp
a -> Int# -> Int# -> Int# -> Int# -> Int# -> b -> Int#
with
- usage = { mangle ParAtRelOp [mkO, mkP, mkP, mkP, mkP, mkM] mkM }
has_side_effects = True
primop ParAtForNowOp "parAtForNow#" GenPrimOp
b -> a -> Int# -> Int# -> Int# -> Int# -> c -> Int#
with
- usage = { mangle ParAtForNowOp [mkO, mkZ, mkP, mkP, mkP, mkP, mkM] mkM }
has_side_effects = True
-- copyable# and noFollow# are yet to be implemented (for GpH)
--primop CopyableOp "copyable#" GenPrimOp
-- a -> Int#
-- with
--- usage = { mangle CopyableOp [mkZ] mkR }
-- has_side_effects = True
--
--primop NoFollowOp "noFollow#" GenPrimOp
-- a -> Int#
-- with
--- usage = { mangle NoFollowOp [mkZ] mkR }
-- has_side_effects = True
primop DataToTagOp "dataToTag#" GenPrimOp
a -> Int#
with
- strictness = { \ arity -> mkStrictSig (mkTopDmdType [seqDmd] TopRes) }
+ strictness = { \ _arity -> mkStrictSig (mkTopDmdType [seqDmd] TopRes) }
-- dataToTag# must have an evaluated argument
primop TagToEnumOp "tagToEnum#" GenPrimOp
out_of_line = True
primop NewBCOOp "newBCO#" GenPrimOp
- ByteArr# -> ByteArr# -> Array# a -> Int# -> ByteArr# -> State# s -> (# State# s, BCO# #)
+ ByteArray# -> ByteArray# -> Array# a -> Int# -> ByteArray# -> State# s -> (# State# s, BCO# #)
with
has_side_effects = True
out_of_line = True
-primop InfoPtrOp "infoPtr#" GenPrimOp
- a -> Addr#
+primop UnpackClosureOp "unpackClosure#" GenPrimOp
+ a -> (# Addr#, Array# b, ByteArray# #)
with
out_of_line = True
-primop ClosurePayloadOp "closurePayload#" GenPrimOp
- a -> (# Array# b, ByteArr# #)
+primop GetApStackValOp "getApStackVal#" GenPrimOp
+ a -> Int# -> (# Int#, b #)
with
out_of_line = True
+------------------------------------------------------------------------
+section "Misc"
+ {These aren't nearly as wired in as Etc...}
+------------------------------------------------------------------------
+
+primop TraceCcsOp "traceCcs#" GenPrimOp
+ a -> b -> b
+ with
+ has_side_effects = True
+ out_of_line = True
------------------------------------------------------------------------
section "Etc"
pseudoop "inline"
a -> a
- { The call {\tt(inline f)} arranges that f is inlined, regardless of its size.
- More precisely, the call {\tt(inline f)} rewrites to the right-hand side of
+ { The call {\tt (inline f)} arranges that f is inlined, regardless of its size.
+ More precisely, the call {\tt (inline f)} rewrites to the right-hand side of
{\tt f}'s definition. This allows the programmer to control inlining from a
particular call site rather than the definition site of the function (c.f.
- {\ttINLINE} pragmas in User's Guide, Section 7.10.3, "INLINE and NOINLINE
+ {\tt INLINE} pragmas in User's Guide, Section 7.10.3, "INLINE and NOINLINE
pragmas").
This inlining occurs regardless of the argument to the call or the size of
This behaviour is occasionally useful when controlling evaluation order.
Notably, {\tt lazy} is used in the library definition of {\tt Control.Parallel.par}:
- > par :: a -> b -> b
- > par x y = case (par# x) of { _ -> lazy y }
+ {\tt par :: a -> b -> b}
+
+ {\tt par x y = case (par\# x) of \_ -> lazy y}
If {\tt lazy} were not lazy, {\tt par} would look strict in {\tt y} which
would defeat the whole purpose of {\tt par}.
It's also used to instantiate un-constrained type variables after type
checking. For example
- > length Any []
+ {\tt length Any []}
Annoyingly, we sometimes need {\tt Any}s of other kinds, such as {\tt (* -> *)} etc.
This is a bit like tuples. We define a couple of useful ones here,
used when you want to write a program that you know is well-typed, but where Haskell's
type system is not expressive enough to prove that it is well typed.
- The argument to {\tt unsafeCoerce\#} can have unboxed types, although extremely bad
- things will happen if you coerce a boxed type to an unboxed type. }
+ The following uses of {\tt unsafeCoerce\#} are supposed to work (i.e. not lead to
+ spurious compile-time or run-time crashes):
+
+ * Casting any lifted type to {\tt Any}
+
+ * Casting {\tt Any} back to the real type
+
+ * Casting an unboxed type to another unboxed type of the same size
+ (but not coercions between floating-point and integral types)
+ * Casting between two types that have the same runtime representation. One case is when
+ the two types differ only in "phantom" type parameters, for example
+ {\tt Ptr Int} to {\tt Ptr Float}, or {\tt [Int]} to {\tt [Float]} when the list is
+ known to be empty. Also, a {\tt newtype} of a type {\tt T} has the same representation
+ at runtime as {\tt T}.
+
+ Other uses of {\tt unsafeCoerce\#} are undefined. In particular, you should not use
+ {\tt unsafeCoerce\#} to cast a T to an algebraic data type D, unless T is also
+ an algebraic data type. For example, do not cast {\tt Int->Int} to {\tt Bool}, even if
+ you later cast that {\tt Bool} back to {\tt Int->Int} before applying it. The reasons
+ have to do with GHC's internal representation details (for the congnoscenti, data values
+ can be entered but function closures cannot). If you want a safe type to cast things
+ to, use {\tt Any}, which is not an algebraic data type.
+
+ }
+
+-- NB. It is tempting to think that casting a value to a type that it doesn't have is safe
+-- as long as you don't "do anything" with the value in its cast form, such as seq on it. This
+-- isn't the case: the compiler can insert seqs itself, and if these happen at the wrong type,
+-- Bad Things Might Happen. See bug #1616: in this case we cast a function of type (a,b) -> (a,b)
+-- to () -> () and back again. The strictness analyser saw that the function was strict, but
+-- the wrapper had type () -> (), and hence the wrapper de-constructed the (), the worker re-constructed
+-- a new (), with the result that the code ended up with "case () of (a,b) -> ...".
+
+primop TraceEventOp "traceEvent#" GenPrimOp
+ Addr# -> State# s -> State# s
+ { Emits an event via the RTS tracing framework. The contents
+ of the event is the zero-terminated byte string passed as the first
+ argument. The event will be emitted either to the .eventlog file,
+ or to stderr, depending on the runtime RTS flags. }
+ with
+ has_side_effects = True
+ out_of_line = True
------------------------------------------------------------------------
--- ---