X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fprelude%2Fprimops.txt.pp;h=adb2e110ff8ced4fc4348f767daa93185a37c4bf;hb=594cc38109e66088ab144f9370ca07a8eb54d2e8;hp=a3267391f3b0b3f3e885c84cd3dc2c107a2cd07e;hpb=84bd33df44c6f52c5517405dd1bb968a7ccdd154;p=ghc-hetmet.git diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp index a326739..adb2e11 100644 --- a/compiler/prelude/primops.txt.pp +++ b/compiler/prelude/primops.txt.pp @@ -545,6 +545,10 @@ primop DoubleDivOp "/##" Dyadic 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 @@ -614,6 +618,13 @@ primop DoubleDecodeOp "decodeDouble#" GenPrimOp represent an {\tt Integer\#} holding the mantissa.} with out_of_line = True +primop DoubleDecode_2IntOp "decodeDouble_2Int#" GenPrimOp + Double# -> (# Int#, Int#, Int# #) + {Convert to arbitrary-precision integer. + First {\tt Int\#} in result is the high 32 bits of the mantissa, and the + second is the low 32. The third is the exponent.} + with out_of_line = True + ------------------------------------------------------------------------ section "Float#" {Operations on single-precision (32-bit) floating-point numbers.} @@ -652,6 +663,9 @@ primop FloatDivOp "divideFloat#" Dyadic 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# @@ -717,6 +731,12 @@ primop FloatDecodeOp "decodeFloat#" GenPrimOp represent an {\tt Integer\#} holding the mantissa.} with out_of_line = True +primop FloatDecode_IntOp "decodeFloat_Int#" GenPrimOp + Float# -> (# Int#, Int# #) + {Convert to arbitrary-precision integer. + First {\tt Int\#} in result is the mantissa; second is the exponent.} + with out_of_line = True + ------------------------------------------------------------------------ section "Arrays" {Operations on {\tt Array\#}.} @@ -1233,7 +1253,7 @@ primop CatchOp "catch#" GenPrimOp primop RaiseOp "raise#" GenPrimOp a -> b with - strictness = { \ arity -> mkStrictSig (mkTopDmdType [lazyDmd] BotRes) } + strictness = { \ _arity -> mkStrictSig (mkTopDmdType [lazyDmd] BotRes) } -- NB: result is bottom out_of_line = True @@ -1653,7 +1673,7 @@ section "Tag to enum stuff" 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 @@ -1692,11 +1712,6 @@ primop GetApStackValOp "getApStackVal#" GenPrimOp with out_of_line = True -primop GetStackFrame "getStackFrame#" GenPrimOp - ThreadId# -> Int# -> (# Int#, Int# #) - with - out_of_line = True - ------------------------------------------------------------------------ section "Etc" {Miscellaneous built-ins} @@ -1778,9 +1793,38 @@ pseudoop "unsafeCoerce#" 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 + + * 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) -> ...". ------------------------------------------------------------------------ --- ---