ghc-dup: e209b58ba1c3cf6ac07764430dd15db01ca2c5bf
1: {-|
2: Module : GHC.dup
3: Copyright : (c) 2012 Joachim Breitner
4: License : BSD3
5: Maintainer : Joachim Breitner <mail@joachim-breitner.de>
6: Stability : experimental
7: Portability : not at all
8:
9: This module provides two new operations, 'GHC.Dup.dup' and 'GHC.Dup.deepDup',
10: that allow you to prevent the result of two evaluations of the same
11: expression to be shared.
12: -}
13:
14: {-# LANGUAGE GHCForeignImportPrim, MagicHash, UnboxedTuples, UnliftedFFITypes #-}
15:
16: {-# OPTIONS_HADDOCK prune #-}
17:
18: module GHC.Dup (Box(Box), dup, deepDup, deepDupFun) where
19:
20: import GHC.Exts
21:
22: -- This is a datatype that has the same layout as Ptr, so that by
23: -- unsafeCoerce'ing, we obtain the Addr of the wrapped value
24:
25: -- | The Box datatype allows you to control the time of evaluations of 'dup' or
26: -- 'deepDup', by pattern-matching on the result.
27: data Box a = Box a
28:
29: -- This is for turning an a to something we can pass to a primitive operation
30:
31: aToWord# :: Any -> Word#
32: aToWord# a = case Box a of mb@(Box _) -> case unsafeCoerce# mb :: Word of W# addr -> addr
33:
34: wordToA# :: Word# -> Box Any
35: wordToA# a = unsafeCoerce# (W# a) :: Box Any
36:
37: -- This is for actually calling the primitive operation
38:
39: foreign import prim "dupClosure" dupClosure :: Word# -> Word#
40:
41: {-# NOINLINE dup #-}
42: -- | Dup copies a the parameter and returns it. The copy is shallow, i.e.
43: -- referenced thunks are still shared between the parameter and its copy.
44: dup :: a -> Box a
45: dup a =
46: case dupClosure (aToWord# (unsafeCoerce# a)) of { x ->
47: case wordToA# x of { Box x' ->
48: Box (unsafeCoerce# x')
49: }}
50:
51: foreign import prim "deepDupClosure" deepDupClosure :: Word# -> Word#
52:
53: -- This is like 'deepDup', but with a different type, and should not be used by
54: -- the programmer.
55: deepDupFun :: a -> a
56: deepDupFun a =
57: case deepDupClosure (aToWord# (unsafeCoerce# a)) of { x ->
58: case wordToA# x of { Box x' ->
59: unsafeCoerce# x'
60: }}
61: {-# NOINLINE deepDupFun #-}
62:
63: -- | This copies the parameter and changes all references therein so that when
64: -- they are evaluated, they are copied again. This ensures that everything put on the heap by a function that wraps all is parameters in 'deepDup' can be freed after the evaluation.
65: deepDup :: a -> Box a
66: deepDup a =
67: case deepDupClosure (aToWord# (unsafeCoerce# a)) of { x ->
68: case wordToA# x of { Box x' ->
69: Box (unsafeCoerce# x')
70: }}
71: {-# NOINLINE deepDup #-}
72:
Generated by git2html.