wherefrom-compat-0.1.1.1/0000755000000000000000000000000007346545000013320 5ustar0000000000000000wherefrom-compat-0.1.1.1/CHANGELOG.md0000644000000000000000000000034707346545000015135 0ustar0000000000000000# Revision history for wherefrom-compat ## 0.1.1.1 -- 2024/05/24 * Support GHC-9.10 ## 0.1.1.0 -- 2024/02/01 * Fix interface around srcFile/srcSpan. ## 0.1.0.0 -- 2024/02/01 * First version. Released on an unsuspecting world. wherefrom-compat-0.1.1.1/LICENSE0000644000000000000000000000242607346545000014331 0ustar0000000000000000Copyright (c) 2023, Teo Camarasu All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. wherefrom-compat-0.1.1.1/src/GHC/InfoProv/0000755000000000000000000000000007346545000016252 5ustar0000000000000000wherefrom-compat-0.1.1.1/src/GHC/InfoProv/Compat.hs0000644000000000000000000001046607346545000020040 0ustar0000000000000000{-# LANGUAGE CPP #-} -- | This module provides a stable interface to access GHC's info provenance information. -- This is helpful for seeing metadata about heap objects. module GHC.InfoProv.Compat ( InfoProv(..) , whereFrom ) where #if MIN_VERSION_base(4,20,0) import qualified GHC.InfoProv as IP data InfoProv = InfoProv { ipName :: String, ipDesc :: String, ipTyDesc :: String, ipLabel :: String, ipMod :: String, ipSrcFile :: String, ipSrcSpan :: String } deriving (Eq, Show) -- | Get information about where a value originated from. -- -- This information is stored statically in a binary when @super-duper@ is enabled. -- The source positions will be greatly improved by also enabled debug information with @-g3@. -- Finally you can enable @-fdistinct-constructor-tables@ to get more precise information about data constructor allocations. -- -- The information is collect by looking at the info table address of a specific closure and then consulting a specially generated map (by @-finfo-table-map@) -- to find out where we think the best source position to describe that info table arose from. whereFrom :: a -> IO (Maybe InfoProv) whereFrom v = do xs <- IP.whereFrom v pure $ do ip <- xs Just $ InfoProv { ipName = IP.ipName ip , ipDesc = show . fromEnum $ IP.ipDesc ip , ipTyDesc = IP.ipTyDesc ip , ipLabel = IP.ipLabel ip , ipMod = IP.ipMod ip , ipSrcFile = IP.ipSrcFile ip , ipSrcSpan = IP.ipSrcSpan ip } #elif MIN_VERSION_base(4,18,0) import GHC.InfoProv (InfoProv(..), whereFrom) #elif MIN_VERSION_base(4,17,0) import qualified GHC.Stack.CCS as CCS data InfoProv = InfoProv { ipName :: String, ipDesc :: String, ipTyDesc :: String, ipLabel :: String, ipMod :: String, ipSrcFile :: String, ipSrcSpan :: String } deriving (Eq, Show) -- | Get information about where a value originated from. -- -- This information is stored statically in a binary when @super-duper@ is enabled. -- The source positions will be greatly improved by also enabled debug information with @-g3@. -- Finally you can enable @-fdistinct-constructor-tables@ to get more precise information about data constructor allocations. -- -- The information is collect by looking at the info table address of a specific closure and then consulting a specially generated map (by @-finfo-table-map@) -- to find out where we think the best source position to describe that info table arose from. whereFrom :: a -> IO (Maybe InfoProv) whereFrom v = do xs <- CCS.whereFrom v pure $ do ip <- xs -- srcFileSpan has the format: `test/Spec.hs:12:1-11` (srcFile, _:srcSpan) <- Just . break (== ':') $ CCS.ipLoc ip Just $ InfoProv { ipName = CCS.ipName ip , ipDesc = CCS.ipDesc ip , ipTyDesc = CCS.ipTyDesc ip , ipLabel = CCS.ipLabel ip , ipMod = CCS.ipMod ip -- the following fields are not available in this version of base , ipSrcFile = srcFile , ipSrcSpan = srcSpan } #else import qualified GHC.Stack.CCS as CCS data InfoProv = InfoProv { ipName :: String, ipDesc :: String, ipTyDesc :: String, ipLabel :: String, ipMod :: String, ipSrcFile :: String, ipSrcSpan :: String } deriving (Eq, Show) -- | Get information about where a value originated from. -- -- This information is stored statically in a binary when @super-duper@ is enabled. -- The source positions will be greatly improved by also enabled debug information with @-g3@. -- Finally you can enable @-fdistinct-constructor-tables@ to get more precise information about data constructor allocations. -- -- The information is collect by looking at the info table address of a specific closure and then consulting a specially generated map (by @-finfo-table-map@) -- to find out where we think the best source position to describe that info table arose from. whereFrom :: a -> IO (Maybe InfoProv) whereFrom v = do xs <- CCS.whereFrom v pure $ do [name, desc, tyDesc, label, modName, srcFileSpan] <- Just xs -- srcFileSpan has the format: `test/Spec.hs:12:1-11` (srcFile, _:srcSpan) <- Just $ break (== ':') srcFileSpan Just $ InfoProv { ipName = name , ipDesc = desc , ipTyDesc = tyDesc , ipLabel = label , ipMod = modName , ipSrcFile = srcFile , ipSrcSpan = srcSpan } #endif wherefrom-compat-0.1.1.1/test/0000755000000000000000000000000007346545000014277 5ustar0000000000000000wherefrom-compat-0.1.1.1/test/Spec.hs0000644000000000000000000000046507346545000015532 0ustar0000000000000000module Main (main) where import Test.Tasty import Test.Tasty.HUnit import GHC.InfoProv.Compat main :: IO () main = defaultMain tests tests :: TestTree tests = testGroup "Tests" [ testCase "whereFrom works" $ do v <- whereFrom main assertBool "whereFrom shouldn't be Nothing" $ v /= Nothing ] wherefrom-compat-0.1.1.1/wherefrom-compat.cabal0000644000000000000000000000255107346545000017566 0ustar0000000000000000cabal-version: 3.0 name: wherefrom-compat version: 0.1.1.1 synopsis: A compatibility layer for GHC's 'wherefrom' function description: A compatibility layer for GHC's 'wherefrom' function, which exposes info provenance information. Each major version of this library exports a different version of this interface. license: BSD-2-Clause license-file: LICENSE author: Teo Camarasu maintainer: teofilcamarasu@gmail.com copyright: The wherefrom-compat contributors build-type: Simple extra-doc-files: CHANGELOG.md bug-reports: https://codeberg.org/teo/wherefrom-compat/issues category: Compatibility tested-with: GHC ==9.2.8 || ==9.4.7 || ==9.6.3 || ==9.8.1 || ==9.10.1 common warnings ghc-options: -Wall library import: warnings exposed-modules: GHC.InfoProv.Compat build-depends: base >=4.16.0.0 && <4.21.0.0 hs-source-dirs: src default-language: Haskell2010 test-suite test type: exitcode-stdio-1.0 hs-source-dirs: test ghc-options: -finfo-table-map main-is: Spec.hs build-depends: , base , tasty ^>=1.5 , tasty-hunit ^>=0.10 , wherefrom-compat default-language: Haskell2010 source-repository head type: git location: https://codeberg.org/teo/wherefrom-compat.git