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.