@@ -432,7 +432,44 @@ subProxy _ _ = error "Exp.(-): undefined"
432432-- * Typeable Reflection
433433--------------------------------------------------------------------------------
434434
435+ stablePtrToIntPtr :: StablePtr a -> IntPtr
436+ stablePtrToIntPtr = ptrToIntPtr . castStablePtrToPtr
437+ {-# INLINE stablePtrToIntPtr #-}
438+
439+ intPtrToStablePtr :: IntPtr -> StablePtr a
440+ intPtrToStablePtr = castPtrToStablePtr . intPtrToPtr
441+ {-# INLINE intPtrToStablePtr #-}
442+
443+ argument :: (p s -> r ) -> Proxy s
444+ argument _ = Proxy
445+
446+ -- This had to be moved to the top level, due to an apparent bug in
447+ -- the ghc inliner introduced in ghc 7.0.x
448+ reflectBefore :: forall (proxy :: * -> * ) s b . (Proxy s -> b ) -> proxy s -> b
449+ reflectBefore f = const $! f Proxy
450+ {-# NOINLINE reflectBefore #-}
451+
435452
453+ #if USE_TYPE_LITS
454+ reifyTypeable :: {- Typeable a => -} a -> (forall (s :: * ). (Typeable s , Reifies s a ) => Proxy s -> r ) -> r
455+ # if MIN_VERSION_base(4,4,0)
456+ reifyTypeable (a :: a ) k = unsafeDupablePerformIO $ do
457+ # else
458+ reifyTypeable (a :: a ) k = unsafePerformIO $ do
459+ # endif
460+ p <- newStablePtr a
461+ let n = stablePtrToIntPtr p
462+ reifyNat (fromIntegral n) (\ (_ :: Proxy n ) ->
463+ reflectBefore (fmap return k) $
464+ (Proxy :: Proxy (Stable n a )))
465+ data Stable (n :: Nat ) a
466+ instance KnownNat n => Reifies (Stable n a ) a where
467+ reflect = r where
468+ r = unsafePerformIO $ const <$> deRefStablePtr p <* freeStablePtr p
469+ s = argument r
470+ p = intPtrToStablePtr $ fromIntegral $ reflect (Proxy :: Proxy n )
471+
472+ #else
436473class Typeable s => B s where
437474 reflectByte :: proxy s -> IntPtr
438475
@@ -492,14 +529,6 @@ stable :: p b0 -> p b1 -> p b2 -> p b3 -> p b4 -> p b5 -> p b6 -> p b7
492529stable _ _ _ _ _ _ _ _ = Proxy
493530{-# INLINE stable #-}
494531
495- stablePtrToIntPtr :: StablePtr a -> IntPtr
496- stablePtrToIntPtr = ptrToIntPtr . castStablePtrToPtr
497- {-# INLINE stablePtrToIntPtr #-}
498-
499- intPtrToStablePtr :: IntPtr -> StablePtr a
500- intPtrToStablePtr = castPtrToStablePtr . intPtrToPtr
501- {-# INLINE intPtrToStablePtr #-}
502-
503532byte0 :: p (Stable (W b0 b1 b2 b3 ) w1 a ) -> Proxy b0
504533byte0 _ = Proxy
505534
@@ -524,9 +553,6 @@ byte6 _ = Proxy
524553byte7 :: p (Stable w0 (W b4 b5 b6 b7 ) a ) -> Proxy b7
525554byte7 _ = Proxy
526555
527- argument :: (p s -> r ) -> Proxy s
528- argument _ = Proxy
529-
530556instance (B b0 , B b1 , B b2 , B b3 , B b4 , B b5 , B b6 , B b7 , w0 ~ W b0 b1 b2 b3 , w1 ~ W b4 b5 b6 b7 )
531557 => Reifies (Stable w0 w1 a ) a where
532558 reflect = r where
@@ -543,12 +569,6 @@ instance (B b0, B b1, B b2, B b3, B b4, B b5, B b6, B b7, w0 ~ W b0 b1 b2 b3, w1
543569 (reflectByte (byte7 s) `shiftL` 56 )
544570 {-# NOINLINE reflect #-}
545571
546- -- This had to be moved to the top level, due to an apparent bug in
547- -- the ghc inliner introduced in ghc 7.0.x
548- reflectBefore :: forall (proxy :: * -> * ) s b . (Proxy s -> b ) -> proxy s -> b
549- reflectBefore f = const $! f Proxy
550- {-# NOINLINE reflectBefore #-}
551-
552572-- | Reify a value at the type level in a 'Typeable'-compatible fashion, to be recovered with 'reflect'.
553573--
554574-- This can be necessary to work around the changes to @Data.Typeable@ in GHC HEAD.
@@ -570,6 +590,7 @@ reifyTypeable a k = unsafePerformIO $ do
570590 reifyByte (fromIntegral (n `shiftR` 56 )) (\ s7 ->
571591 reflectBefore (fmap return k) $
572592 stable s0 s1 s2 s3 s4 s5 s6 s7))))))))
593+ #endif
573594
574595
575596data ReifiedMonoid a = ReifiedMonoid { reifiedMappend :: a -> a -> a , reifiedMempty :: a }
0 commit comments