X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Flib%2Fghc%2FUnsafeST.lhs;fp=ghc%2Flib%2Fghc%2FUnsafeST.lhs;h=5565178033a60f8ccb6a1e79e7cdbcda01e06161;hb=4e2bf823d13edfcd3e76e2b4754f83021adb13ce;hp=0000000000000000000000000000000000000000;hpb=94a3714fc95e7502d333135be2a8bfc6cd3e12bf;p=ghc-hetmet.git diff --git a/ghc/lib/ghc/UnsafeST.lhs b/ghc/lib/ghc/UnsafeST.lhs new file mode 100644 index 0000000..5565178 --- /dev/null +++ b/ghc/lib/ghc/UnsafeST.lhs @@ -0,0 +1,68 @@ +% +% (c) The AQUA Project, Glasgow University, 1994-1996 +% + +\section[UnsafeST]{Module @UnsafeST@} + +These functions have their own module because we definitely don't want +them to be inlined. + +\begin{code} +{-# OPTIONS -fno-implicit-prelude #-} + +module UnsafeST (unsafeInterleaveST, runST) where + +import STBase +import PrelBase +\end{code} + +\begin{code} +unsafeInterleaveST :: ST s a -> ST s a +unsafeInterleaveST (ST m) = ST ( \ s -> + let + STret _ r = m s + in + STret s r) + +\end{code} + +Definition of runST +~~~~~~~~~~~~~~~~~~~ + +SLPJ 95/04: Why @runST@ must not have an unfolding; consider: +\begin{verbatim} +f x = + runST ( \ s -> let + (a, s') = newArray# 100 [] s + (_, s'') = fill_in_array_or_something a x s' + in + freezeArray# a s'' ) +\end{verbatim} +If we inline @runST@, we'll get: +\begin{verbatim} +f x = let + (a, s') = newArray# 100 [] realWorld#{-NB-} + (_, s'') = fill_in_array_or_something a x s' + in + freezeArray# a s'' +\end{verbatim} +And now the @newArray#@ binding can be floated to become a CAF, which +is totally and utterly wrong: +\begin{verbatim} +f = let + (a, s') = newArray# 100 [] realWorld#{-NB-} -- YIKES!!! + in + \ x -> + let (_, s'') = fill_in_array_or_something a x s' in + freezeArray# a s'' +\end{verbatim} +All calls to @f@ will share a {\em single} array! End SLPJ 95/04. + +\begin{code} +runST :: (All s => ST s a) -> a +runST st = + case st of + ST m -> case m realWorld# of + STret _ r -> r +\end{code} +