From bd6a0427c90e9dec8d520e2fd6190770c46c044a Mon Sep 17 00:00:00 2001 From: simonmar Date: Wed, 10 Sep 2003 14:45:24 +0000 Subject: [PATCH] [project @ 2003-09-10 14:45:24 by simonmar] Quick hack to work around the dynamic exception crashes in GHCi. The problem is this: the Data.Typeable library (Data.Dymamic in previous versions of GHC) maintains an internal cache mapping type names to unique numbers, and this cache is used for fast comparisons on TypeReps. In GHCi, there are actually two versions of the Data.Typeable library loaded: one linked to GHCi itself, and the other dynamically loaded, so there are two copies of the hash tables. The problem is that if we have a Dynamic value generated using one set of hash tables, it will erroneously appear to be of a different type when the other hash tables are used. The hack I've instigated is to use the central RTS genSym (which already exists) to generate the unique Ids, so that the two copies of the dynamic library will be using distinct Ids, and Dynamics from one will never be recognisable to the other. --- Data/Typeable.hs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Data/Typeable.hs b/Data/Typeable.hs index 6f38656..c67d307 100644 --- a/Data/Typeable.hs +++ b/Data/Typeable.hs @@ -414,9 +414,28 @@ cache = unsafePerformIO $ do ap_tbl = empty_ap_tbl }) newKey :: IORef Key -> IO Key +#ifdef __GLASGOW_HASKELL__ +newKey kloc = do i <- genSym; return (Key i) +#else newKey kloc = do { k@(Key i) <- readIORef kloc ; writeIORef kloc (Key (i+1)) ; return k } +#endif + +#ifdef __GLASGOW_HASKELL__ +-- In GHC we use the RTS's genSym function to get a new unique, +-- because in GHCi we might have two copies of the Data.Typeable +-- library running (one in the compiler and one in the running +-- program), and we need to make sure they don't share any keys. +-- +-- This is really a hack. A better solution would be to centralise the +-- whole mutable state used by this module, i.e. both hashtables. But +-- the current solution solves the immediate problem, which is that +-- dynamics generated in one world with one type were erroneously +-- being recognised by the other world as having a different type. +foreign import ccall unsafe "genSymZh" + genSym :: IO Int +#endif mkTyConKey :: String -> Key mkTyConKey str -- 1.7.10.4