ab7fcd1764a362ee1af57db3d4e0071c5d40ade5
[ghc.git] / compiler / ghci / DebuggerUtils.hs
1 module DebuggerUtils (
2 dataConInfoPtrToName,
3 ) where
4
5 import ByteCodeItbls
6 import DynFlags
7 import FastString
8 import TcRnTypes
9 import TcRnMonad
10 import IfaceEnv
11 import CgInfoTbls
12 import SMRep
13 import Module
14 import OccName
15 import Name
16 import Outputable
17 import Util
18
19 import Data.Char
20 import Foreign
21 import Data.List
22
23 #include "HsVersions.h"
24
25 -- | Given a data constructor in the heap, find its Name.
26 -- The info tables for data constructors have a field which records
27 -- the source name of the constructor as a Ptr Word8 (UTF-8 encoded
28 -- string). The format is:
29 --
30 -- > Package:Module.Name
31 --
32 -- We use this string to lookup the interpreter's internal representation of the name
33 -- using the lookupOrig.
34 --
35 dataConInfoPtrToName :: Ptr () -> TcM (Either String Name)
36 dataConInfoPtrToName x = do
37 dflags <- getDynFlags
38 theString <- liftIO $ do
39 let ptr = castPtr x :: Ptr StgInfoTable
40 conDescAddress <- getConDescAddress dflags ptr
41 peekArray0 0 conDescAddress
42 let (pkg, mod, occ) = parse theString
43 pkgFS = mkFastStringByteList pkg
44 modFS = mkFastStringByteList mod
45 occFS = mkFastStringByteList occ
46 occName = mkOccNameFS OccName.dataName occFS
47 modName = mkModule (fsToPackageId pkgFS) (mkModuleNameFS modFS)
48 return (Left $ showSDoc dflags $ ppr modName <> dot <> ppr occName)
49 `recoverM` (Right `fmap` lookupOrig modName occName)
50
51 where
52
53 {- To find the string in the constructor's info table we need to consider
54 the layout of info tables relative to the entry code for a closure.
55
56 An info table can be next to the entry code for the closure, or it can
57 be separate. The former (faster) is used in registerised versions of ghc,
58 and the latter (portable) is for non-registerised versions.
59
60 The diagrams below show where the string is to be found relative to
61 the normal info table of the closure.
62
63 1) Code next to table:
64
65 --------------
66 | | <- pointer to the start of the string
67 --------------
68 | | <- the (start of the) info table structure
69 | |
70 | |
71 --------------
72 | entry code |
73 | .... |
74
75 In this case the pointer to the start of the string can be found in
76 the memory location _one word before_ the first entry in the normal info
77 table.
78
79 2) Code NOT next to table:
80
81 --------------
82 info table structure -> | *------------------> --------------
83 | | | entry code |
84 | | | .... |
85 --------------
86 ptr to start of str -> | |
87 --------------
88
89 In this case the pointer to the start of the string can be found
90 in the memory location: info_table_ptr + info_table_size
91 -}
92
93 getConDescAddress :: DynFlags -> Ptr StgInfoTable -> IO (Ptr Word8)
94 getConDescAddress dflags ptr
95 | ghciTablesNextToCode = do
96 offsetToString <- peek $ ptr `plusPtr` (- wORD_SIZE dflags)
97 return $ (ptr `plusPtr` stdInfoTableSizeB dflags) `plusPtr` (fromIntegral (offsetToString :: StgWord))
98 | otherwise =
99 peek $ intPtrToPtr $ ptrToIntPtr ptr + fromIntegral (stdInfoTableSizeB dflags)
100 -- parsing names is a little bit fiddly because we have a string in the form:
101 -- pkg:A.B.C.foo, and we want to split it into three parts: ("pkg", "A.B.C", "foo").
102 -- Thus we split at the leftmost colon and the rightmost occurrence of the dot.
103 -- It would be easier if the string was in the form pkg:A.B.C:foo, but alas
104 -- this is not the conventional way of writing Haskell names. We stick with
105 -- convention, even though it makes the parsing code more troublesome.
106 -- Warning: this code assumes that the string is well formed.
107 parse :: [Word8] -> ([Word8], [Word8], [Word8])
108 parse input
109 = ASSERT (all (>0) (map length [pkg, mod, occ])) (pkg, mod, occ)
110 where
111 dot = fromIntegral (ord '.')
112 (pkg, rest1) = break (== fromIntegral (ord ':')) input
113 (mod, occ)
114 = (concat $ intersperse [dot] $ reverse modWords, occWord)
115 where
116 (modWords, occWord) = ASSERT (length rest1 > 0) (parseModOcc [] (tail rest1))
117 parseModOcc :: [[Word8]] -> [Word8] -> ([[Word8]], [Word8])
118 -- We only look for dots if str could start with a module name,
119 -- i.e. if it starts with an upper case character.
120 -- Otherwise we might think that "X.:->" is the module name in
121 -- "X.:->.+", whereas actually "X" is the module name and
122 -- ":->.+" is a constructor name.
123 parseModOcc acc str@(c : _)
124 | isUpper $ chr $ fromIntegral c
125 = case break (== dot) str of
126 (top, []) -> (acc, top)
127 (top, _ : bot) -> parseModOcc (top : acc) bot
128 parseModOcc acc str = (acc, str)