You can subscribe to this list here.
| 2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(127) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(6) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2005 |
Jan
|
Feb
|
Mar
(35) |
Apr
(23) |
May
|
Jun
(1) |
Jul
(48) |
Aug
(23) |
Sep
(10) |
Oct
(4) |
Nov
|
Dec
|
| 2006 |
Jan
|
Feb
|
Mar
(27) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(7) |
Dec
|
| 2007 |
Jan
|
Feb
(16) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(19) |
Oct
(25) |
Nov
(8) |
Dec
(25) |
| 2009 |
Jan
(6) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(25) |
Sep
(2) |
Oct
|
Nov
|
Dec
|
| 2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(3) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <cod...@go...> - 2009-08-11 18:58:32
|
Revision: 391 Author: jam...@us... Date: Tue Aug 11 11:50:17 2009 Log: (objc2 branch) pulled just-committed cabal build fix from trunk http://code.google.com/p/hoc/source/detail?r=391 Modified: / /branches/objc2/hoc /branches/objc2/hoc/HOC.cabal /branches/objc2/hoc/Setup.hs ======================================= --- /branches/objc2/hoc/HOC.cabal Tue Aug 11 11:50:04 2009 +++ /branches/objc2/hoc/HOC.cabal Tue Aug 11 11:50:17 2009 @@ -64,7 +64,16 @@ hs-source-dirs: HOC extra-libraries: objc, ffi + + -- This is a hack. + -- Setup.hs contains code to build HOC_cbits.o from the + -- objective-c sources, as well as a matching hack to prevent + -- Cabal from invoking "ghc -c" on this file. Cabal will then + -- include HOC_cbits.o on the linker command line, which is the + -- whole point of this exercise. c-sources: HOC_cbits.o + + if os(darwin) include-dirs: /usr/include/ffi frameworks: Foundation ======================================= --- /branches/objc2/hoc/Setup.hs Wed Dec 10 14:10:22 2008 +++ /branches/objc2/hoc/Setup.hs Tue Aug 11 11:50:17 2009 @@ -5,6 +5,7 @@ import Distribution.Simple.PreProcess import Distribution.Simple.Configure import Distribution.Simple.LocalBuildInfo +import Distribution.Simple.Program import System.Cmd( system ) import System.Exit( ExitCode(..) ) import System.Environment( getEnv ) @@ -99,6 +100,13 @@ extraFlags <- buildCBits (libBuildInfo libInfo) + -- add compiler flags required by C parts of HOC; + -- + -- HACK #1: + -- This passes the HOC_cbits.o object file on the + -- as a compiler flag so that template haskell can link + -- compile-time code. + let hooked_pd = pd { library = Just $ libInfo { libBuildInfo = addCompilerFlags extraFlags @@ -109,7 +117,42 @@ (executables pd) } - build hooked_pd lbi buildFlags knownSuffixHandlers + -- HACK #2: + -- HOC_cbits.o (built by buildCBits below) is specified in c-sources + -- for the library. Cabal reacts to this by invoking ghc -c HOC_cbits.o, + -- which ghc doesn't like. So, instead of calling ghc directly, we call + -- a short auto-generated shell script that does nothing in this case, + -- and calls the real ghc in all other cases. + -- After having "compiled" HOC_cbits.o in this way, Cabal will link + -- HOC_cbits.o as part of the library, which is what we want. + + let Just pr = lookupKnownProgram "ghc" (withPrograms lbi) + Just conf = lookupProgram pr (withPrograms lbi) + + ghcLocation = programLocation conf + + let fakeGHC = "./dist/build/fake-ghc.sh" + + writeFile fakeGHC $ unlines [ + "#!/bin/sh -e", + "case \"$*\" in", + " *HOC_cbits.o) true;;", + " *) \"" ++ locationPath ghcLocation ++ "\" \"$@\";;", + "esac" + ] + system $ "chmod +x " ++ fakeGHC + + let conf' = conf { programLocation = UserSpecified fakeGHC } + + progs' = updateProgram conf' (withPrograms lbi) + + let lbi' = lbi { + withPrograms = progs' + } + + -- call the default with our modified package description and + -- local build info + build hooked_pd lbi' buildFlags knownSuffixHandlers -- |Build HOC_cbits.o using the flags specified in the configuration -- stage, and return a list of flags to add to support usage of |
|
From: <cod...@go...> - 2009-08-11 18:54:29
|
Revision: 390 Author: jam...@us... Date: Tue Aug 11 11:50:04 2009 Log: (objc2 branch) merged changes from trunk http://code.google.com/p/hoc/source/detail?r=390 Modified: / /branches/objc2/hoc /branches/objc2/hoc/Bindings/AdditionalCode/Foundation/NSException.hs /branches/objc2/hoc/HOC/HOC/Exception.hs /branches/objc2/hoc/HOC.cabal /branches/objc2/hoc/InterfaceGenerator2/Output.hs /branches/objc2/hoc/Tests/MiniFoundation.hs /branches/objc2/hoc/Tests/TestFoundation.hs ======================================= --- /branches/objc2/hoc/Bindings/AdditionalCode/Foundation/NSException.hs Tue Mar 7 22:53:38 2006 +++ /branches/objc2/hoc/Bindings/AdditionalCode/Foundation/NSException.hs Tue Aug 11 11:50:04 2009 @@ -1,10 +1,9 @@ --X catchNS -import Control.Exception ( catchDyn ) -import HOC.Exception ( WrappedNSException(..) ) +import HOC.Exception ( WrappedNSException(..), catchWrappedNSException ) -- CUT HERE catchNS :: IO a -> (NSException () -> IO a) -> IO a catchNS action handler - = action `catchDyn` \(WrappedNSException exc) -> handler (castObject exc) + = action `catchWrappedNSException` \(WrappedNSException exc) -> handler (castObject exc) ======================================= --- /branches/objc2/hoc/HOC/HOC/Exception.hs Fri Jan 9 17:57:45 2009 +++ /branches/objc2/hoc/HOC/HOC/Exception.hs Tue Aug 11 11:50:04 2009 @@ -1,11 +1,12 @@ -{-# LANGUAGE ForeignFunctionInterface, DeriveDataTypeable #-} +{-# LANGUAGE ForeignFunctionInterface, DeriveDataTypeable, + ScopedTypeVariables, CPP #-} module HOC.Exception where import Data.Typeable import Foreign import Foreign.C.String ( CString, withCString ) import Prelude hiding ( catch ) -import Control.Exception ( Exception, evaluate, throwIO, throwDyn, catchDyn, catch ) +import Control.Exception import HOC.Base import HOC.Arguments @@ -14,11 +15,53 @@ data WrappedNSException = WrappedNSException (ID ()) deriving Typeable - -foreign import ccall unsafe wrapHaskellException :: CString -> StablePtr Exception -> IO (Ptr ObjCObject) -foreign import ccall unsafe unwrapHaskellException :: Ptr ObjCObject -> IO (StablePtr Exception) - -exceptionObjCToHaskell :: Ptr ObjCObject -> IO a +exceptionObjCToHaskell :: Ptr ObjCObject -> IO a + +#ifdef BASE4 + +foreign import ccall unsafe wrapHaskellException + :: CString -> StablePtr SomeException -> IO (Ptr ObjCObject) +foreign import ccall unsafe unwrapHaskellException + :: Ptr ObjCObject -> IO (StablePtr SomeException) + +-- get the exception pointer figure out if it is a NSException +-- or a haskell exception and throw it. +exceptionObjCToHaskell exception = do + sptr <- unwrapHaskellException exception + if (castStablePtrToPtr sptr == nullPtr) + then do + exc <- importArgument exception + throwIO $ WrappedNSException exc + else do + exc <- deRefStablePtr sptr + throwIO exc + +exceptionHaskellToObjC :: IO a -> IO (Ptr ObjCObject) + +exceptionHaskellToObjC action = + (action >> return nullPtr) + `catches` [ + Handler $ \(WrappedNSException exc) -> exportArgument exc, + Handler $ \(exc :: SomeException) -> withCString (show exc) $ + \cstr -> newStablePtr exc >>= wrapHaskellException cstr + ] + +instance Exception WrappedNSException where + toException = SomeException + fromException (SomeException ex) = cast ex + +instance Show WrappedNSException where + show (WrappedNSException ex) = "<<NSException>>" + +catchWrappedNSException :: IO a -> (WrappedNSException -> IO a) -> IO a +catchWrappedNSException = catch + +#else + +foreign import ccall unsafe wrapHaskellException + :: CString -> StablePtr Exception -> IO (Ptr ObjCObject) +foreign import ccall unsafe unwrapHaskellException + :: Ptr ObjCObject -> IO (StablePtr Exception) -- get the exception pointer figure out if it is a NSException -- or a haskell exception and throw it. @@ -40,3 +83,8 @@ (\(WrappedNSException exc) -> exportArgument exc) `catch` (\exc -> withCString (show exc) $ \cstr -> newStablePtr exc >>= wrapHaskellException cstr) + +catchWrappedNSException :: IO a -> (WrappedNSException -> IO a) -> IO a +catchWrappedNSException = catchDyn + +#endif ======================================= --- /branches/objc2/hoc/HOC.cabal Fri Jan 9 17:57:45 2009 +++ /branches/objc2/hoc/HOC.cabal Tue Aug 11 11:50:04 2009 @@ -17,8 +17,15 @@ Flag ObjC2 description: build for Objective-C 2.0 +Flag base4 + Library - build-depends: base < 4, template-haskell, unix + build-depends: template-haskell, unix + if flag(base4) + build-depends: base >= 4, syb + cpp-options: -DBASE4 + else + build-depends: base < 4 exposed-modules: HOC, @@ -87,7 +94,12 @@ cpp-options: -DTEST - build-depends: HUnit + build-depends: HUnit, template-haskell, unix + if flag(base4) + build-depends: base >= 4, syb + cpp-options: -DBASE4 + else + build-depends: base < 4 if !flag(Tests) buildable: False ======================================= --- /branches/objc2/hoc/InterfaceGenerator2/Output.hs Tue Aug 11 11:49:43 2009 +++ /branches/objc2/hoc/InterfaceGenerator2/Output.hs Tue Aug 11 11:50:04 2009 @@ -293,13 +293,21 @@ = text "name:" <+> text "HOC-" <> text frameworkName $+$ text "version: 1.0" $+$ text "build-type: Simple" $+$ - text "build-depends:" <+> - hsep (punctuate comma $ map text $ - ["base", "HOC"] ++ map ("HOC-" ++) dependencies) $+$ --- text "" $+$ - text "exposed-modules:" <+> sep (punctuate comma $ - map textBS $ BS.pack frameworkName : modules) $+$ - text "frameworks:" <+> text frameworkName + text "Flag base4" $+$ + text "Library" $+$ nest 4 ( + text "if flag(base4)" $+$ nest 4 ( + text "build-depends: base >= 4" $+$ + text "cpp-options: -DBASE4" -- don't neeed the define yet, though + ) $+$ text "else" $+$ nest 4 ( + text "build-depends: base < 4" + ) $+$ + text "build-depends:" <+> + hsep (punctuate comma $ map text $ + ["HOC"] ++ map ("HOC-" ++) dependencies) $+$ + text "exposed-modules:" <+> sep (punctuate comma $ + map textBS $ BS.pack frameworkName : modules) $+$ + text "frameworks:" <+> text frameworkName + ) where modules = [ m | LocalModule m <- Set.toList $ Set.fromList $ ======================================= --- /branches/objc2/hoc/Tests/MiniFoundation.hs Fri Jan 9 17:57:45 2009 +++ /branches/objc2/hoc/Tests/MiniFoundation.hs Tue Aug 11 11:50:04 2009 @@ -1,13 +1,14 @@ {-# LANGUAGE TemplateHaskell, StandaloneDeriving, MultiParamTypeClasses, - TypeSynonymInstances, FlexibleInstances, RankNTypes #-} + TypeSynonymInstances, FlexibleInstances, RankNTypes, CPP #-} module MiniFoundation where import HOC import HOC.Exception ( WrappedNSException(..) ) import Foreign.C.Types -import Control.Exception ( catchDyn ) +import Control.Exception import System.IO.Unsafe ( unsafePerformIO ) +import Prelude hiding ( catch ) $(declareClass "NSObject" "ID") $(declareClass "NSString" "NSObject") @@ -109,8 +110,13 @@ catchNS :: IO a -> (NSException () -> IO a) -> IO a +#ifdef BASE4 +catchNS action handler + = action `catch` \(WrappedNSException exc) -> handler (castObject exc) +#else catchNS action handler = action `catchDyn` \(WrappedNSException exc) -> handler (castObject exc) +#endif -- NSMutableArray ======================================= --- /branches/objc2/hoc/Tests/TestFoundation.hs Fri Jan 9 17:57:45 2009 +++ /branches/objc2/hoc/Tests/TestFoundation.hs Tue Aug 11 11:50:04 2009 @@ -1,4 +1,5 @@ -{-# OPTIONS -fth -fglasgow-exts #-} +{-# LANGUAGE TemplateHaskell, TypeSynonymInstances, FlexibleInstances, + MultiParamTypeClasses, RankNTypes, DeriveDataTypeable, CPP #-} module TestFoundation where import HOC @@ -13,7 +14,7 @@ import System.Mem ( performGC ) import Control.Concurrent ( threadDelay ) import Control.Monad ( when ) -import Control.Exception ( try, finally, catchDyn ) +import Control.Exception hiding ( assert ) import qualified System.Info( os ) @@ -300,7 +301,12 @@ let nilNumber = nil :: NSNumber () result <- try (nilNumber # intValue) expected <- try (fail "Message sent to nil: intValue") +#ifdef BASE4 + show (result :: Either SomeException CInt) + @?= show (expected :: Either SomeException CInt) +#else result @?= expected +#endif ) ], "Super" ~: test [ @@ -385,7 +391,12 @@ "HtoCtoH" ~: (do obj <- _ExceptionThrower # alloc >>= init result <- try (obj # throwHaskellException) +#ifdef BASE4 + show (result :: Either SomeException ()) + @?= "Left user error (Test Exception)" +#else show result @?= "Left user error (Test Exception)" +#endif ), "CtoHtoCtoH" ~: (do obj <- _ExceptionThrower # alloc >>= init |
|
From: <cod...@go...> - 2009-08-11 18:50:13
|
Revision: 389 Author: jam...@us... Date: Tue Aug 11 11:49:43 2009 Log: (objc2 branch) Include some instance declarations in generated .hs-boot files for bindings. http://code.google.com/p/hoc/source/detail?r=389 Modified: / /branches/objc2/hoc/InterfaceGenerator2/Output.hs ======================================= --- /branches/objc2/hoc/InterfaceGenerator2/Output.hs Wed Dec 10 08:29:58 2008 +++ /branches/objc2/hoc/InterfaceGenerator2/Output.hs Tue Aug 11 11:49:43 2009 @@ -66,7 +66,8 @@ <+> textBS (eHaskellName e) <> text "MetaClass") pprHsBoot entityPile modName entities - = text "module" <+> textBS modName <+> text "where" $+$ + = text "{-# OPTIONS -fglasgow-exts #-}" $+$ + text "module" <+> textBS modName <+> text "where" $+$ text "import HOC" $+$ vcat imports $+$ vcat classes @@ -84,7 +85,9 @@ <+> parens (textBS name <> char '_' <+> char 'a') $+$ text "type" <+> textBS name <> text "MetaClass" <+> char 'a' <+> equals <+> text (maybe "MetaClass" ( (++ "MetaClass") . BS.unpack . eHaskellName ) mbSuper) - <+> parens (textBS name <> char '_' <+> char 'a') + <+> parens (textBS name <> char '_' <+> char 'a') $+$ + text "instance" <+> text "ClassObject" <+> parens (textBS name <> text "Class" <+> text "()") $+$ + text "_" <> textBS name <+> text "::" <+> textBS name <> text "Class" <+> text "()" | (name, mbSuper) <- classes0 ] |
|
From: <cod...@go...> - 2009-08-11 18:23:51
|
Revision: 388 Author: wol...@gm... Date: Tue Aug 11 11:23:05 2009 Log: Have another shot at fixing the cabal build (issue #12). HOC_cbits.o is passed in via c-sources; Setup.hs now contains a hack that prevents the "ghc: no input files" problem. To be exact: the custom build hook arranges for a short shell script to be called instead of ghc. This shell script checks whether it is being called on HOC_cbits.o and silently ignores that command. For all other parameters, it invokes the actual ghc. http://code.google.com/p/hoc/source/detail?r=388 Modified: /trunk/hoc/HOC.cabal /trunk/hoc/Setup.hs ======================================= --- /trunk/hoc/HOC.cabal Sat Feb 14 12:53:11 2009 +++ /trunk/hoc/HOC.cabal Tue Aug 11 11:23:05 2009 @@ -64,7 +64,16 @@ hs-source-dirs: HOC extra-libraries: objc, ffi + + -- This is a hack. + -- Setup.hs contains code to build HOC_cbits.o from the + -- objective-c sources, as well as a matching hack to prevent + -- Cabal from invoking "ghc -c" on this file. Cabal will then + -- include HOC_cbits.o on the linker command line, which is the + -- whole point of this exercise. c-sources: HOC_cbits.o + + if os(darwin) include-dirs: /usr/include/ffi frameworks: Foundation ======================================= --- /trunk/hoc/Setup.hs Sun Dec 21 13:42:00 2008 +++ /trunk/hoc/Setup.hs Tue Aug 11 11:23:05 2009 @@ -5,6 +5,7 @@ import Distribution.Simple.PreProcess import Distribution.Simple.Configure import Distribution.Simple.LocalBuildInfo +import Distribution.Simple.Program import System.Cmd( system ) import System.Exit( ExitCode(..) ) import System.Environment( getEnv ) @@ -99,6 +100,13 @@ extraFlags <- buildCBits (libBuildInfo libInfo) + -- add compiler flags required by C parts of HOC; + -- + -- HACK #1: + -- This passes the HOC_cbits.o object file on the + -- as a compiler flag so that template haskell can link + -- compile-time code. + let hooked_pd = pd { library = Just $ libInfo { libBuildInfo = addCompilerFlags extraFlags @@ -109,7 +117,42 @@ (executables pd) } - build hooked_pd lbi buildFlags knownSuffixHandlers + -- HACK #2: + -- HOC_cbits.o (built by buildCBits below) is specified in c-sources + -- for the library. Cabal reacts to this by invoking ghc -c HOC_cbits.o, + -- which ghc doesn't like. So, instead of calling ghc directly, we call + -- a short auto-generated shell script that does nothing in this case, + -- and calls the real ghc in all other cases. + -- After having "compiled" HOC_cbits.o in this way, Cabal will link + -- HOC_cbits.o as part of the library, which is what we want. + + let Just pr = lookupKnownProgram "ghc" (withPrograms lbi) + Just conf = lookupProgram pr (withPrograms lbi) + + ghcLocation = programLocation conf + + let fakeGHC = "./dist/build/fake-ghc.sh" + + writeFile fakeGHC $ unlines [ + "#!/bin/sh -e", + "case \"$*\" in", + " *HOC_cbits.o) true;;", + " *) \"" ++ locationPath ghcLocation ++ "\" \"$@\";;", + "esac" + ] + system $ "chmod +x " ++ fakeGHC + + let conf' = conf { programLocation = UserSpecified fakeGHC } + + progs' = updateProgram conf' (withPrograms lbi) + + let lbi' = lbi { + withPrograms = progs' + } + + -- call the default with our modified package description and + -- local build info + build hooked_pd lbi' buildFlags knownSuffixHandlers -- |Build HOC_cbits.o using the flags specified in the configuration -- stage, and return a list of flags to add to support usage of |
|
From: <cod...@go...> - 2009-08-11 17:39:15
|
Revision: 387 Author: wol...@gm... Date: Tue Aug 11 10:37:55 2009 Log: fix a typo http://code.google.com/p/hoc/source/detail?r=387 Modified: /trunk/hoc/InterfaceGenerator2/Output.hs ======================================= --- /trunk/hoc/InterfaceGenerator2/Output.hs Sat Feb 14 12:53:11 2009 +++ /trunk/hoc/InterfaceGenerator2/Output.hs Tue Aug 11 10:37:55 2009 @@ -290,7 +290,7 @@ = text "name:" <+> text "HOC-" <> text frameworkName $+$ text "version: 1.0" $+$ text "build-type: Simple" $+$ - text "Flag base" $+$ + text "Flag base4" $+$ text "Library" $+$ nest 4 ( text "if flag(base4)" $+$ nest 4 ( text "build-depends: base >= 4" $+$ |
|
From: <cod...@go...> - 2009-02-14 21:24:00
|
Author: wol...@gm...
Date: Sat Feb 14 12:53:11 2009
New Revision: 386
Modified:
trunk/hoc/Bindings/AdditionalCode/Foundation/NSException.hs
trunk/hoc/HOC.cabal
trunk/hoc/HOC/HOC/Exception.hs
trunk/hoc/InterfaceGenerator2/Output.hs
trunk/hoc/Tests/MiniFoundation.hs
trunk/hoc/Tests/TestFoundation.hs
Log:
add a flag for base 4.0 support
Modified: trunk/hoc/Bindings/AdditionalCode/Foundation/NSException.hs
==============================================================================
--- trunk/hoc/Bindings/AdditionalCode/Foundation/NSException.hs (original)
+++ trunk/hoc/Bindings/AdditionalCode/Foundation/NSException.hs Sat Feb 14
12:53:11 2009
@@ -1,10 +1,9 @@
--X catchNS
-import Control.Exception ( catchDyn )
-import HOC.Exception ( WrappedNSException(..) )
+import HOC.Exception ( WrappedNSException(..),
catchWrappedNSException )
-- CUT HERE
catchNS :: IO a -> (NSException () -> IO a) -> IO a
catchNS action handler
- = action `catchDyn` \(WrappedNSException exc) -> handler (castObject
exc)
+ = action `catchWrappedNSException` \(WrappedNSException exc) ->
handler (castObject exc)
Modified: trunk/hoc/HOC.cabal
==============================================================================
--- trunk/hoc/HOC.cabal (original)
+++ trunk/hoc/HOC.cabal Sat Feb 14 12:53:11 2009
@@ -17,8 +17,15 @@
Flag ObjC2
description: build for Objective-C 2.0
+Flag base4
+
Library
- build-depends: base < 4, template-haskell, unix
+ build-depends: template-haskell, unix
+ if flag(base4)
+ build-depends: base >= 4, syb
+ cpp-options: -DBASE4
+ else
+ build-depends: base < 4
exposed-modules:
HOC,
@@ -87,7 +94,12 @@
cpp-options: -DTEST
- build-depends: HUnit
+ build-depends: HUnit, template-haskell, unix
+ if flag(base4)
+ build-depends: base >= 4, syb
+ cpp-options: -DBASE4
+ else
+ build-depends: base < 4
if !flag(Tests)
buildable: False
Modified: trunk/hoc/HOC/HOC/Exception.hs
==============================================================================
--- trunk/hoc/HOC/HOC/Exception.hs (original)
+++ trunk/hoc/HOC/HOC/Exception.hs Sat Feb 14 12:53:11 2009
@@ -1,11 +1,12 @@
-{-# LANGUAGE ForeignFunctionInterface, DeriveDataTypeable #-}
+{-# LANGUAGE ForeignFunctionInterface, DeriveDataTypeable,
+ ScopedTypeVariables, CPP #-}
module HOC.Exception where
import Data.Typeable
import Foreign
import Foreign.C.String ( CString, withCString )
import Prelude hiding ( catch )
-import Control.Exception ( Exception, evaluate, throwIO, throwDyn,
catchDyn, catch )
+import Control.Exception
import HOC.Base
import HOC.Arguments
@@ -14,11 +15,53 @@
data WrappedNSException = WrappedNSException (ID ())
deriving Typeable
+exceptionObjCToHaskell :: Ptr ObjCObject -> IO a
-foreign import ccall unsafe wrapHaskellException :: CString -> StablePtr
Exception -> IO (Ptr ObjCObject)
-foreign import ccall unsafe unwrapHaskellException :: Ptr ObjCObject -> IO
(StablePtr Exception)
+#ifdef BASE4
-exceptionObjCToHaskell :: Ptr ObjCObject -> IO a
+foreign import ccall unsafe wrapHaskellException
+ :: CString -> StablePtr SomeException -> IO (Ptr ObjCObject)
+foreign import ccall unsafe unwrapHaskellException
+ :: Ptr ObjCObject -> IO (StablePtr SomeException)
+
+-- get the exception pointer figure out if it is a NSException
+-- or a haskell exception and throw it.
+exceptionObjCToHaskell exception = do
+ sptr <- unwrapHaskellException exception
+ if (castStablePtrToPtr sptr == nullPtr)
+ then do
+ exc <- importArgument exception
+ throwIO $ WrappedNSException exc
+ else do
+ exc <- deRefStablePtr sptr
+ throwIO exc
+
+exceptionHaskellToObjC :: IO a -> IO (Ptr ObjCObject)
+
+exceptionHaskellToObjC action =
+ (action >> return nullPtr)
+ `catches` [
+ Handler $ \(WrappedNSException exc) -> exportArgument exc,
+ Handler $ \(exc :: SomeException) -> withCString (show exc) $
+ \cstr -> newStablePtr exc >>= wrapHaskellException cstr
+ ]
+
+instance Exception WrappedNSException where
+ toException = SomeException
+ fromException (SomeException ex) = cast ex
+
+instance Show WrappedNSException where
+ show (WrappedNSException ex) = "<<NSException>>"
+
+catchWrappedNSException :: IO a -> (WrappedNSException -> IO a) -> IO a
+catchWrappedNSException = catch
+
+#else
+
+foreign import ccall unsafe wrapHaskellException
+ :: CString -> StablePtr Exception -> IO (Ptr ObjCObject)
+foreign import ccall unsafe unwrapHaskellException
+ :: Ptr ObjCObject -> IO (StablePtr Exception)
-- get the exception pointer figure out if it is a NSException
-- or a haskell exception and throw it.
@@ -40,3 +83,8 @@
(\(WrappedNSException exc) -> exportArgument exc)
`catch`
(\exc -> withCString (show exc) $ \cstr -> newStablePtr exc >>=
wrapHaskellException cstr)
+
+catchWrappedNSException :: IO a -> (WrappedNSException -> IO a) -> IO a
+catchWrappedNSException = catchDyn
+
+#endif
Modified: trunk/hoc/InterfaceGenerator2/Output.hs
==============================================================================
--- trunk/hoc/InterfaceGenerator2/Output.hs (original)
+++ trunk/hoc/InterfaceGenerator2/Output.hs Sat Feb 14 12:53:11 2009
@@ -290,13 +290,21 @@
= text "name:" <+> text "HOC-" <> text frameworkName $+$
text "version: 1.0" $+$
text "build-type: Simple" $+$
- text "build-depends:" <+>
- hsep (punctuate comma $ map text $
- ["base <4", "HOC"] ++ map ("HOC-" ++) dependencies) $+$
--- text "" $+$
- text "exposed-modules:" <+> sep (punctuate comma $
- map textBS $ BS.pack
frameworkName : modules) $+$
- text "frameworks:" <+> text frameworkName
+ text "Flag base" $+$
+ text "Library" $+$ nest 4 (
+ text "if flag(base4)" $+$ nest 4 (
+ text "build-depends: base >= 4" $+$
+ text "cpp-options: -DBASE4" -- don't neeed the define yet,
though
+ ) $+$ text "else" $+$ nest 4 (
+ text "build-depends: base < 4"
+ ) $+$
+ text "build-depends:" <+>
+ hsep (punctuate comma $ map text $
+ ["HOC"] ++ map ("HOC-" ++) dependencies) $+$
+ text "exposed-modules:" <+> sep (punctuate comma $
+ map textBS $ BS.pack
frameworkName : modules) $+$
+ text "frameworks:" <+> text frameworkName
+ )
where
modules = [ m | LocalModule m
<- Set.toList $ Set.fromList $
Modified: trunk/hoc/Tests/MiniFoundation.hs
==============================================================================
--- trunk/hoc/Tests/MiniFoundation.hs (original)
+++ trunk/hoc/Tests/MiniFoundation.hs Sat Feb 14 12:53:11 2009
@@ -1,13 +1,14 @@
{-# LANGUAGE TemplateHaskell, StandaloneDeriving, MultiParamTypeClasses,
- TypeSynonymInstances, FlexibleInstances, RankNTypes #-}
+ TypeSynonymInstances, FlexibleInstances, RankNTypes, CPP #-}
module MiniFoundation where
import HOC
import HOC.Exception ( WrappedNSException(..) )
import Foreign.C.Types
-import Control.Exception ( catchDyn )
+import Control.Exception
import System.IO.Unsafe ( unsafePerformIO )
+import Prelude hiding ( catch )
$(declareClass "NSObject" "ID")
$(declareClass "NSString" "NSObject")
@@ -109,8 +110,13 @@
catchNS :: IO a -> (NSException () -> IO a) -> IO a
+#ifdef BASE4
+catchNS action handler
+ = action `catch` \(WrappedNSException exc) -> handler (castObject exc)
+#else
catchNS action handler
= action `catchDyn` \(WrappedNSException exc) -> handler (castObject
exc)
+#endif
-- NSMutableArray
Modified: trunk/hoc/Tests/TestFoundation.hs
==============================================================================
--- trunk/hoc/Tests/TestFoundation.hs (original)
+++ trunk/hoc/Tests/TestFoundation.hs Sat Feb 14 12:53:11 2009
@@ -1,4 +1,5 @@
-{-# OPTIONS -fth -fglasgow-exts #-}
+{-# LANGUAGE TemplateHaskell, TypeSynonymInstances, FlexibleInstances,
+ MultiParamTypeClasses, RankNTypes, DeriveDataTypeable, CPP #-}
module TestFoundation where
import HOC
@@ -13,7 +14,7 @@
import System.Mem ( performGC )
import Control.Concurrent ( threadDelay )
import Control.Monad ( when )
-import Control.Exception ( try, finally, catchDyn )
+import Control.Exception hiding ( assert )
import qualified System.Info( os )
@@ -300,7 +301,12 @@
let nilNumber = nil :: NSNumber ()
result <- try (nilNumber # intValue)
expected <- try (fail "Message sent to nil: intValue")
+#ifdef BASE4
+ show (result :: Either SomeException CInt)
+ @?= show (expected :: Either SomeException CInt)
+#else
result @?= expected
+#endif
)
],
"Super" ~: test [
@@ -385,7 +391,12 @@
"HtoCtoH" ~: (do
obj <- _ExceptionThrower # alloc >>= init
result <- try (obj # throwHaskellException)
+#ifdef BASE4
+ show (result :: Either SomeException ())
+ @?= "Left user error (Test Exception)"
+#else
show result @?= "Left user error (Test Exception)"
+#endif
),
"CtoHtoCtoH" ~: (do
obj <- _ExceptionThrower # alloc >>= init
|
|
From: <cod...@go...> - 2009-01-13 16:54:54
|
Author: jam...@us...
Date: Tue Jan 13 08:54:16 2009
New Revision: 385
Modified:
/ (props changed)
trunk/hoc/InterfaceGenerator2/Output.hs
Log:
Quick fix in InterfaceGenerator2 to make bindings build on ghc 6.10:
adds "<4" to the "base" dependency in the generated cabal file. A more
complete fix could be to add cabal file splicing and/or pragma splicing to
the AdditionalCode handling system.
Modified: trunk/hoc/InterfaceGenerator2/Output.hs
==============================================================================
--- trunk/hoc/InterfaceGenerator2/Output.hs (original)
+++ trunk/hoc/InterfaceGenerator2/Output.hs Tue Jan 13 08:54:16 2009
@@ -292,7 +292,7 @@
text "build-type: Simple" $+$
text "build-depends:" <+>
hsep (punctuate comma $ map text $
- ["base", "HOC"] ++ map ("HOC-" ++) dependencies) $+$
+ ["base <4", "HOC"] ++ map ("HOC-" ++) dependencies) $+$
-- text "" $+$
text "exposed-modules:" <+> sep (punctuate comma $
map textBS $ BS.pack
frameworkName : modules) $+$
|
|
From: <cod...@go...> - 2009-01-10 02:20:02
|
Author: jam...@us...
Date: Fri Jan 9 18:06:02 2009
New Revision: 384
Modified:
/ (props changed)
branches/objc2/hoc/HOC/HOC/NewClass.hs
Log:
Fixing merge error - I accidentally took 2 versions of the same function.
Modified: branches/objc2/hoc/HOC/HOC/NewClass.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/NewClass.hs (original)
+++ branches/objc2/hoc/HOC/HOC/NewClass.hs Fri Jan 9 18:06:02 2009
@@ -109,8 +109,6 @@
setHaskellReleaseMethod methodList idx super =
setMethodInList methodList idx releaseSelector "v@:" releaseCif
(haskellObject_release_IMP super)
-setHaskellReleaseMethod methodList idx =
- setMethodInList methodList idx releaseSelector "v@:" releaseCif
haskellObject_release_IMP
setHaskellDataMethod methodList idx super mbDat =
setMethodInList methodList idx getHaskellDataSelector "^v@:#"
getHaskellDataCif (getHaskellData_IMP super mbDat)
|
|
From: <cod...@go...> - 2009-01-10 01:59:43
|
Author: jam...@us...
Date: Fri Jan 9 17:57:45 2009
New Revision: 383
Modified:
/ (props changed)
branches/objc2/hoc/ (props changed)
branches/objc2/hoc/HOC.cabal
branches/objc2/hoc/HOC/HOC/Exception.hs
branches/objc2/hoc/HOC/HOC/NewClass.hs
branches/objc2/hoc/HOC/HOC/StdArgumentTypes.hs
branches/objc2/hoc/HOC_cbits/Ivars.h (props changed)
branches/objc2/hoc/HOC_cbits/Methods.h (props changed)
branches/objc2/hoc/InterfaceGenerator2/Headers.hs
branches/objc2/hoc/InterfaceGenerator2/ParserBase.hs
branches/objc2/hoc/Tests/MiniFoundation.hs
branches/objc2/hoc/Tests/TestFoundation.hs
Log:
merging trunk back to objc2 branch
Modified: branches/objc2/hoc/HOC.cabal
==============================================================================
--- branches/objc2/hoc/HOC.cabal (original)
+++ branches/objc2/hoc/HOC.cabal Fri Jan 9 17:57:45 2009
@@ -18,7 +18,7 @@
description: build for Objective-C 2.0
Library
- build-depends: base, template-haskell, unix
+ build-depends: base < 4, template-haskell, unix
exposed-modules:
HOC,
Modified: branches/objc2/hoc/HOC/HOC/Exception.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/Exception.hs (original)
+++ branches/objc2/hoc/HOC/HOC/Exception.hs Fri Jan 9 17:57:45 2009
@@ -5,7 +5,7 @@
import Foreign
import Foreign.C.String ( CString, withCString )
import Prelude hiding ( catch )
-import Control.Exception ( evaluate, throwIO, throwDyn, catchDyn, catch
)
+import Control.Exception ( Exception, evaluate, throwIO, throwDyn,
catchDyn, catch )
import HOC.Base
import HOC.Arguments
@@ -15,8 +15,8 @@
deriving Typeable
-foreign import ccall unsafe wrapHaskellException :: CString -> StablePtr a
-> IO (Ptr ObjCObject)
-foreign import ccall unsafe unwrapHaskellException :: Ptr ObjCObject -> IO
(StablePtr a)
+foreign import ccall unsafe wrapHaskellException :: CString -> StablePtr
Exception -> IO (Ptr ObjCObject)
+foreign import ccall unsafe unwrapHaskellException :: Ptr ObjCObject -> IO
(StablePtr Exception)
exceptionObjCToHaskell :: Ptr ObjCObject -> IO a
Modified: branches/objc2/hoc/HOC/HOC/NewClass.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/NewClass.hs (original)
+++ branches/objc2/hoc/HOC/HOC/NewClass.hs Fri Jan 9 17:57:45 2009
@@ -109,6 +109,8 @@
setHaskellReleaseMethod methodList idx super =
setMethodInList methodList idx releaseSelector "v@:" releaseCif
(haskellObject_release_IMP super)
+setHaskellReleaseMethod methodList idx =
+ setMethodInList methodList idx releaseSelector "v@:" releaseCif
haskellObject_release_IMP
setHaskellDataMethod methodList idx super mbDat =
setMethodInList methodList idx getHaskellDataSelector "^v@:#"
getHaskellDataCif (getHaskellData_IMP super mbDat)
Modified: branches/objc2/hoc/HOC/HOC/StdArgumentTypes.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/StdArgumentTypes.hs (original)
+++ branches/objc2/hoc/HOC/HOC/StdArgumentTypes.hs Fri Jan 9 17:57:45 2009
@@ -78,6 +78,16 @@
withUTF8String str = withArray0 0 (unicodeToUtf8 str)
+instance ObjCArgument a (Ptr b) => ObjCArgument (Maybe a) (Ptr b) where
+ withExportedArgument Nothing action = action nullPtr
+ withExportedArgument (Just x) action = withExportedArgument x action
+ exportArgument Nothing = return nullPtr
+ exportArgument (Just x) = exportArgument x
+ importArgument p
+ | p == nullPtr = return Nothing
+ | otherwise = fmap Just (importArgument p)
+ objCTypeString _ = objCTypeString (undefined :: a)
+
instance ObjCArgument String (Ptr ObjCObject) where
withExportedArgument arg action =
bracket (withUTF8String arg utf8ToNSString) releaseObject action
@@ -88,4 +98,4 @@
importArgument arg = nsStringToUTF8 arg >>= peekArray0 0
>>= return . utf8ToUnicode
- objCTypeString _ = "*"
+ objCTypeString _ = "@"
Modified: branches/objc2/hoc/InterfaceGenerator2/Headers.hs
==============================================================================
--- branches/objc2/hoc/InterfaceGenerator2/Headers.hs (original)
+++ branches/objc2/hoc/InterfaceGenerator2/Headers.hs Fri Jan 9 17:57:45
2009
@@ -12,7 +12,7 @@
import Control.Monad(when)
import Data.Char(isAlphaNum, toUpper)
import Data.List(isPrefixOf,isSuffixOf)
-import Data.Maybe(mapMaybe)
+import Data.Maybe(mapMaybe, maybeToList)
import System.Directory(getDirectoryContents, doesDirectoryExist)
import System.Info(os)
import Text.Parsec( runParserT )
@@ -89,9 +89,9 @@
graph :: Gr () ()
graph = mkUGraph [ 0 .. length loaded - 1 ]
[ (to, from) | (_, name, includes, _) <- loaded,
- from <- Map.lookup name
namesToNums,
+ from <- maybeToList $ Map.lookup
name namesToNums,
include <- includes,
- to <- Map.lookup include
namesToNums ]
+ to <- maybeToList $ Map.lookup
include namesToNums ]
sorted = map (numsToHeaders Map.!) $ topsort graph
process ( (headerFileName, moduleName, imports, contents) :
moreHeaders ) env accum
Modified: branches/objc2/hoc/InterfaceGenerator2/ParserBase.hs
==============================================================================
--- branches/objc2/hoc/InterfaceGenerator2/ParserBase.hs (original)
+++ branches/objc2/hoc/InterfaceGenerator2/ParserBase.hs Fri Jan 9
17:57:45 2009
@@ -21,7 +21,13 @@
= fst $ runMessages $ runParserT parser emptyParseEnvironment fileName
text
lookupIntegerConstant :: String -> Parser Integer
-lookupIntegerConstant name = getState >>= Map.lookup name
+lookupIntegerConstant name = getState >>= mapLookup name
+ where
+ -- ghc 6.10's containers package no longer allows arbitrary
+ -- monads in its return types
+ mapLookup k v = case Map.lookup k v of
+ Nothing -> fail "Integer constant not found"
+ Just x -> return x
defineIntegerConstant :: String -> Integer -> Parser ()
defineIntegerConstant name value = modifyState (Map.insert name value)
Modified: branches/objc2/hoc/Tests/MiniFoundation.hs
==============================================================================
--- branches/objc2/hoc/Tests/MiniFoundation.hs (original)
+++ branches/objc2/hoc/Tests/MiniFoundation.hs Fri Jan 9 17:57:45 2009
@@ -115,8 +115,10 @@
-- NSMutableArray
$(declareSelector "addObject:" [t| forall t1 . ID t1 -> IO () |])
+$(declareSelector "objectAtIndex:" [t| forall a. CUInt -> IO (ID a) |] )
instance Has_addObject (NSMutableArray a)
+instance Has_objectAtIndex (NSMutableArray a)
deriving instance Show NSRect
deriving instance Show NSPoint
Modified: branches/objc2/hoc/Tests/TestFoundation.hs
==============================================================================
--- branches/objc2/hoc/Tests/TestFoundation.hs (original)
+++ branches/objc2/hoc/Tests/TestFoundation.hs Fri Jan 9 17:57:45 2009
@@ -48,8 +48,15 @@
instance Has_otherObject (HaskellObjectWithOutlet a)
instance Has_setOtherObject (HaskellObjectWithOutlet a)
+$(declareSelector "maybeString" [t| IO (Maybe String) |])
+$(declareSelector "setMaybeString:" [t| Maybe String -> IO () |] )
+
+instance Has_maybeString (HaskellObjectWithOutlet a)
+instance Has_setMaybeString (HaskellObjectWithOutlet a)
+
$(exportClass "HaskellObjectWithOutlet" "ho1_" [
- Outlet "otherObject" [t| ID () |]
+ Outlet "otherObject" [t| ID () |],
+ Outlet "maybeString" [t| NSString () |]
])
$(declareClass "HaskellObjectWithDescription" "NSObject")
@@ -214,6 +221,37 @@
hobj # setOtherObject num
num' <- hobj # otherObject >>= return . castObject
when (num /= num') $ assert "Different Object returned."
+ ),
+ "set-forget-reget" ~: (assertNoLeaks $ do
+ -- set an ivar, 'forget' the object (stash it outside
haskell-space),
+ -- run the GC, 'remember' the object, and read the ivar.
+
+ -- this catches a class of bug which helped me grok
HSOs ;-)
+
+ (num, array) <- assertLeaks 3 $ do
+ num <- _NSNumber # alloc >>= initWithInt 42
+ hobj <- _HaskellObjectWithOutlet # alloc >>= init
+ hobj # setOtherObject num
+
+ array <- _NSMutableArray # alloc >>= init
+ array # addObject hobj
+
+ return (num, array)
+
+ assertLeaks (-3) $ do
+ hobj <- array # objectAtIndex 0 :: IO
(HaskellObjectWithOutlet ())
+
+ num' <- hobj # otherObject >>= return . castObject
+ when (num /= num') $ assert "Different Object
returned."
+ ),
+ "set-get-maybeString" ~: (assertNoLeaks $ do
+ hobj <- _HaskellObjectWithOutlet # alloc >>= init
+ nothing <- hobj # maybeString
+ nothing @?= Nothing
+
+ hobj # setMaybeString (Just "42")
+ just42 <- hobj # maybeString
+ just42 @?= Just "42"
)
],
"HaskellObjectWithIVar" ~: test [
|
|
From: <cod...@go...> - 2009-01-10 01:50:35
|
Author: jam...@us...
Date: Fri Jan 9 17:28:12 2009
New Revision: 382
Modified:
/ (props changed)
trunk/hoc/HOC/HOC/StdArgumentTypes.hs
trunk/hoc/Tests/MiniFoundation.hs
trunk/hoc/Tests/TestFoundation.hs
Log:
Added an ObjCArgument instance for Maybe versions of all Ptr-marshalled
types which maps nullPtr to Nothing.
Also added test cases for this and for something else I noticed a while
back (not a bug in HOC, but a bug in some experiments I had been doing with
ID marshalling). It's somewhat redundant, but gives a good illustration of
why certain other tests were failing in my experiments.
Modified: trunk/hoc/HOC/HOC/StdArgumentTypes.hs
==============================================================================
--- trunk/hoc/HOC/HOC/StdArgumentTypes.hs (original)
+++ trunk/hoc/HOC/HOC/StdArgumentTypes.hs Fri Jan 9 17:28:12 2009
@@ -78,6 +78,16 @@
withUTF8String str = withArray0 0 (unicodeToUtf8 str)
+instance ObjCArgument a (Ptr b) => ObjCArgument (Maybe a) (Ptr b) where
+ withExportedArgument Nothing action = action nullPtr
+ withExportedArgument (Just x) action = withExportedArgument x action
+ exportArgument Nothing = return nullPtr
+ exportArgument (Just x) = exportArgument x
+ importArgument p
+ | p == nullPtr = return Nothing
+ | otherwise = fmap Just (importArgument p)
+ objCTypeString _ = objCTypeString (undefined :: a)
+
instance ObjCArgument String (Ptr ObjCObject) where
withExportedArgument arg action =
bracket (withUTF8String arg utf8ToNSString) releaseObject action
Modified: trunk/hoc/Tests/MiniFoundation.hs
==============================================================================
--- trunk/hoc/Tests/MiniFoundation.hs (original)
+++ trunk/hoc/Tests/MiniFoundation.hs Fri Jan 9 17:28:12 2009
@@ -115,8 +115,10 @@
-- NSMutableArray
$(declareSelector "addObject:" [t| forall t1 . ID t1 -> IO () |])
+$(declareSelector "objectAtIndex:" [t| forall a. CUInt -> IO (ID a) |] )
instance Has_addObject (NSMutableArray a)
+instance Has_objectAtIndex (NSMutableArray a)
deriving instance Show NSRect
deriving instance Show NSPoint
Modified: trunk/hoc/Tests/TestFoundation.hs
==============================================================================
--- trunk/hoc/Tests/TestFoundation.hs (original)
+++ trunk/hoc/Tests/TestFoundation.hs Fri Jan 9 17:28:12 2009
@@ -48,8 +48,15 @@
instance Has_otherObject (HaskellObjectWithOutlet a)
instance Has_setOtherObject (HaskellObjectWithOutlet a)
+$(declareSelector "maybeString" [t| IO (Maybe String) |])
+$(declareSelector "setMaybeString:" [t| Maybe String -> IO () |] )
+
+instance Has_maybeString (HaskellObjectWithOutlet a)
+instance Has_setMaybeString (HaskellObjectWithOutlet a)
+
$(exportClass "HaskellObjectWithOutlet" "ho1_" [
- Outlet "otherObject" [t| ID () |]
+ Outlet "otherObject" [t| ID () |],
+ Outlet "maybeString" [t| NSString () |]
])
$(declareClass "HaskellObjectWithDescription" "NSObject")
@@ -214,6 +221,37 @@
hobj # setOtherObject num
num' <- hobj # otherObject >>= return . castObject
when (num /= num') $ assert "Different Object returned."
+ ),
+ "set-forget-reget" ~: (assertNoLeaks $ do
+ -- set an ivar, 'forget' the object (stash it outside
haskell-space),
+ -- run the GC, 'remember' the object, and read the ivar.
+
+ -- this catches a class of bug which helped me grok
HSOs ;-)
+
+ (num, array) <- assertLeaks 3 $ do
+ num <- _NSNumber # alloc >>= initWithInt 42
+ hobj <- _HaskellObjectWithOutlet # alloc >>= init
+ hobj # setOtherObject num
+
+ array <- _NSMutableArray # alloc >>= init
+ array # addObject hobj
+
+ return (num, array)
+
+ assertLeaks (-3) $ do
+ hobj <- array # objectAtIndex 0 :: IO
(HaskellObjectWithOutlet ())
+
+ num' <- hobj # otherObject >>= return . castObject
+ when (num /= num') $ assert "Different Object
returned."
+ ),
+ "set-get-maybeString" ~: (assertNoLeaks $ do
+ hobj <- _HaskellObjectWithOutlet # alloc >>= init
+ nothing <- hobj # maybeString
+ nothing @?= Nothing
+
+ hobj # setMaybeString (Just "42")
+ just42 <- hobj # maybeString
+ just42 @?= Just "42"
)
],
"HaskellObjectWithIVar" ~: test [
|
|
From: <cod...@go...> - 2009-01-10 01:26:34
|
Author: jam...@us...
Date: Fri Jan 9 16:57:16 2009
New Revision: 381
Modified:
/ (props changed)
trunk/hoc/HOC/HOC/StdArgumentTypes.hs
Log:
Fixed argument type code for String ("*" is for C strings - should be "@"
for an object - I assume this is true in GNUStep too?)
Modified: trunk/hoc/HOC/HOC/StdArgumentTypes.hs
==============================================================================
--- trunk/hoc/HOC/HOC/StdArgumentTypes.hs (original)
+++ trunk/hoc/HOC/HOC/StdArgumentTypes.hs Fri Jan 9 16:57:16 2009
@@ -88,4 +88,4 @@
importArgument arg = nsStringToUTF8 arg >>= peekArray0 0
>>= return . utf8ToUnicode
- objCTypeString _ = "*"
+ objCTypeString _ = "@"
|
|
From: <cod...@go...> - 2009-01-10 01:15:29
|
Author: jam...@us...
Date: Fri Jan 9 16:57:06 2009
New Revision: 380
Modified:
/ (props changed)
branches/objc2/hoc/HOC/HOC/ExportClass.hs
branches/objc2/hoc/HOC/HOC/ID.hs
branches/objc2/hoc/HOC/HOC/NewClass.hs
branches/objc2/hoc/HOC_cbits/MemoryManagement.h
branches/objc2/hoc/HOC_cbits/MemoryManagement.m
Log:
(objc2 branch) Rewrote retain/release to call superclass's implementations.
Modified: branches/objc2/hoc/HOC/HOC/ExportClass.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/ExportClass.hs (original)
+++ branches/objc2/hoc/HOC/HOC/ExportClass.hs Fri Jan 9 16:57:06 2009
@@ -130,8 +130,8 @@
ivars <- makeDefaultIvarList
imethods <- makeMethodList (nIMethods+3)
cmethods <- makeMethodList nCMethods
- setHaskellRetainMethod imethods 0
- setHaskellReleaseMethod imethods 1
+ setHaskellRetainMethod imethods 0 super
+ setHaskellReleaseMethod imethods 1 super
setHaskellDataMethod imethods 2 super (
Just ($(typedInitIvars) >>= return . toDyn)
)
Modified: branches/objc2/hoc/HOC/HOC/ID.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/ID.hs (original)
+++ branches/objc2/hoc/HOC/HOC/ID.hs Fri Jan 9 16:57:06 2009
@@ -8,7 +8,7 @@
import Control.Concurrent.MVar
import Control.Exception(evaluate,assert)
-import Control.Monad(when)
+import Control.Monad(when, join)
import System.IO.Unsafe(unsafePerformIO)
import System.Mem.Weak
import Foreign.Ptr
@@ -21,6 +21,12 @@
data ID a = ID HSO | Nil
+dPutStrLn = if {--} False --} True
+ then putStrLn
+ else const $ return ()
+
+dPutWords = dPutStrLn . unwords
+
nil = Nil
castObject (ID a) = ID a
@@ -59,6 +65,13 @@
objectMapLock = unsafePerformIO $ newMVar ()
{-# NOINLINE objectMapLock #-}
+withObjectMapLock taker action = do
+ dPutWords [">", "withObjectMapLock", taker]
+ res <- withMVar objectMapLock $ \_ -> action
+ dPutWords ["<", "withObjectMapLock", taker]
+ return res
+
+
-- given a pointer to an ObjCObject, return a stablePtr to a Weak
reference to
-- a HSO
foreign import ccall unsafe "ObjectMap.h getHaskellPart"
@@ -91,13 +104,21 @@
getRetainedHaskellPart :: Ptr ObjCObject -> IO (StablePtr HSO)
foreign import ccall unsafe "RetainedHaskellPart.h setRetainedHaskellPart"
setRetainedHaskellPart :: Ptr ObjCObject -> StablePtr HSO -> IO ()
-
-foreign import ccall unsafe "NSObjectReferenceCount.h
NSIncrementExtraRefCount"
- nsIncrementExtraRefCount :: Ptr ObjCObject -> IO ()
-foreign import ccall unsafe "NSObjectReferenceCount.h
NSDecrementExtraRefCountWasZero"
- nsDecrementExtraRefCountWasZero :: Ptr ObjCObject -> IO CChar{-BOOL-}
-foreign import ccall unsafe "NSObjectReferenceCount.h NSExtraRefCount"
- nsExtraRefCount :: Ptr ObjCObject -> IO CUInt
+replaceRetainedHaskellPart :: Ptr ObjCObject -> StablePtr HSO -> IO ()
+replaceRetainedHaskellPart self newHSO = do
+ dPutWords ["replaceRetainedHaskellPart", show self, show
(castStablePtrToPtr newHSO)]
+ oldHSO <- getRetainedHaskellPart self
+ when (oldHSO /= newHSO) $ do
+ when (castStablePtrToPtr oldHSO /= nullPtr) $ do
+ freeStablePtr oldHSO
+ setRetainedHaskellPart self newHSO
+
+foreign import ccall "MemoryManagement.h retainSuper"
+ retainSuper :: Ptr ObjCObject -> Ptr ObjCObject -> IO ()
+foreign import ccall "MemoryManagement.h releaseSuper"
+ releaseSuper :: Ptr ObjCObject -> Ptr ObjCObject -> IO ()
+foreign import ccall unsafe "MemoryManagement.h retainCount"
+ retainCount :: Ptr ObjCObject -> IO CUInt
-- Since finalizers are executed in arbitrary threads, we must
-- ensure that we establish an autoreleasepool for the duration
@@ -147,11 +168,13 @@
importImmortal = importArgument' True
--- this is where the mogic happens.
+-- this is where the magic happens.
importArgument' immortal p
| p == nullPtr = return Nil
- -- objectMapLock is a global, thanks to unsafePerformIO
- | otherwise = withMVar objectMapLock $ \_ -> do
+ -- do what needs to be done in the lock, return what
+ -- needs to be done outside the lock (specifically,
+ -- the retain needs to be done outside the lock).
+ | otherwise = join $ withObjectMapLock "importArgument'" $ do
sptr <- getHaskellPart p
mbHaskellObj <-
if castStablePtrToPtr sptr /= nullPtr
@@ -162,39 +185,31 @@
return Nothing
case mbHaskellObj of
-- if the HSO already exists, we're done!
- Just haskellObj -> return $ ID haskellObj
+ Just haskellObj -> return $ return $ ID haskellObj
-- notice that the finalizer definition requires new_sptr
Nothing -> mdo {- it's much more pratical than fixM -}
haskellData <- makeNewHaskellData p
+ dPutWords ["got haskell data", show haskellData]
let haskellObj = HSO p (fromMaybe [] haskellData)
- finalizer | isJust haskellData = Just $
finalizeHaskellID p new_sptr
- | immortal = Nothing
+ finalizer | immortal = Nothing
| otherwise = Just $ finalizeID p new_sptr
wptr <- mkWeakPtr haskellObj finalizer
new_sptr <- newStablePtr wptr
setHaskellPart p new_sptr (if immortal then 1 else 0)
- case haskellData of
- Just _ -> haskellObject_retain p
- Nothing -> retainObject p
-
- return $ ID haskellObj
+ return $ do
+ -- retain the object, but do it outside the
+ -- lock because the retain IMP may need the lock.
+ retainObject p
+ return $ ID haskellObj
finalizeID :: Ptr ObjCObject -> StablePtr (Weak HSO) -> IO ()
finalizeID cObj sptr = do
- withMVar objectMapLock $ \_ -> removeHaskellPart cObj sptr
+ withObjectMapLock "finalizeID" $ removeHaskellPart cObj sptr
+
releaseObjectWithPool cObj
freeStablePtr sptr
-finalizeHaskellID :: Ptr ObjCObject -> StablePtr (Weak HSO) -> IO ()
-finalizeHaskellID cObj sptr = do
- withMVar objectMapLock $ \_ -> removeHaskellPart cObj sptr
- extraRefs <- nsExtraRefCount cObj
- -- putStrLn "destroy haskelll object"
- assert (extraRefs == 0) (deallocObjectWithPool cObj)
- freeStablePtr sptr
-
---
makeNewHaskellData p = do
stable <- getNewHaskellData p
if (castStablePtrToPtr stable == nullPtr)
@@ -204,77 +219,74 @@
freeStablePtr stable
return (Just dat)
-haskellObject_retain_IMP :: FFICif -> Ptr () -> Ptr (Ptr ()) -> IO (Ptr
ObjCObject)
-haskellObject_retain_IMP cif ret args = do
+haskellObject_retain_IMP :: Ptr ObjCObject -> FFICif -> Ptr () -> Ptr (Ptr
()) -> IO (Ptr ObjCObject)
+haskellObject_retain_IMP super cif ret args = do
selfPtr <- peekElemOff args 0
self <- peek (castPtr selfPtr) :: IO (Ptr ObjCObject)
poke (castPtr ret) self -- retain returns self
- -- putStrLn "retain haskell object_IMP"
- withMVar objectMapLock $ \_ -> haskellObject_retain self
+ dPutWords ["haskellObject_retain_IMP", show super, "<FFICif>", show
ret, show args]
+ haskellObject_retain self super
return nullPtr -- no exception
-haskellObject_retain self = do
- -- putStrLn "retain haskell object"
- nsIncrementExtraRefCount self
+haskellObject_retain self super = do
+ dPutWords ["haskellObject_retain", show self, show super]
+ retainSuper self super
+ dPutStrLn "retained super"
- stablePtrToHaskellSelf <- getRetainedHaskellPart self
- when (castStablePtrToPtr stablePtrToHaskellSelf == nullPtr) $ do
- stableWeakPtrToHaskellSelf <- getHaskellPart self
- when (castStablePtrToPtr stableWeakPtrToHaskellSelf /= nullPtr) $
do
- weakPtrToHaskellSelf <- deRefStablePtr
stableWeakPtrToHaskellSelf
- mbHaskellSelf <- deRefWeak weakPtrToHaskellSelf
- case mbHaskellSelf of
- Just haskellSelf -> do
- stablePtrToHaskellSelf <- newStablePtr haskellSelf
- setRetainedHaskellPart self stablePtrToHaskellSelf
- Nothing ->
- -- The weak pointer will only be dealloced when there
are
- -- no known references from ObjC and no references
from Haskell.
- -- So if we get here, it's not my bug (hopefully).
- -- When an object is exported (returned or passed as a
parameter)
- -- from Haskell, it is retained and autoreleased, so
passing an
- -- object from Haskell to Objective C and immediately
forgetting
- -- the reference (before ObjC has a chance to retain
it) is safe.
-
- error "Error: Retaining Haskell Object that has
already been released"
+ withObjectMapLock "haskellObject_retain" $ do
+ stablePtrToHaskellSelf <- getRetainedHaskellPart self
+ when (castStablePtrToPtr stablePtrToHaskellSelf == nullPtr) $ do
+ stableWeakPtrToHaskellSelf <- getHaskellPart self
+ when (castStablePtrToPtr stableWeakPtrToHaskellSelf /=
nullPtr) $ do
+ weakPtrToHaskellSelf <- deRefStablePtr
stableWeakPtrToHaskellSelf
+ mbHaskellSelf <- deRefWeak weakPtrToHaskellSelf
+ case mbHaskellSelf of
+ Just haskellSelf -> do
+ stablePtrToHaskellSelf <- newStablePtr haskellSelf
+ setRetainedHaskellPart self stablePtrToHaskellSelf
+ Nothing ->
+ -- The weak pointer will only be dealloced when
there are
+ -- no known references from ObjC and no references
from Haskell.
+ -- So if we get here, it's not my bug (hopefully).
+ -- When an object is exported (returned or passed
as a parameter)
+ -- from Haskell, it is retained and autoreleased,
so passing an
+ -- object from Haskell to Objective C and
immediately forgetting
+ -- the reference (before ObjC has a chance to
retain it) is safe.
+
+ error "Error: Retaining Haskell Object that has
already been released"
-haskellObject_release_IMP :: FFICif -> Ptr () -> Ptr (Ptr ()) -> IO (Ptr
ObjCObject)
-haskellObject_release_IMP cif ret args = do
+haskellObject_release_IMP :: Ptr ObjCObject -> FFICif -> Ptr () -> Ptr
(Ptr ()) -> IO (Ptr ObjCObject)
+haskellObject_release_IMP super cif ret args = do
selfPtr <- peekElemOff args 0
self <- peek (castPtr selfPtr) :: IO (Ptr ObjCObject)
- -- putStrLn "release haskell object_IMP"
- withMVar objectMapLock $ \_ -> haskellObject_release self
+ dPutWords ["haskellObject_release_IMP", show super, "<FFICif>", show
ret, show args]
+ haskellObject_release super self
return nullPtr -- no exception
-haskellObject_release self = do
- -- putStrLn "release haskell object"
- wasZero <- nsDecrementExtraRefCountWasZero self
- -- nobody else should call NSDecrementExtraRefCountWasZero anyway,
- -- and we're protected from ourselves by the objectMapLock
- -- ==> no race condition here
- refCount <- nsExtraRefCount self
+haskellObject_release super self = do
+ dPutWords ["haskellObject_release", show super, show self]
+ retainCount+1 <- retainCount self
+ -- retainCount+1 because we want to know the retainCount after we
+ -- release; if it's about to become zero, then we won't be
+ -- able to call retainCount on self after the call to releaseSuper.
+ releaseSuper self super
+ -- retainCount should now contain the current retain count.
- when (refCount == 0) $ do
+ when (retainCount == 1) $ withObjectMapLock "haskellObject_release" $
do
-- no extra references
-- Only the reference from the Haskell part remains,
-- which means we do no longer want to have a stable pointer
-- (if we have one, that is)
- stablePtrToHaskellSelf <- getRetainedHaskellPart self
- when (castStablePtrToPtr stablePtrToHaskellSelf /= nullPtr) $ do
- freeStablePtr stablePtrToHaskellSelf
- setRetainedHaskellPart self (castPtrToStablePtr nullPtr)
-
- when (wasZero /= 0) $ do
- deallocObject self
+ replaceRetainedHaskellPart self (castPtrToStablePtr nullPtr)
-- this is the implementation of the __getHaskellData__ selector.
getHaskellData_IMP :: Ptr ObjCObject -> Maybe (IO Dynamic)
-> FFICif -> Ptr () -> Ptr (Ptr ()) -> IO (Ptr
ObjCObject)
getHaskellData_IMP super mbDat cif ret args = do
- -- putStrLn "__getHaskellData__"
selfPtr <- peekElemOff args 0
self <- peek (castPtr selfPtr) :: IO (Ptr ObjCObject)
+ dPutWords ["__getHaskellData__", show self, show super]
superDataStable <- getNewHaskellDataForClass self super
superData <- if castStablePtrToPtr superDataStable == nullPtr
then do
Modified: branches/objc2/hoc/HOC/HOC/NewClass.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/NewClass.hs (original)
+++ branches/objc2/hoc/HOC/HOC/NewClass.hs Fri Jan 9 16:57:06 2009
@@ -95,20 +95,20 @@
return list
retainSelector = getSelectorForName "retain"
-retainCif = getCifForSelector (undefined :: ID () -> IO (ID ()))
+retainCif = getCifForSelector (undefined :: Class () -> ID () -> IO (ID
()))
releaseSelector = getSelectorForName "release"
-releaseCif = getCifForSelector (undefined :: ID () -> IO ())
+releaseCif = getCifForSelector (undefined :: Class () -> ID () -> IO ())
getHaskellDataSelector = getSelectorForName "__getHaskellData__"
getHaskellDataCif = getCifForSelector (undefined :: Class () -> ID () ->
IO (ID ()))
-- actually -> IO (Ptr
()) ...
-setHaskellRetainMethod methodList idx =
- setMethodInList methodList idx retainSelector "@@:" retainCif
haskellObject_retain_IMP
+setHaskellRetainMethod methodList idx super =
+ setMethodInList methodList idx retainSelector "@@:" retainCif
(haskellObject_retain_IMP super)
-setHaskellReleaseMethod methodList idx =
- setMethodInList methodList idx releaseSelector "v@:" releaseCif
haskellObject_release_IMP
+setHaskellReleaseMethod methodList idx super =
+ setMethodInList methodList idx releaseSelector "v@:" releaseCif
(haskellObject_release_IMP super)
setHaskellDataMethod methodList idx super mbDat =
setMethodInList methodList idx getHaskellDataSelector "^v@:#"
getHaskellDataCif (getHaskellData_IMP super mbDat)
Modified: branches/objc2/hoc/HOC_cbits/MemoryManagement.h
==============================================================================
--- branches/objc2/hoc/HOC_cbits/MemoryManagement.h (original)
+++ branches/objc2/hoc/HOC_cbits/MemoryManagement.h Fri Jan 9 16:57:06 2009
@@ -8,6 +8,11 @@
void retainObject(id obj);
void releaseObject(id obj);
+
+void retainSuper(id obj, Class cls);
+void releaseSuper(id obj, Class cls);
+unsigned int retainCount(id obj);
+
void deallocObject(id obj);
void autoreleaseObject(id obj);
Modified: branches/objc2/hoc/HOC_cbits/MemoryManagement.m
==============================================================================
--- branches/objc2/hoc/HOC_cbits/MemoryManagement.m (original)
+++ branches/objc2/hoc/HOC_cbits/MemoryManagement.m Fri Jan 9 16:57:06 2009
@@ -1,3 +1,11 @@
+#ifdef GNUSTEP
+#include <objc/objc-api.h>
+#else
+#include <objc/objc-runtime.h>
+#endif
+
+#include <stdlib.h>
+
#include "MemoryManagement.h"
#define DO_LOG 0
@@ -44,6 +52,7 @@
static SEL selRetain = 0;
static SEL selRelease = 0;
+static SEL selRetainCount = 0;
static SEL selDealloc = 0;
static SEL selAutorelease = 0;
static SEL selAlloc = 0;
@@ -55,7 +64,7 @@
if(!selRetain)
selRetain = getSelectorForName("retain");
#if DO_LOG
- printf("retain %p, %p\n",obj,obj->class_pointer);
+ printf("retain %p, %p\n",obj,obj->isa);
#endif
objc_msgSend(obj,selRetain);
}
@@ -65,9 +74,59 @@
if(!selRelease)
selRelease = getSelectorForName("release");
#if DO_LOG
- printf("release %p, %p\n",obj,obj->class_pointer);
+ printf("release %p, %p\n",obj,obj->isa);
#endif
objc_msgSend(obj,selRelease);
+}
+
+void retainSuper(id obj, Class cls)
+{
+ if(!selRetain)
+ selRetain = getSelectorForName("retain");
+
+#if DO_LOG
+ printf("retain super %p, %p\n",obj,cls);
+#endif
+
+ struct objc_super * super = calloc(1, sizeof(struct objc_super));
+
+ super->receiver = obj;
+ super->super_class = cls;
+
+ objc_msgSendSuper(super, selRetain);
+}
+
+void releaseSuper(id obj, Class cls)
+{
+ if(!selRelease)
+ selRelease = getSelectorForName("release");
+
+#if DO_LOG
+ printf("release super %p, %p\n",obj,cls);
+#endif
+
+ struct objc_super * super = calloc(1, sizeof(struct objc_super));
+
+ super->receiver = obj;
+ super->super_class = cls;
+
+ objc_msgSendSuper(super, selRelease);
+}
+
+unsigned int retainCount(id obj) {
+ unsigned int rc;
+
+#if DO_LOG
+ printf("retainCount %p = ",obj);
+#endif
+ if(!selRetainCount)
+ selRetainCount = getSelectorForName("retainCount");
+
+ rc = (unsigned int) objc_msgSend(obj,selRetainCount);
+#if DO_LOG
+ printf("%d\n",rc);
+#endif
+ return rc;
}
void deallocObject(id obj)
|
|
From: <cod...@go...> - 2008-12-29 17:34:16
|
Author: jam...@us...
Date: Mon Dec 29 09:33:01 2008
New Revision: 379
Modified:
/ (props changed)
trunk/hoc/HOC.cabal
Log:
Placed 'c-sources' line back into cabal file. I thought this had fixed
ghc-6.10 builds, but it turns out the problem was deeper than I thought.
Essentially, this line was fooling Cabal into including
dist/build/HOC_cbits.o in the built library. Under earlier versions of
GHC, the ghc call that the cabal generates to handle this "C source" is
silently ignored because it is calling 'ghc -c' on an object file. With
ghc 6.10.1, the call dies violently with "no input files".
I have dug around a bit in the cabal api, but not yet found any way of
achieving the desired effect, so for now I'm going to have to re-open issue
10 and put the line back.
Modified: trunk/hoc/HOC.cabal
==============================================================================
--- trunk/hoc/HOC.cabal (original)
+++ trunk/hoc/HOC.cabal Mon Dec 29 09:33:01 2008
@@ -57,6 +57,7 @@
hs-source-dirs: HOC
extra-libraries: objc, ffi
+ c-sources: HOC_cbits.o
if os(darwin)
include-dirs: /usr/include/ffi
frameworks: Foundation
|
|
From: <cod...@go...> - 2008-12-29 16:15:52
|
Author: jam...@us...
Date: Mon Dec 29 07:46:35 2008
New Revision: 378
Modified:
/ (props changed)
trunk/hoc/HOC.cabal
trunk/hoc/HOC/HOC/Exception.hs
trunk/hoc/InterfaceGenerator2/Headers.hs
trunk/hoc/InterfaceGenerator2/ParserBase.hs
Log:
Updated to build with ghc 6.10.1 (Issue 10)
Modified: trunk/hoc/HOC.cabal
==============================================================================
--- trunk/hoc/HOC.cabal (original)
+++ trunk/hoc/HOC.cabal Mon Dec 29 07:46:35 2008
@@ -18,7 +18,7 @@
description: build for Objective-C 2.0
Library
- build-depends: base, template-haskell, unix
+ build-depends: base < 4, template-haskell, unix
exposed-modules:
HOC,
@@ -57,7 +57,6 @@
hs-source-dirs: HOC
extra-libraries: objc, ffi
- c-sources: HOC_cbits.o
if os(darwin)
include-dirs: /usr/include/ffi
frameworks: Foundation
Modified: trunk/hoc/HOC/HOC/Exception.hs
==============================================================================
--- trunk/hoc/HOC/HOC/Exception.hs (original)
+++ trunk/hoc/HOC/HOC/Exception.hs Mon Dec 29 07:46:35 2008
@@ -5,7 +5,7 @@
import Foreign
import Foreign.C.String ( CString, withCString )
import Prelude hiding ( catch )
-import Control.Exception ( evaluate, throwIO, throwDyn, catchDyn, catch
)
+import Control.Exception ( Exception, evaluate, throwIO, throwDyn,
catchDyn, catch )
import HOC.Base
import HOC.Arguments
@@ -15,8 +15,8 @@
deriving Typeable
-foreign import ccall unsafe wrapHaskellException :: CString -> StablePtr a
-> IO (Ptr ObjCObject)
-foreign import ccall unsafe unwrapHaskellException :: Ptr ObjCObject -> IO
(StablePtr a)
+foreign import ccall unsafe wrapHaskellException :: CString -> StablePtr
Exception -> IO (Ptr ObjCObject)
+foreign import ccall unsafe unwrapHaskellException :: Ptr ObjCObject -> IO
(StablePtr Exception)
exceptionObjCToHaskell :: Ptr ObjCObject -> IO a
Modified: trunk/hoc/InterfaceGenerator2/Headers.hs
==============================================================================
--- trunk/hoc/InterfaceGenerator2/Headers.hs (original)
+++ trunk/hoc/InterfaceGenerator2/Headers.hs Mon Dec 29 07:46:35 2008
@@ -12,7 +12,7 @@
import Control.Monad(when)
import Data.Char(isAlphaNum, toUpper)
import Data.List(isPrefixOf,isSuffixOf)
-import Data.Maybe(mapMaybe)
+import Data.Maybe(mapMaybe, maybeToList)
import System.Directory(getDirectoryContents, doesDirectoryExist)
import System.Info(os)
import Text.Parsec( runParserT )
@@ -89,9 +89,9 @@
graph :: Gr () ()
graph = mkUGraph [ 0 .. length loaded - 1 ]
[ (to, from) | (_, name, includes, _) <- loaded,
- from <- Map.lookup name
namesToNums,
+ from <- maybeToList $ Map.lookup
name namesToNums,
include <- includes,
- to <- Map.lookup include
namesToNums ]
+ to <- maybeToList $ Map.lookup
include namesToNums ]
sorted = map (numsToHeaders Map.!) $ topsort graph
process ( (headerFileName, moduleName, imports, contents) :
moreHeaders ) env accum
Modified: trunk/hoc/InterfaceGenerator2/ParserBase.hs
==============================================================================
--- trunk/hoc/InterfaceGenerator2/ParserBase.hs (original)
+++ trunk/hoc/InterfaceGenerator2/ParserBase.hs Mon Dec 29 07:46:35 2008
@@ -21,7 +21,13 @@
= fst $ runMessages $ runParserT parser emptyParseEnvironment fileName
text
lookupIntegerConstant :: String -> Parser Integer
-lookupIntegerConstant name = getState >>= Map.lookup name
+lookupIntegerConstant name = getState >>= mapLookup name
+ where
+ -- ghc 6.10's containers package no longer allows arbitrary
+ -- monads in its return types
+ mapLookup k v = case Map.lookup k v of
+ Nothing -> fail "Integer constant not found"
+ Just x -> return x
defineIntegerConstant :: String -> Integer -> Parser ()
defineIntegerConstant name value = modifyState (Map.insert name value)
|
|
From: <cod...@go...> - 2008-12-21 22:06:32
|
Author: wol...@gm...
Date: Sun Dec 21 13:42:00 2008
New Revision: 377
Added:
trunk/hoc/HOC_cbits/Ivars.h (contents, props changed)
trunk/hoc/HOC_cbits/Ivars.m
trunk/hoc/HOC_cbits/Methods.h (contents, props changed)
trunk/hoc/HOC_cbits/Methods.m
Modified:
trunk/hoc/HOC.cabal
trunk/hoc/HOC/HOC.hs
trunk/hoc/HOC/HOC/Base.hs
trunk/hoc/HOC/HOC/Class.hs
trunk/hoc/HOC/HOC/DeclareClass.hs
trunk/hoc/HOC/HOC/ExportClass.hs
trunk/hoc/HOC/HOC/NewClass.hs
trunk/hoc/HOC_cbits/Class.h
trunk/hoc/HOC_cbits/Class.m
trunk/hoc/HOC_cbits/Exceptions.m
trunk/hoc/HOC_cbits/GetNewHaskellData.m
trunk/hoc/HOC_cbits/NewClass.h
trunk/hoc/HOC_cbits/NewClass.m
trunk/hoc/InterfaceGenerator2/Output.hs
trunk/hoc/Setup.hs
trunk/hoc/Tests/TestFoundation.hs
Log:
Merge Objective-C 2.0 branch
Big thanks to James Cook for doing all the work.
Modified: trunk/hoc/HOC.cabal
==============================================================================
--- trunk/hoc/HOC.cabal (original)
+++ trunk/hoc/HOC.cabal Sun Dec 21 13:42:00 2008
@@ -14,6 +14,9 @@
description: build test cases
default: False
+Flag ObjC2
+ description: build for Objective-C 2.0
+
Library
build-depends: base, template-haskell, unix
@@ -54,13 +57,18 @@
hs-source-dirs: HOC
extra-libraries: objc, ffi
+ c-sources: HOC_cbits.o
if os(darwin)
+ include-dirs: /usr/include/ffi
frameworks: Foundation
cpp-options: -DMACOSX
else
-- paths are inserted by Setup.hs
extra-libraries: gnustep-base
cpp-options: -DGNUSTEP
+
+ if flag(ObjC2)
+ cpp-options: -D__OBJC2__=1
Executable hoc-ifgen
Modified: trunk/hoc/HOC/HOC.hs
==============================================================================
--- trunk/hoc/HOC/HOC.hs (original)
+++ trunk/hoc/HOC/HOC.hs Sun Dec 21 13:42:00 2008
@@ -4,6 +4,7 @@
nil,
Object(..),
Class,
+ MetaClass,
ClassAndObject,
ClassObject,
classObject,
Modified: trunk/hoc/HOC/HOC/Base.hs
==============================================================================
--- trunk/hoc/HOC/HOC/Base.hs (original)
+++ trunk/hoc/HOC/HOC/Base.hs Sun Dec 21 13:42:00 2008
@@ -20,6 +20,10 @@
--
+foreign import ccall "stdlib.h &free"
+ freePtr :: FunPtr (Ptr a -> IO ())
+
+--
foreign import ccall "MemoryManagement.h retainObject"
retainObject :: Ptr ObjCObject -> IO ()
Modified: trunk/hoc/HOC/HOC/Class.hs
==============================================================================
--- trunk/hoc/HOC/HOC/Class.hs (original)
+++ trunk/hoc/HOC/HOC/Class.hs Sun Dec 21 13:42:00 2008
@@ -11,15 +11,13 @@
import Foreign
import Foreign.C.String
-
data Class_ a
type Class a = ID (Class_ a)
-
+type MetaClass a = Class (Class_ a)
unsafeGetClassObject :: String -> Class a
-
foreign import ccall unsafe "Class.h getClassByName"
c_getClassByName :: CString -> IO (Ptr ObjCObject)
@@ -30,6 +28,16 @@
getClassByName name >>= importImmortal
+unsafeGetMetaclassForClass :: Class a -> MetaClass a
+
+foreign import ccall unsafe "Class.h getClassForObject"
+ c_getClassForObject :: Ptr ObjCObject -> IO (Ptr ObjCObject)
+
+getClassForObject obj = withExportedArgument obj c_getClassForObject
+
+{-# NOINLINE unsafeGetMetaclassForClass #-}
+unsafeGetMetaclassForClass obj = unsafePerformIO $
+ getClassForObject obj >>= importImmortal
class (Object a, Object b) => ClassAndObject a b | a -> b, b -> a
Modified: trunk/hoc/HOC/HOC/DeclareClass.hs
==============================================================================
--- trunk/hoc/HOC/HOC/DeclareClass.hs (original)
+++ trunk/hoc/HOC/HOC/DeclareClass.hs Sun Dec 21 13:42:00 2008
@@ -31,6 +31,12 @@
`appT` (conT (mkName phantomName)
`appT` varT (mkName "a"))),
+ -- type $(metaMetaClassName) a = $(superMetaMetaClassName)
($(phantomName) a)
+ tySynD (mkName metaMetaClassName) [mkName "a"]
+ (conT (mkName superMetaMetaClassName)
+ `appT` (conT (mkName phantomName)
+ `appT` varT (mkName "a"))),
+
-- $(classObjectName) :: $(metaClassName) ()
sigD (mkName classObjectName) (conT (mkName metaClassName)
`appT` [t| () |]),
@@ -39,6 +45,11 @@
valD (return $ VarP (mkName classObjectName))
(normalB [| unsafeGetClassObject $(stringE name) |]) [],
+ -- $(metaClassObjectName) = unsafeGetMetaclassForClass
$(classObjectName)
+ valD (return $ VarP (mkName metaClassObjectName))
+ (normalB [| unsafeGetMetaclassForClass $(varE (mkName
classObjectName)) |]) [],
+
+ -- $(superName) :: String
sigD (mkName superName) [t| String |],
-- $(superName) = "super"
@@ -47,20 +58,35 @@
-- instance SuperClass (name ()) (super ())
instanceD (cxt []) (conT ''SuperClass `appT` clsType `appT`
superType) [],
+ -- instance SuperClass (clsName ()) (superClsName ())
+ instanceD (cxt []) (conT ''SuperClass `appT` metaClsType `appT`
superMetaType) [],
+
-- instance ClassObject (metaClsName ())
-- where classObject = classObject
instanceD (cxt []) (conT ''ClassObject `appT` metaClsType)
- [funD 'classObject [clause [] (normalB $ varE (mkName
classObjectName)) []]]
+ [funD 'classObject [clause [] (normalB $ varE (mkName
classObjectName)) []]],
+
+ -- instance ClassObject metaMetaCls
+ -- where classObject = unsafeGetMetaclassForClass classObject
+ -- {- metaclass object, to support super calls in class methods -}
+ instanceD (cxt []) (conT ''ClassObject `appT` metaMetaClsType)
+ [funD 'classObject [clause [] (normalB $ varE (mkName
metaClassObjectName)) []]]
]
where
phantomName = name ++ "_"
metaClassName = name ++ "Class"
+ metaMetaClassName = name ++ "MetaClass"
metaPhantomName = metaClassName ++ "_"
superMetaClassName | super == "ID" = "Class"
| otherwise = super ++ "Class"
+ superMetaMetaClassName | super == "ID" = "MetaClass"
+ | otherwise = super ++ "MetaClass"
classObjectName = "_" ++ name
+ metaClassObjectName = "_" ++ metaClassName
superName = "super_" ++ name
+ metaMetaClsType = conT (mkName metaMetaClassName) `appT` [t| () |]
metaClsType = conT (mkName metaClassName) `appT` [t| () |]
clsType = conT (mkName name) `appT` [t| () |]
superType = conT (mkName super) `appT` [t| () |]
+ superMetaType = conT (mkName superMetaClassName) `appT` [t| () |]
Modified: trunk/hoc/HOC/HOC/ExportClass.hs
==============================================================================
--- trunk/hoc/HOC/HOC/ExportClass.hs (original)
+++ trunk/hoc/HOC/HOC/ExportClass.hs Sun Dec 21 13:42:00 2008
@@ -138,7 +138,7 @@
$(fillMethodList False 3 [|imethods|] instanceMethods)
$(fillMethodList True 0 [|cmethods|] classMethods)
clsname <- newCString name
- newClass super clsname defaultIvarSize ivars imethods
cmethods
+ newClass super clsname ivars imethods cmethods
|]
where
typedInitIvars = [|initializeInstanceVariables|]
Modified: trunk/hoc/HOC/HOC/NewClass.hs
==============================================================================
--- trunk/hoc/HOC/HOC/NewClass.hs (original)
+++ trunk/hoc/HOC/HOC/NewClass.hs Sun Dec 21 13:42:00 2008
@@ -9,7 +9,6 @@
setIvarInList,
setMethodInList,
makeDefaultIvarList,
- defaultIvarSize,
setHaskellRetainMethod,
setHaskellReleaseMethod,
setHaskellDataMethod
@@ -22,49 +21,79 @@
import HOC.Class
import Foreign.C.String
+import Foreign.C.Types
import Foreign
type IMP = FFICif -> Ptr () -> Ptr (Ptr ()) -> IO (Ptr ObjCObject)
foreign import ccall "wrapper" wrapIMP :: IMP -> IO (FunPtr IMP)
-newtype MethodList = MethodList (Ptr MethodList)
-newtype IvarList = IvarList (Ptr IvarList)
+newtype MethodList = MethodList (ForeignPtr MethodList)
+newtype IvarList = IvarList (ForeignPtr IvarList)
foreign import ccall "NewClass.h newClass"
- newClass :: Ptr ObjCObject -> CString
- -> Int -> IvarList
+ rawNewClass :: Ptr ObjCObject -> CString
+ -> Ptr IvarList
+ -> Ptr MethodList -> Ptr MethodList
+ -> IO ()
+
+newClass :: Ptr ObjCObject -> CString
+ -> IvarList
-> MethodList -> MethodList
-> IO ()
+newClass sc name (IvarList ivars) (MethodList ms) (MethodList cms) =
+ withForeignPtr ivars $ \ivars ->
+ withForeignPtr ms $ \ms ->
+ withForeignPtr cms $ \cms -> do
+ rawNewClass sc name ivars ms cms
foreign import ccall "NewClass.h makeMethodList"
- makeMethodList :: Int -> IO MethodList
+ rawMakeMethodList :: Int -> IO (Ptr MethodList)
foreign import ccall "NewClass.h setMethodInList"
- rawSetMethodInList :: MethodList -> Int
+ rawSetMethodInList :: Ptr MethodList -> Int
-> SEL -> CString
-> FFICif -> FunPtr IMP
-> IO ()
foreign import ccall "NewClass.h makeIvarList"
- makeIvarList :: Int -> IO IvarList
+ rawMakeIvarList :: Int -> IO (Ptr IvarList)
foreign import ccall "NewClass.h setIvarInList"
- setIvarInList :: IvarList -> Int
- -> CString -> CString -> Int -> IO ()
+ rawSetIvarInList :: Ptr IvarList -> Int
+ -> CString -> CString -> CSize -> Word8 -> IO ()
-setMethodInList methodList idx sel typ cif imp = do
- typC <- newCString typ
- thunk <- wrapIMP imp
- rawSetMethodInList methodList idx sel typC cif thunk
+makeIvarList :: Int -> IO IvarList
+makeIvarList n = do
+ ivars <- rawMakeIvarList n
+ ivars <- newForeignPtr freePtr ivars
+ return (IvarList ivars)
+
+setIvarInList:: IvarList -> Int
+ -> CString -> CString -> CSize -> Word8 -> IO ()
+setIvarInList (IvarList ivars) n name ty sz align =
+ withForeignPtr ivars $ \ivars -> do
+ rawSetIvarInList ivars n name ty sz align
+
+makeMethodList :: Int -> IO MethodList
+makeMethodList n = do
+ methods <- rawMakeMethodList n
+ methods <- newForeignPtr freePtr methods
+ return (MethodList methods)
+
+setMethodInList (MethodList methodList) idx sel typ cif imp =
+ withForeignPtr methodList $ \methodList -> do
+ typC <- newCString typ
+ thunk <- wrapIMP imp
+ rawSetMethodInList methodList idx sel typC cif thunk
makeDefaultIvarList = do
list <- makeIvarList 1
name <- newCString "__retained_haskell_part__"
typ <- newCString "^v"
- setIvarInList list 0 name typ 0
+ setIvarInList list 0 name typ
+ (fromIntegral $ sizeOf nullPtr)
+ (fromIntegral $ alignment nullPtr)
return list
-defaultIvarSize = 4 :: Int
-
retainSelector = getSelectorForName "retain"
retainCif = getCifForSelector (undefined :: ID () -> IO (ID ()))
@@ -75,33 +104,11 @@
getHaskellDataCif = getCifForSelector (undefined :: Class () -> ID () ->
IO (ID ()))
-- actually -> IO (Ptr
()) ...
-setHaskellRetainMethod methodList idx = do
- typC <- newCString "@@:"
- thunk <- wrapIMP haskellObject_retain_IMP
- rawSetMethodInList methodList
- idx
- retainSelector
- typC
- retainCif
- thunk
+setHaskellRetainMethod methodList idx =
+ setMethodInList methodList idx retainSelector "@@:" retainCif
haskellObject_retain_IMP
-setHaskellReleaseMethod methodList idx = do
- typC <- newCString "v@:"
- thunk <- wrapIMP haskellObject_release_IMP
- rawSetMethodInList methodList
- idx
- releaseSelector
- typC
- releaseCif
- thunk
-
-setHaskellDataMethod methodList idx super mbDat = do
- typC <- newCString "^v@:#"
- thunk <- wrapIMP (getHaskellData_IMP super mbDat)
- rawSetMethodInList methodList
- idx
- getHaskellDataSelector
- typC
- getHaskellDataCif
- thunk
+setHaskellReleaseMethod methodList idx =
+ setMethodInList methodList idx releaseSelector "v@:" releaseCif
haskellObject_release_IMP
+setHaskellDataMethod methodList idx super mbDat =
+ setMethodInList methodList idx getHaskellDataSelector "^v@:#"
getHaskellDataCif (getHaskellData_IMP super mbDat)
Modified: trunk/hoc/HOC_cbits/Class.h
==============================================================================
--- trunk/hoc/HOC_cbits/Class.h (original)
+++ trunk/hoc/HOC_cbits/Class.h Sun Dec 21 13:42:00 2008
@@ -1,3 +1,9 @@
#include <objc/objc.h>
id getClassByName(const char* name);
+
+Class getSuperclassForClass(Class class);
+Class getRootClassForClass(Class super_class);
+
+Class getClassForObject(id self);
+Class getSuperClassForObject(id self);
\ No newline at end of file
Modified: trunk/hoc/HOC_cbits/Class.m
==============================================================================
--- trunk/hoc/HOC_cbits/Class.m (original)
+++ trunk/hoc/HOC_cbits/Class.m Sun Dec 21 13:42:00 2008
@@ -13,3 +13,50 @@
return objc_getClass(name);
#endif
}
+
+Class getSuperclassForClass(Class class)
+{
+#ifdef GNUSTEP
+ if(CLS_ISRESOLV(class))
+ return class->super_class;
+ else
+ return getClassByName((const char*) class->super_class);
+
+#elif defined(__OBJC2__)
+ return class_getSuperclass(class);
+#else
+ return class->super_class;
+#endif
+}
+
+Class getRootClassForClass(Class super_class)
+{
+ Class root_class;
+
+ for(root_class = super_class;
+ getSuperclassForClass(root_class) != nil;
+ root_class = getSuperclassForClass(root_class))
+ ;
+
+ return root_class;
+}
+
+Class getClassForObject(id object)
+{
+#ifdef __OBJC2__
+ return object_getClass(object);
+#else
+ return object->isa;
+#endif
+}
+
+Class getSuperClassForObject(id self)
+{
+#ifdef GNUSTEP
+ return self->class_pointer->super_class;
+#elif defined(__OBJC2__)
+ return class_getSuperclass(object_getClass(self));
+#else
+ return self->isa->super_class;
+#endif
+}
\ No newline at end of file
Modified: trunk/hoc/HOC_cbits/Exceptions.m
==============================================================================
--- trunk/hoc/HOC_cbits/Exceptions.m (original)
+++ trunk/hoc/HOC_cbits/Exceptions.m Sun Dec 21 13:42:00 2008
@@ -1,10 +1,15 @@
#include <objc/objc.h>
#include "NewClass.h"
#include "Class.h"
+#include "Ivars.h"
+#include "Methods.h"
#include "Selector.h"
#include "Marshalling.h"
#include "HsFFI.h"
+#define hsExceptionClassName "HOCHaskellException"
+#define hsExceptionIvarName "_haskellException"
+
static BOOL excWrapperInited = NO;
static int stablePtrOffset;
static id clsHOCHaskellException;
@@ -21,12 +26,18 @@
#if GNUSTEP
super.self = self;
- super.class = self->class_pointer->super_class;
+ super.class = getSuperClassForObject(self);
(*objc_msg_lookup_super(&super, selDealloc))(self, selDealloc);
#else
super.receiver = self;
- super.class = self->isa->super_class;
+
+# ifdef __OBJC2__
+ super.super_class = getSuperClassForObject(self);
+# else
+ super.class = getSuperClassForObject(self);
+# endif
+
objc_msgSendSuper(&super, selDealloc);
#endif
}
@@ -35,30 +46,29 @@
{
if(!excWrapperInited)
{
- struct objc_method_list *methods = makeMethodList(1);
- struct objc_method_list *class_methods = makeMethodList(0);
- struct objc_ivar_list *ivars = makeIvarList(1);
+ struct hoc_method_list *methods = makeMethodList(1);
+ struct hoc_method_list *class_methods = makeMethodList(0);
+ struct hoc_ivar_list *ivars = makeIvarList(1);
+ struct objc_ivar *stablePtrIvar;
selDealloc = getSelectorForName("dealloc");
-#ifdef GNUSTEP
- methods->method_list[0].method_name = (SEL)"dealloc";
-#else
- methods->method_list[0].method_name = selDealloc;
-#endif
- methods->method_list[0].method_types = "v@:";
- methods->method_list[0].method_imp = (IMP) &exc_dealloc;
+ setMethodInListWithIMP(methods, 0, selDealloc, "v@:", (IMP)
&exc_dealloc);
- setIvarInList(ivars, 0, "_haskellExecption", "^v", 0);
+ setIvarInList(ivars, 0, hsExceptionIvarName, "^v", sizeof(void *),
IVAR_PTR_ALIGN);
newClass(getClassByName("NSException"),
- "HOCHaskellException",
- sizeof(void*),
+ hsExceptionClassName,
ivars, methods, class_methods);
clsHOCHaskellException = getClassByName("HOCHaskellException");
- stablePtrOffset = ivars->ivar_list[0].ivar_offset;
+ stablePtrIvar = class_getInstanceVariable(clsHOCHaskellException,
hsExceptionIvarName);
+#ifdef __OBJC2__
+ stablePtrOffset = ivar_getOffset(stablePtrIvar);
+#else
+ stablePtrOffset = stablePtrIvar->ivar_offset;
+#endif
selExceptionWithNameReasonUserInfo =
getSelectorForName("exceptionWithName:reason:userInfo:");
Modified: trunk/hoc/HOC_cbits/GetNewHaskellData.m
==============================================================================
--- trunk/hoc/HOC_cbits/GetNewHaskellData.m (original)
+++ trunk/hoc/HOC_cbits/GetNewHaskellData.m Sun Dec 21 13:42:00 2008
@@ -47,7 +47,13 @@
#endif
if(m)
+ {
+#ifdef __OBJC2__
+ imp = method_getImplementation(m);
+#else
imp = m->method_imp;
+#endif
+ }
if(imp)
return (*(getHaskellDataIMP)imp)(obj, selGetHaskellData);
Added: trunk/hoc/HOC_cbits/Ivars.h
==============================================================================
--- (empty file)
+++ trunk/hoc/HOC_cbits/Ivars.h Sun Dec 21 13:42:00 2008
@@ -0,0 +1,39 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+struct hoc_ivar {
+ char *ivar_name;
+ char *ivar_types;
+ size_t ivar_size;
+ uint8_t ivar_alignment;
+};
+
+#define IVAR_PTR_ALIGN ((uint8_t) sizeof(void *))
+
+struct hoc_ivar_list {
+ int ivar_count;
+
+ /* variable length structure */
+ struct hoc_ivar ivar_list[1];
+};
+
+struct hoc_ivar_list * makeIvarList(int n);
+
+void setIvarInList(
+ struct hoc_ivar_list *list,
+ int i,
+ char *name, /* never deallocate this */
+ char *types, /* never deallocate this */
+ size_t size,
+ uint8_t alignment
+ );
+
+#ifndef __OBJC2__
+
+struct objc_ivar_list * buildIndexedIvarList(
+ struct hoc_ivar_list *list,
+ int start_offset,
+ int *instance_size /* out */
+ );
+
+#endif
\ No newline at end of file
Added: trunk/hoc/HOC_cbits/Ivars.m
==============================================================================
--- (empty file)
+++ trunk/hoc/HOC_cbits/Ivars.m Sun Dec 21 13:42:00 2008
@@ -0,0 +1,92 @@
+#ifdef GNUSTEP
+#include <objc/objc-api.h>
+#else
+#include <objc/objc-runtime.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "Ivars.h"
+
+struct hoc_ivar_list * makeIvarList(int n)
+{
+ struct hoc_ivar_list *list =
+ calloc(1, sizeof(struct hoc_ivar_list)
+ + (n-1) * sizeof(struct hoc_ivar));
+ list->ivar_count = n;
+ return list;
+}
+
+void setIvarInList(
+ struct hoc_ivar_list *list,
+ int i,
+ char *name,
+ char *types,
+ size_t size,
+ uint8_t alignment
+ )
+{
+ list->ivar_list[i].ivar_name = name;
+ list->ivar_list[i].ivar_types = types;
+ list->ivar_list[i].ivar_size = size;
+ list->ivar_list[i].ivar_alignment = alignment;
+}
+
+#ifndef __OBJC2__
+
+/* Used to be makeIvarList in NewClass.m */
+static struct objc_ivar_list * makeIndexedIvarList(int n)
+{
+ struct objc_ivar_list *list =
+ calloc(1, sizeof(struct objc_ivar_list)
+ + (n-1) * sizeof(struct objc_ivar));
+ list->ivar_count = n;
+ return list;
+}
+
+/* Used to be setIvarInList in NewClass.m */
+static void setIvarInIndexedList(
+ struct objc_ivar_list *list,
+ int i,
+ char *name,
+ char *type,
+ int offset
+ )
+{
+ list->ivar_list[i].ivar_name = name;
+ list->ivar_list[i].ivar_type = type;
+ list->ivar_list[i].ivar_offset = offset;
+}
+
+struct objc_ivar_list * buildIndexedIvarList(
+ struct hoc_ivar_list *list,
+ int start_offset,
+ int *instance_size /* out */
+ )
+{
+ struct objc_ivar_list * outList =
makeIndexedIvarList(list->ivar_count);
+ int offset = start_offset;
+ int i;
+
+ for (i = 0; i < list->ivar_count; i++)
+ {
+ struct hoc_ivar *ivar = &list->ivar_list[i];
+
+ int align = ivar->ivar_alignment;
+ int alignmask = align - 1;
+
+ assert((align & alignmask) == 0);
+ if ((offset & alignmask) != 0)
+ offset = (offset & ~alignmask) + align;
+
+ setIvarInIndexedList(outList, i, ivar->ivar_name,
ivar->ivar_types, offset);
+
+ offset += ivar->ivar_size;
+ }
+
+ *instance_size = offset - start_offset;
+ return outList;
+}
+
+#endif // ifndef __OBJC2__
\ No newline at end of file
Added: trunk/hoc/HOC_cbits/Methods.h
==============================================================================
--- (empty file)
+++ trunk/hoc/HOC_cbits/Methods.h Sun Dec 21 13:42:00 2008
@@ -0,0 +1,57 @@
+#ifdef GNUSTEP
+#include <objc/objc-api.h>
+#else
+#include <objc/objc-runtime.h>
+#endif
+
+#include <ffi.h>
+
+#ifdef __OBJC__
+@class NSException;
+#else
+typedef void NSException;
+#endif
+
+typedef NSException *(*haskellIMP)(
+ ffi_cif *cif,
+ void * ret,
+ void **args
+ );
+
+struct hoc_method {
+ SEL method_name;
+ char *method_types;
+ IMP method_imp;
+};
+
+struct hoc_method_list {
+ int method_count;
+
+ /* variable length structure */
+ struct hoc_method method_list[1];
+};
+
+struct hoc_method_list * makeMethodList(int n);
+
+void setMethodInListWithIMP(
+ struct hoc_method_list *list,
+ int i,
+ SEL sel,
+ char *types, /* never deallocate this */
+ IMP imp /* never deallocate this */
+ );
+
+void setMethodInList(
+ struct hoc_method_list *list,
+ int i,
+ SEL sel,
+ char *types, /* never deallocate this */
+ ffi_cif *cif, /* never deallocate this */
+ haskellIMP imp
+ );
+
+#ifndef __OBJC2__
+
+struct objc_method_list * convertMethodList(struct hoc_method_list * list);
+
+#endif
\ No newline at end of file
Added: trunk/hoc/HOC_cbits/Methods.m
==============================================================================
--- (empty file)
+++ trunk/hoc/HOC_cbits/Methods.m Sun Dec 21 13:42:00 2008
@@ -0,0 +1,104 @@
+#include <stdlib.h>
+#include "Methods.h"
+#include "Statistics.h"
+
+#ifdef __OBJC__
+#import <Foundation/NSException.h>
+#endif
+
+static void objcIMP(ffi_cif *cif, void * ret, void **args, void *userData)
+{
+ recordHOCEvent(kHOCAboutToEnterHaskell, args);
+ NSException *e = (*(haskellIMP)userData)(cif, ret, args);
+ recordHOCEvent(kHOCLeftHaskell, args);
+ if(e != nil)
+ [e raise];
+}
+
+static ffi_closure *newIMP(ffi_cif *cif, haskellIMP imp)
+{
+ ffi_closure *closure = (ffi_closure*) calloc(1, sizeof(ffi_closure));
+ ffi_prep_closure(closure, cif, &objcIMP, (void*) imp);
+ return closure;
+}
+
+struct hoc_method_list * makeMethodList(int n)
+{
+ struct hoc_method_list *list =
+ calloc(1, sizeof(struct hoc_method_list)
+ + (n-1) * sizeof(struct hoc_method));
+ list->method_count = n;
+ return list;
+}
+
+void setMethodInList(
+ struct hoc_method_list *list,
+ int i,
+ SEL sel,
+ char *types,
+ ffi_cif *cif,
+ haskellIMP imp
+ )
+{
+ setMethodInListWithIMP(list, i, sel, types, (IMP) newIMP(cif, imp) );
+}
+
+void setMethodInListWithIMP(
+ struct hoc_method_list *list,
+ int i,
+ SEL sel,
+ char *types,
+ IMP imp
+ )
+{
+ list->method_list[i].method_name = sel;
+ list->method_list[i].method_types = types;
+ list->method_list[i].method_imp = imp;
+}
+
+#ifndef __OBJC2__
+
+/* Was previously makeMethodList */
+static struct objc_method_list * makeObjcMethodList(int n)
+{
+ struct objc_method_list *list =
+ calloc(1, sizeof(struct objc_method_list)
+ + (n-1) * sizeof(struct objc_method));
+ list->method_count = n;
+ return list;
+}
+
+/* Was previously setMethodInList */
+static void setObjCMethodInList(
+ struct objc_method_list *list,
+ int i,
+ SEL sel,
+ char *types,
+ IMP imp
+ )
+{
+#ifdef GNUSTEP
+ list->method_list[i].method_name = (SEL) sel_get_name(sel);
+#else
+ list->method_list[i].method_name = sel;
+#endif
+ list->method_list[i].method_types = types;
+ list->method_list[i].method_imp = imp;
+}
+
+struct objc_method_list *
+convertMethodList(struct hoc_method_list * list) {
+ struct objc_method_list * newList =
makeObjcMethodList(list->method_count);
+ int i;
+
+ for(i = 0; i < list->method_count; i++)
+ {
+ struct hoc_method * method = &list->method_list[i];
+
+ setObjCMethodInList(newList, i, method->method_name,
method->method_types, method->method_imp);
+ }
+
+ return newList;
+}
+
+#endif // ifndef __OBJC2__
\ No newline at end of file
Modified: trunk/hoc/HOC_cbits/NewClass.h
==============================================================================
--- trunk/hoc/HOC_cbits/NewClass.h (original)
+++ trunk/hoc/HOC_cbits/NewClass.h Sun Dec 21 13:42:00 2008
@@ -4,42 +4,12 @@
#include <objc/objc-runtime.h>
#endif
-#include <ffi.h>
+struct hoc_ivar_list;
+struct hoc_method_list;
-#ifdef __OBJC__
-@class NSException;
-#else
-typedef void NSException;
-#endif
-
-void newClass(struct objc_class * super_class,
+void newClass(Class super_class,
const char * name, /* never
deallocate this */
- int instance_size,
- struct objc_ivar_list *ivars, /* never deallocate this */
- struct objc_method_list *methods, /* never deallocate this */
- struct objc_method_list *class_methods); /* never deallocate this */
+ struct hoc_ivar_list *ivars,
+ struct hoc_method_list *methods,
+ struct hoc_method_list *class_methods);
-typedef NSException *(*haskellIMP)(
- ffi_cif *cif,
- void * ret,
- void **args
- );
-
-struct objc_method_list * makeMethodList(int n);
-void setMethodInList(
- struct objc_method_list *list,
- int i,
- SEL sel,
- char *types, /* never deallocate this */
- ffi_cif *cif, /* never deallocate this */
- haskellIMP imp
- );
-
-struct objc_ivar_list * makeIvarList(int n);
-void setIvarInList(
- struct objc_ivar_list *list,
- int i,
- char *name, /* never deallocate this */
- char *type, /* never deallocate this */
- int offset
- );
Modified: trunk/hoc/HOC_cbits/NewClass.m
==============================================================================
--- trunk/hoc/HOC_cbits/NewClass.m (original)
+++ trunk/hoc/HOC_cbits/NewClass.m Sun Dec 21 13:42:00 2008
@@ -2,8 +2,9 @@
#include <Foundation/NSException.h>
#include <assert.h>
#include "Class.h"
+#include "Ivars.h"
+#include "Methods.h"
#include "NewClass.h"
-#include "Statistics.h"
#ifdef GNUSTEP
#define isa class_pointer
@@ -11,157 +12,133 @@
#define CLS_META _CLS_META
#endif
-static struct objc_class * getSuper(struct objc_class *class)
-{
-#ifdef GNUSTEP
- if(CLS_ISRESOLV(class))
- return class->super_class;
- else
- return getClassByName((const char*) class->super_class);
-
+static Class allocateClassPair(Class super_class, const char * name) {
+#ifdef __OBJC2__
+ return objc_allocateClassPair(super_class, name, 0);
#else
- return class->super_class;
+ Class new_class = calloc( 2, sizeof(struct objc_class) );
+ Class meta_class = &new_class[1];
+ Class root_class = getRootClassForClass(super_class);
+
+ new_class->isa = meta_class;
+ new_class->info = CLS_CLASS;
+ meta_class->info = CLS_META;
+
+ new_class->name = name;
+ meta_class->name = name;
+
+# ifdef GNUSTEP
+ new_class->super_class = (void*)(super_class->name);
+ meta_class->super_class = (void*)(super_class->isa->name);
+# else
+ new_class->super_class = super_class;
+ meta_class->super_class = super_class->isa;
+ meta_class->isa = (void *)root_class->isa;
+# endif
+
+ return new_class;
#endif
}
-void newClass(struct objc_class * super_class,
- const char * name,
- int instance_size,
- struct objc_ivar_list *ivars,
- struct objc_method_list *methods,
- struct objc_method_list *class_methods)
-{
- struct objc_class * meta_class;
- struct objc_class * new_class;
- struct objc_class * root_class;
- int i;
-
- assert(objc_lookUpClass(name) == nil);
-
- for(root_class = super_class;
- root_class->super_class != nil;
- root_class = getSuper(root_class))
- ;
-
- new_class = calloc( 2, sizeof(struct objc_class) );
- meta_class = &new_class[1];
-
- new_class->isa = meta_class;
- new_class->info = CLS_CLASS;
- meta_class->info = CLS_META;
-
- new_class->name = name;
- meta_class->name = name;
-
- new_class->instance_size = super_class->instance_size + instance_size;
- for(i=0; i<ivars->ivar_count; i++)
- ivars->ivar_list[i].ivar_offset += super_class->instance_size;
-
- new_class->ivars = ivars;
-
+static void registerClassPair(Class new_class) {
#ifdef GNUSTEP
- new_class->super_class = (void*)(super_class->name);
- meta_class->super_class = (void*)(super_class->isa->name);
-
- {
- Module_t module = calloc(1, sizeof(Module));
- Symtab_t symtab = calloc(1, sizeof(Symtab) + sizeof(void*) /* two
defs pointers */);
- extern void __objc_exec_class (Module_t module);
- extern void __objc_resolve_class_links ();
-
- module->version = 8;
- module->size = sizeof(Module);
- module->name = strdup(name);
- module->symtab = symtab;
- symtab->cls_def_cnt = 1;
- symtab->defs[0] = new_class;
- symtab->defs[1] = NULL;
-
- __objc_exec_class (module);
- __objc_resolve_class_links();
- }
+ Module_t module = calloc(1, sizeof(Module));
+ Symtab_t symtab = calloc(1, sizeof(Symtab) + sizeof(void*) /* two defs
pointers */);
+ extern void __objc_exec_class (Module_t module);
+ extern void __objc_resolve_class_links ();
+
+ module->version = 8;
+ module->size = sizeof(Module);
+ module->name = strdup(name);
+ module->symtab = symtab;
+ symtab->cls_def_cnt = 1;
+ symtab->defs[0] = new_class;
+ symtab->defs[1] = NULL;
- class_add_method_list(new_class, methods);
- class_add_method_list(meta_class, class_methods);
+ __objc_exec_class (module);
+ __objc_resolve_class_links();
+#elif defined(__OBJC2__)
+ objc_registerClassPair(new_class);
#else
- new_class->methodLists = calloc( 1, sizeof(struct objc_method_list *) );
- meta_class->methodLists = calloc( 1, sizeof(struct objc_method_list *) );
- new_class->methodLists[0] = (struct objc_method_list*) -1;
- meta_class->methodLists[0] = (struct objc_method_list*) -1;
-
- new_class->super_class = super_class;
- meta_class->super_class = super_class->isa;
- meta_class->isa = (void *)root_class->isa;
-
- objc_addClass( new_class );
-
- class_addMethods(new_class, methods);
- class_addMethods(meta_class, class_methods);
+ objc_addClass( new_class );
#endif
}
-
-static void objcIMP(ffi_cif *cif, void * ret, void **args, void *userData)
-{
- recordHOCEvent(kHOCAboutToEnterHaskell, args);
- NSException *e = (*(haskellIMP)userData)(cif, ret, args);
- recordHOCEvent(kHOCLeftHaskell, args);
- if(e != nil)
- [e raise];
-}
-
-static ffi_closure *newIMP(ffi_cif *cif, haskellIMP imp)
+static void addIvarsToClass(Class new_class, struct hoc_ivar_list *ivars)
{
- ffi_closure *closure = (ffi_closure*) calloc(1, sizeof(ffi_closure));
- ffi_prep_closure(closure, cif, &objcIMP, (void*) imp);
- return closure;
-}
-
-struct objc_method_list * makeMethodList(int n)
-{
- struct objc_method_list *list =
- calloc(1, sizeof(struct objc_method_list)
- + (n-1) * sizeof(struct objc_method));
- list->method_count = n;
- return list;
+#ifdef __OBJC2__
+ int i;
+
+ for (i = 0; i < ivars->ivar_count; i++)
+ {
+ struct hoc_ivar *ivar = &ivars->ivar_list[i];
+ class_addIvar(new_class, ivar->ivar_name,
+ ivar->ivar_size, ivar->ivar_alignment, ivar->ivar_types);
+ }
+#else
+ Class super_class = getSuperclassForClass(new_class);
+
+ int instance_size;
+ new_class->ivars = buildIndexedIvarList(
+ ivars,
+ super_class->instance_size,
+ &instance_size);
+
+ new_class->instance_size = super_class->instance_size + instance_size;
+#endif
}
-void setMethodInList(
- struct objc_method_list *list,
- int i,
- SEL sel,
- char *types,
- ffi_cif *cif,
- haskellIMP imp
- )
+static void addMethodsToClass(Class new_class, struct hoc_method_list
*methods)
{
#ifdef GNUSTEP
- list->method_list[i].method_name = (SEL) sel_get_name(sel);
+ class_add_method_list(new_class, convertMethodList(methods));
+#elif defined(__OBJC2__)
+ int i;
+ for (i = 0; i < methods->method_count; i++)
+ {
+ struct hoc_method * m = &methods->method_list[i];
+ class_addMethod(new_class, m->method_name, m->method_imp,
m->method_types);
+ }
#else
- list->method_list[i].method_name = sel;
+ new_class->methodLists = calloc( 1, sizeof(struct objc_method_list *)
);
+ new_class->methodLists[0] = (struct objc_method_list*) -1;
+
+ class_addMethods(new_class, convertMethodList(methods));
#endif
- list->method_list[i].method_types = types;
- list->method_list[i].method_imp = (IMP) newIMP(cif, imp);
}
-struct objc_ivar_list * makeIvarList(int n)
+void newClass(Class super_class,
+ const char * name,
+ struct hoc_ivar_list *ivars,
+ struct hoc_method_list *methods,
+ struct hoc_method_list *class_methods)
{
- struct objc_ivar_list *list =
- calloc(1, sizeof(struct objc_ivar_list)
- + (n-1) * sizeof(struct objc_ivar));
- list->ivar_count = n;
- return list;
-}
+ Class meta_class;
+ Class new_class;
+
+ assert(objc_lookUpClass(name) == nil);
+
+ /* Allocate the class and metaclass */
+ new_class = allocateClassPair(super_class, name);
+ meta_class = getClassForObject(new_class);
+
+ /* Add instance variables to the class */
+ addIvarsToClass(new_class, ivars);
+
+ /* Add methods and class methods */
+ /* I don't know whether order actually matters here in the non-objc2
cases,
+ so I'm leaving it as it was. */
+#ifdef __OBJC2__
+ addMethodsToClass(new_class, methods);
+ addMethodsToClass(meta_class, class_methods);
+
+ registerClassPair(new_class);
+#else
+ registerClassPair(new_class);
+
+ addMethodsToClass(new_class, methods);
+ addMethodsToClass(meta_class, class_methods);
+#endif
-void setIvarInList(
- struct objc_ivar_list *list,
- int i,
- char *name,
- char *type,
- int offset
- )
-{
- list->ivar_list[i].ivar_name = name;
- list->ivar_list[i].ivar_type = type;
- list->ivar_list[i].ivar_offset = offset;
}
+
Modified: trunk/hoc/InterfaceGenerator2/Output.hs
==============================================================================
--- trunk/hoc/InterfaceGenerator2/Output.hs (original)
+++ trunk/hoc/InterfaceGenerator2/Output.hs Sun Dec 21 13:42:00 2008
@@ -25,6 +25,7 @@
ClassEntity _ ->
[eHaskellName e, '_' `BS.cons` eHaskellName e,
eHaskellName e `BS.append` BS.pack "Class",
+ eHaskellName e `BS.append` BS.pack "MetaClass",
BS.pack "super_" `BS.append` eHaskellName e,
eHaskellName e `BS.snoc` '_' ]
EnumEntity complete values ->
@@ -56,11 +57,13 @@
LocalModule m
-> text "import {-# SOURCE #-}" <+> textBS m
<+> parens (textBS (eHaskellName e) <> comma
- <+> textBS (eHaskellName e) <> text "Class")
+ <+> textBS (eHaskellName e) <> text "Class" <>
comma
+ <+> textBS (eHaskellName e) <>
text "MetaClass")
FrameworkModule f m
-> text "import" <+> textBS m
<+> parens (textBS (eHaskellName e) <> comma
- <+> textBS (eHaskellName e) <> text "Class")
+ <+> textBS (eHaskellName e) <> text "Class" <>
comma
+ <+> textBS (eHaskellName e) <>
text "MetaClass")
pprHsBoot entityPile modName entities
= text "module" <+> textBS modName <+> text "where" $+$
@@ -78,6 +81,9 @@
<+> parens (textBS name <> char '_' <+> char 'a')
$+$
text "type" <+> textBS name <> text "Class" <+>
char 'a' <+> equals
<+> text (maybe "Class" ( (++ "Class") .
BS.unpack . eHaskellName ) mbSuper)
+ <+> parens (textBS name <> char '_' <+> char 'a')
$+$
+ text "type" <+> textBS name <> text "MetaClass" <+>
char 'a' <+> equals
+ <+> text (maybe "MetaClass" ( (++ "MetaClass") .
BS.unpack . eHaskellName ) mbSuper)
<+> parens (textBS name <> char '_' <+> char 'a')
| (name, mbSuper) <- classes0 ]
Modified: trunk/hoc/Setup.hs
==============================================================================
--- trunk/hoc/Setup.hs (original)
+++ trunk/hoc/Setup.hs Sun Dec 21 13:42:00 2008
@@ -1,6 +1,8 @@
import Distribution.Simple
import Distribution.PackageDescription
+import Distribution.Simple.Build
import Distribution.Simple.Setup
+import Distribution.Simple.PreProcess
import Distribution.Simple.Configure
import Distribution.Simple.LocalBuildInfo
import System.Cmd( system )
@@ -13,9 +15,46 @@
main = defaultMainWithHooks $ simpleUserHooks {
confHook = customConfig,
- preBuild = customPreBuild
+ buildHook = customBuild
}
+
+-- You probably don't need to change this, but if you do beware that
+-- it will not be sanitized for the shell.
+cbitsObjectFile = "dist/build/HOC_cbits.o"
+
+needsCBitsWhileBuilding :: Executable -> Bool
+needsCBitsWhileBuilding e
+ | exeName e == "hoc-test" = True
+ | otherwise = False
+
+objc2_flagName = FlagName "objc2"
+
+setObjC2Flag :: ConfigFlags -> IO ConfigFlags
+setObjC2Flag cf
+ -- if the flag is set on the command line, do nothing
+ | lookup (objc2_flagName) (configConfigurationsFlags cf) /= Nothing
+ = return cf
+
+ -- if we're not on darwin, assume false
+ | System.Info.os /= "darwin"
+ = return $ addFlag objc2_flagName False cf
+
+ -- otherwise make an educated guess
+ | otherwise
+ = do
+ value <- objC2Available
+ return $ addFlag objc2_flagName value cf
+ where addFlag flag value cf = cf { configConfigurationsFlags =
+ (flag,value) : configConfigurationsFlags cf }
+
+objC2Available :: IO Bool
+objC2Available
+ | System.Info.os /= "darwin" = return False
+ | otherwise = do
+ result <- system "grep -qR /usr/include/objc -e
objc_allocateClassPair"
+ return (result == ExitSuccess)
+
backquote :: String -> IO String
backquote cmd = do
(inp,out,err,pid) <- runInteractiveCommand cmd
@@ -43,6 +82,8 @@
customConfig :: (Either GenericPackageDescription PackageDescription,
HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo
customConfig pdbi cf = do
+ cf <- setObjC2Flag cf
+
lbi <- configure pdbi cf
if System.Info.os == "darwin"
then return()
@@ -52,48 +93,56 @@
return lbi
-customPreBuild :: Args -> BuildFlags -> IO HookedBuildInfo
-customPreBuild args buildFlags = do
- putStrLn "Compiling HOC_cbits..."
- system "mkdir -p dist/build/"
+customBuild :: PackageDescription -> LocalBuildInfo -> UserHooks ->
BuildFlags -> IO ()
+customBuild pd lbi hooks buildFlags = do
+ let Just libInfo = library pd
+
+ extraFlags <- buildCBits (libBuildInfo libInfo)
+
+ let hooked_pd = pd
+ { library = Just $ libInfo
+ { libBuildInfo = addCompilerFlags extraFlags
+ (libBuildInfo libInfo)
+ }
+ , executables = alterExecutable needsCBitsWhileBuilding
+ (\exe -> exe {buildInfo = addCompilerFlags
extraFlags (buildInfo exe)})
+ (executables pd)
+ }
- (cflags, paths, extralibs) <-
- if System.Info.os == "darwin"
- then do
- return ("-I/usr/include/ffi -DMACOSX", [], ["-framework
Foundation"])
- else do
- (gcclibdir, system_libs, system_headers) <- gnustepPaths
- ffi_cflags <- backquote "pkg-config libffi --cflags"
- return ("-I" ++ system_headers ++ " -DGNUSTEP" ++ " " ++
ffi_cflags,
- ["-L" ++ gcclibdir, "-L" ++ system_libs],
- ["-lgnustep-base"])
+ build hooked_pd lbi buildFlags knownSuffixHandlers
+-- |Build HOC_cbits.o using the flags specified in the configuration
+-- stage, and return a list of flags to add to support usage of
+-- template-haskell while compiling (for both the library and the
+-- hoc-test executable)
+buildCBits :: BuildInfo -> IO [(CompilerFlavor, [String])]
+buildCBits buildInfo = do
+ putStrLn "Compiling HOC_cbits..."
+ system ("mkdir -p " ++ takeDirectory cbitsObjectFile)
+
+ let cflags = cppOptions buildInfo ++ ccOptions buildInfo
+ ++ ["-I" ++ dir | dir <- includeDirs buildInfo]
+ extraGHCflags = [cbitsObjectFile]
+ ++ ["-l" ++ lib | lib <- extraLibs buildInfo]
+ ++ ["-framework " ++ fw | fw <- frameworks buildInfo]
+
exitCode <- system $ "gcc -r -nostdlib -I`ghc --print-libdir`/include "
- ++ cflags ++ " HOC_cbits/*.m -o dist/build/HOC_cbits.o"
-
+ ++ unwords cflags
+ ++ " HOC_cbits/*.m -o " ++ cbitsObjectFile
+
case exitCode of
ExitSuccess -> return ()
_ -> fail "Failed in C compilation."
- -- system "cp dist/build/HOC_cbits.o dist/build/HOC_cbits.dyn_o"
- system "cp dist/build/HOC_cbits.o dist/build/hoc-test/hoc-test-tmp/"
-
- let buildInfo = emptyBuildInfo {
- options = [ (GHC, ["dist/build/HOC_cbits.o" ]
- ++ paths ++
- ["-lobjc",
- "-lffi"]
- ++ extralibs) ],
- cSources = ["HOC_cbits.o"]
- }
- buildInfo2 = emptyBuildInfo {
- options = [ (GHC,
["dist/build/hoc-test/hoc-test-tmp/HOC_cbits.o" ]
- ++ paths ++
- ["-lobjc",
- "-lffi"]
- ++ extralibs) ]{-,
- cSources = ["HOC_cbits.o"]-}
- }
-
- return (Just buildInfo, [("hoc-test", buildInfo2)])
+ return [(GHC, extraGHCflags)]
+
+-- TODO: check whether it's OK for the options field to have multiple
+-- entries for the same "compiler flavor"
+addCompilerFlags :: [(CompilerFlavor,[String])] -> BuildInfo -> BuildInfo
+addCompilerFlags flags buildInfo = buildInfo {
+ options = flags ++ options buildInfo
+ }
+alterExecutable :: (Executable -> Bool) -> (Executable -> Executable)
+ -> [Executable] -> [Executable]
+alterExecutable p f exes = [if p exe then f exe else exe | exe <- exes]
\ No newline at end of file
Modified: trunk/hoc/Tests/TestFoundation.hs
==============================================================================
--- trunk/hoc/Tests/TestFoundation.hs (original)
+++ trunk/hoc/Tests/TestFoundation.hs Sun Dec 21 13:42:00 2008
@@ -94,16 +94,19 @@
$(declareClass "HaskellObjectCountingInvocations" "NSObject")
$(exportClass "HaskellObjectCountingInvocations" "hoci_1_" [
- InstanceMethod 'countInvocationsUpto
+ InstanceMethod 'countInvocationsUpto,
+ ClassMethod 'countInvocationsUpto
])
instance Has_countInvocationsUpto (HaskellObjectCountingInvocations a)
+instance Has_countInvocationsUpto (HaskellObjectCountingInvocationsClass a)
hoci_1_countInvocationsUpto start limit self = return (start + 1)
$(declareClass "HaskellObjectUsingSuper" "HaskellObjectCountingInvocations")
$(exportClass "HaskellObjectUsingSuper" "hoci_2_" [
- InstanceMethod 'countInvocationsUpto
+ InstanceMethod 'countInvocationsUpto,
+ ClassMethod 'countInvocationsUpto
])
hoci_2_countInvocationsUpto start limit self
@@ -268,7 +271,7 @@
str <- hobj # description
fromNSString str @?= "<HaskellObjectWithDescription: TEST>"
),
- "chaining" ~: test [
+ "instanceChaining" ~: test [
"base" ~: (assertNoLeaks $ do
hobj <- _HaskellObjectCountingInvocations # alloc >>=
init
count <- hobj # countInvocationsUpto 0 100
@@ -284,6 +287,22 @@
count <- hobj # countInvocationsUpto 0 100
count @?= 2
)
+
+ ],
+ "classChaining" ~: test [
+ "base" ~: (assertNoLeaks $ do
+ count <- _HaskellObjectCountingInvocations #
countInvocationsUpto 0 100
+ count @?= 1
+ ),
+ "subclass" ~: (assertNoLeaks $ do
+ count <- _HaskellObjectUsingSuper #
countInvocationsUpto 0 100
+ count @?= 2
+ ),
+ "subsubclass" ~: (assertNoLeaks $ do
+ count <- _HaskellSubclassOfObjectUsingSuper #
countInvocationsUpto 0 100
+ count @?= 2
+ )
+
]
],
"structs" ~: test [
|
|
From: <cod...@go...> - 2008-12-10 22:32:17
|
Author: jam...@us...
Date: Wed Dec 10 14:10:22 2008
New Revision: 376
Modified:
/ (props changed)
branches/objc2/hoc/HOC.cabal
branches/objc2/hoc/Setup.hs
Log:
r380@Macintosh: james.cook | 2008-12-10 17:09:59 -0500
(objc2 branch) Added simple autodetection for ObjC2 build flag.
Modified: branches/objc2/hoc/HOC.cabal
==============================================================================
--- branches/objc2/hoc/HOC.cabal (original)
+++ branches/objc2/hoc/HOC.cabal Wed Dec 10 14:10:22 2008
@@ -16,7 +16,6 @@
Flag ObjC2
description: build for Objective-C 2.0
- default: False
Library
build-depends: base, template-haskell, unix
Modified: branches/objc2/hoc/Setup.hs
==============================================================================
--- branches/objc2/hoc/Setup.hs (original)
+++ branches/objc2/hoc/Setup.hs Wed Dec 10 14:10:22 2008
@@ -27,6 +27,34 @@
| exeName e == "hoc-test" = True
| otherwise = False
+objc2_flagName = FlagName "objc2"
+
+setObjC2Flag :: ConfigFlags -> IO ConfigFlags
+setObjC2Flag cf
+ -- if the flag is set on the command line, do nothing
+ | lookup (objc2_flagName) (configConfigurationsFlags cf) /= Nothing
+ = return cf
+
+ -- if we're not on darwin, assume false
+ | System.Info.os /= "darwin"
+ = return $ addFlag objc2_flagName False cf
+
+ -- otherwise make an educated guess
+ | otherwise
+ = do
+ value <- objC2Available
+ return $ addFlag objc2_flagName value cf
+
+ where addFlag flag value cf = cf { configConfigurationsFlags =
+ (flag,value) : configConfigurationsFlags cf }
+
+objC2Available :: IO Bool
+objC2Available
+ | System.Info.os /= "darwin" = return False
+ | otherwise = do
+ result <- system "grep -qR /usr/include/objc -e
objc_allocateClassPair"
+ return (result == ExitSuccess)
+
backquote :: String -> IO String
backquote cmd = do
(inp,out,err,pid) <- runInteractiveCommand cmd
@@ -54,6 +82,8 @@
customConfig :: (Either GenericPackageDescription PackageDescription,
HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo
customConfig pdbi cf = do
+ cf <- setObjC2Flag cf
+
lbi <- configure pdbi cf
if System.Info.os == "darwin"
then return()
|
|
From: <cod...@go...> - 2008-12-10 16:32:18
|
Author: jam...@us...
Date: Wed Dec 10 08:29:58 2008
New Revision: 375
Modified:
branches/objc2/hoc/InterfaceGenerator2/Output.hs
Log:
(objc2 branch) Updated InterfaceGenerator2 to properly import and export
metaclasses in support of r374.
Modified: branches/objc2/hoc/InterfaceGenerator2/Output.hs
==============================================================================
--- branches/objc2/hoc/InterfaceGenerator2/Output.hs (original)
+++ branches/objc2/hoc/InterfaceGenerator2/Output.hs Wed Dec 10 08:29:58
2008
@@ -25,6 +25,7 @@
ClassEntity _ ->
[eHaskellName e, '_' `BS.cons` eHaskellName e,
eHaskellName e `BS.append` BS.pack "Class",
+ eHaskellName e `BS.append` BS.pack "MetaClass",
BS.pack "super_" `BS.append` eHaskellName e,
eHaskellName e `BS.snoc` '_' ]
EnumEntity complete values ->
@@ -56,11 +57,13 @@
LocalModule m
-> text "import {-# SOURCE #-}" <+> textBS m
<+> parens (textBS (eHaskellName e) <> comma
- <+> textBS (eHaskellName e) <> text "Class")
+ <+> textBS (eHaskellName e) <> text "Class" <>
comma
+ <+> textBS (eHaskellName e) <>
text "MetaClass")
FrameworkModule f m
-> text "import" <+> textBS m
<+> parens (textBS (eHaskellName e) <> comma
- <+> textBS (eHaskellName e) <> text "Class")
+ <+> textBS (eHaskellName e) <> text "Class" <>
comma
+ <+> textBS (eHaskellName e) <>
text "MetaClass")
pprHsBoot entityPile modName entities
= text "module" <+> textBS modName <+> text "where" $+$
@@ -78,6 +81,9 @@
<+> parens (textBS name <> char '_' <+> char 'a')
$+$
text "type" <+> textBS name <> text "Class" <+>
char 'a' <+> equals
<+> text (maybe "Class" ( (++ "Class") .
BS.unpack . eHaskellName ) mbSuper)
+ <+> parens (textBS name <> char '_' <+> char 'a')
$+$
+ text "type" <+> textBS name <> text "MetaClass" <+>
char 'a' <+> equals
+ <+> text (maybe "MetaClass" ( (++ "MetaClass") .
BS.unpack . eHaskellName ) mbSuper)
<+> parens (textBS name <> char '_' <+> char 'a')
| (name, mbSuper) <- classes0 ]
|
|
From: <cod...@go...> - 2008-12-10 16:24:15
|
Author: jam...@us...
Date: Wed Dec 10 07:59:54 2008
New Revision: 374
Modified:
branches/objc2/hoc/HOC/HOC.hs
branches/objc2/hoc/HOC/HOC/Class.hs
branches/objc2/hoc/HOC/HOC/DeclareClass.hs
branches/objc2/hoc/Tests/TestFoundation.hs
Log:
Experimental patch (committed to objc2 branch only for now, though it's not
at all specific to objective c 2.0 - I just wasn't sure if it was too
disruptive to push to the trunk) extending previous work on super calls to
cover class methods.
This involved adding a fair bit to the output of declareClass - if anyone
sees a better way to do this, I'd love to hear about it. One thing I
thought about was using an instance of the form:
instance ClassAndObject meta $(metaClsType) => ClassObject meta
where classObject = unsafeGetMetaclassForClass classObject
I believe this would have "worked" with slightly less clutter in the
namespace, but it would require adding FlexibleContexts to the LANGUAGE
pragma
of every source file that calls declareClass, which seemed even more
disruptive.
Modified: branches/objc2/hoc/HOC/HOC.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC.hs (original)
+++ branches/objc2/hoc/HOC/HOC.hs Wed Dec 10 07:59:54 2008
@@ -4,6 +4,7 @@
nil,
Object(..),
Class,
+ MetaClass,
ClassAndObject,
ClassObject,
classObject,
Modified: branches/objc2/hoc/HOC/HOC/Class.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/Class.hs (original)
+++ branches/objc2/hoc/HOC/HOC/Class.hs Wed Dec 10 07:59:54 2008
@@ -11,15 +11,13 @@
import Foreign
import Foreign.C.String
-
data Class_ a
type Class a = ID (Class_ a)
-
+type MetaClass a = Class (Class_ a)
unsafeGetClassObject :: String -> Class a
-
foreign import ccall unsafe "Class.h getClassByName"
c_getClassByName :: CString -> IO (Ptr ObjCObject)
@@ -30,6 +28,16 @@
getClassByName name >>= importImmortal
+unsafeGetMetaclassForClass :: Class a -> MetaClass a
+
+foreign import ccall unsafe "Class.h getClassForObject"
+ c_getClassForObject :: Ptr ObjCObject -> IO (Ptr ObjCObject)
+
+getClassForObject obj = withExportedArgument obj c_getClassForObject
+
+{-# NOINLINE unsafeGetMetaclassForClass #-}
+unsafeGetMetaclassForClass obj = unsafePerformIO $
+ getClassForObject obj >>= importImmortal
class (Object a, Object b) => ClassAndObject a b | a -> b, b -> a
Modified: branches/objc2/hoc/HOC/HOC/DeclareClass.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/DeclareClass.hs (original)
+++ branches/objc2/hoc/HOC/HOC/DeclareClass.hs Wed Dec 10 07:59:54 2008
@@ -31,6 +31,12 @@
`appT` (conT (mkName phantomName)
`appT` varT (mkName "a"))),
+ -- type $(metaMetaClassName) a = $(superMetaMetaClassName)
($(phantomName) a)
+ tySynD (mkName metaMetaClassName) [mkName "a"]
+ (conT (mkName superMetaMetaClassName)
+ `appT` (conT (mkName phantomName)
+ `appT` varT (mkName "a"))),
+
-- $(classObjectName) :: $(metaClassName) ()
sigD (mkName classObjectName) (conT (mkName metaClassName)
`appT` [t| () |]),
@@ -39,6 +45,11 @@
valD (return $ VarP (mkName classObjectName))
(normalB [| unsafeGetClassObject $(stringE name) |]) [],
+ -- $(metaClassObjectName) = unsafeGetMetaclassForClass
$(classObjectName)
+ valD (return $ VarP (mkName metaClassObjectName))
+ (normalB [| unsafeGetMetaclassForClass $(varE (mkName
classObjectName)) |]) [],
+
+ -- $(superName) :: String
sigD (mkName superName) [t| String |],
-- $(superName) = "super"
@@ -47,20 +58,35 @@
-- instance SuperClass (name ()) (super ())
instanceD (cxt []) (conT ''SuperClass `appT` clsType `appT`
superType) [],
+ -- instance SuperClass (clsName ()) (superClsName ())
+ instanceD (cxt []) (conT ''SuperClass `appT` metaClsType `appT`
superMetaType) [],
+
-- instance ClassObject (metaClsName ())
-- where classObject = classObject
instanceD (cxt []) (conT ''ClassObject `appT` metaClsType)
- [funD 'classObject [clause [] (normalB $ varE (mkName
classObjectName)) []]]
+ [funD 'classObject [clause [] (normalB $ varE (mkName
classObjectName)) []]],
+
+ -- instance ClassObject metaMetaCls
+ -- where classObject = unsafeGetMetaclassForClass classObject
+ -- {- metaclass object, to support super calls in class methods -}
+ instanceD (cxt []) (conT ''ClassObject `appT` metaMetaClsType)
+ [funD 'classObject [clause [] (normalB $ varE (mkName
metaClassObjectName)) []]]
]
where
phantomName = name ++ "_"
metaClassName = name ++ "Class"
+ metaMetaClassName = name ++ "MetaClass"
metaPhantomName = metaClassName ++ "_"
superMetaClassName | super == "ID" = "Class"
| otherwise = super ++ "Class"
+ superMetaMetaClassName | super == "ID" = "MetaClass"
+ | otherwise = super ++ "MetaClass"
classObjectName = "_" ++ name
+ metaClassObjectName = "_" ++ metaClassName
superName = "super_" ++ name
+ metaMetaClsType = conT (mkName metaMetaClassName) `appT` [t| () |]
metaClsType = conT (mkName metaClassName) `appT` [t| () |]
clsType = conT (mkName name) `appT` [t| () |]
superType = conT (mkName super) `appT` [t| () |]
+ superMetaType = conT (mkName superMetaClassName) `appT` [t| () |]
Modified: branches/objc2/hoc/Tests/TestFoundation.hs
==============================================================================
--- branches/objc2/hoc/Tests/TestFoundation.hs (original)
+++ branches/objc2/hoc/Tests/TestFoundation.hs Wed Dec 10 07:59:54 2008
@@ -94,16 +94,19 @@
$(declareClass "HaskellObjectCountingInvocations" "NSObject")
$(exportClass "HaskellObjectCountingInvocations" "hoci_1_" [
- InstanceMethod 'countInvocationsUpto
+ InstanceMethod 'countInvocationsUpto,
+ ClassMethod 'countInvocationsUpto
])
instance Has_countInvocationsUpto (HaskellObjectCountingInvocations a)
+instance Has_countInvocationsUpto (HaskellObjectCountingInvocationsClass a)
hoci_1_countInvocationsUpto start limit self = return (start + 1)
$(declareClass "HaskellObjectUsingSuper" "HaskellObjectCountingInvocations")
$(exportClass "HaskellObjectUsingSuper" "hoci_2_" [
- InstanceMethod 'countInvocationsUpto
+ InstanceMethod 'countInvocationsUpto,
+ ClassMethod 'countInvocationsUpto
])
hoci_2_countInvocationsUpto start limit self
@@ -268,7 +271,7 @@
str <- hobj # description
fromNSString str @?= "<HaskellObjectWithDescription: TEST>"
),
- "chaining" ~: test [
+ "instanceChaining" ~: test [
"base" ~: (assertNoLeaks $ do
hobj <- _HaskellObjectCountingInvocations # alloc >>=
init
count <- hobj # countInvocationsUpto 0 100
@@ -284,6 +287,22 @@
count <- hobj # countInvocationsUpto 0 100
count @?= 2
)
+
+ ],
+ "classChaining" ~: test [
+ "base" ~: (assertNoLeaks $ do
+ count <- _HaskellObjectCountingInvocations #
countInvocationsUpto 0 100
+ count @?= 1
+ ),
+ "subclass" ~: (assertNoLeaks $ do
+ count <- _HaskellObjectUsingSuper #
countInvocationsUpto 0 100
+ count @?= 2
+ ),
+ "subsubclass" ~: (assertNoLeaks $ do
+ count <- _HaskellSubclassOfObjectUsingSuper #
countInvocationsUpto 0 100
+ count @?= 2
+ )
+
]
],
"structs" ~: test [
|
|
From: <cod...@go...> - 2008-12-10 15:00:30
|
Author: jam...@us...
Date: Wed Dec 10 06:53:54 2008
New Revision: 373
Modified:
branches/objc2/hoc/HOC/HOC.hs
branches/objc2/hoc/HOC/HOC/Class.hs
branches/objc2/hoc/HOC/HOC/DeclareClass.hs
branches/objc2/hoc/HOC/HOC/NewlyAllocated.hs
branches/objc2/hoc/HOC/HOC/Super.hs
Log:
Same as r372, applied to objc2 branch.
Modified: branches/objc2/hoc/HOC/HOC.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC.hs (original)
+++ branches/objc2/hoc/HOC/HOC.hs Wed Dec 10 06:53:54 2008
@@ -5,9 +5,8 @@
Object(..),
Class,
ClassAndObject,
- StaticClassAndObject,
- staticClassForObject,
- staticSuperclassForObject,
+ ClassObject,
+ classObject,
( # ), ( #. ),
withExportedArray,
castObject,
Modified: branches/objc2/hoc/HOC/HOC/Class.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/Class.hs (original)
+++ branches/objc2/hoc/HOC/HOC/Class.hs Wed Dec 10 06:53:54 2008
@@ -36,13 +36,6 @@
instance ClassAndObject (Class a) (ID a)
-class ClassAndObject a b => StaticClassAndObject a b
- where
- -- _staticClassForObject must not touch its parameter:
- -- its value should only depend on the type of the parameter.
- _staticClassForObject :: b -> a
-
--- make an export-safe version; don't want people making new
--- implementations, but they should be allowed to use the info.
-staticClassForObject :: StaticClassAndObject a b => b -> a
-staticClassForObject = _staticClassForObject
\ No newline at end of file
+class Object cls => ClassObject cls
+ where
+ classObject :: cls
Modified: branches/objc2/hoc/HOC/HOC/DeclareClass.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/DeclareClass.hs (original)
+++ branches/objc2/hoc/HOC/HOC/DeclareClass.hs Wed Dec 10 06:53:54 2008
@@ -47,10 +47,10 @@
-- instance SuperClass (name ()) (super ())
instanceD (cxt []) (conT ''SuperClass `appT` clsType `appT`
superType) [],
- -- instance StaticClassAndObject (name ())
- -- where staticClassForObject _ = classObject
- instanceD (cxt []) (conT ''StaticClassAndObject `appT` metaClsType
`appT` clsType)
- [funD '_staticClassForObject [clause [wildP] (normalB $ varE
(mkName classObjectName)) []]]
+ -- instance ClassObject (metaClsName ())
+ -- where classObject = classObject
+ instanceD (cxt []) (conT ''ClassObject `appT` metaClsType)
+ [funD 'classObject [clause [] (normalB $ varE (mkName
classObjectName)) []]]
]
where
phantomName = name ++ "_"
Modified: branches/objc2/hoc/HOC/HOC/NewlyAllocated.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/NewlyAllocated.hs (original)
+++ branches/objc2/hoc/HOC/HOC/NewlyAllocated.hs Wed Dec 10 06:53:54 2008
@@ -1,4 +1,5 @@
-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
UndecidableInstances #-}
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
UndecidableInstances,
+ ScopedTypeVariables #-}
module HOC.NewlyAllocated where
{-
@@ -55,9 +56,6 @@
sendMessageWithoutRetval (NewlyAllocated _) =
objSendMessageWithoutRetval
sendMessageWithoutRetval (NewSuper _ _) = superSendMessageWithoutRetval
-instance (SuperClass sub (ID super), StaticClassAndObject (Class super)
(ID super))
+instance (SuperClass sub (ID super), ClassObject (Class super))
=> Super (NewlyAllocated sub) (NewlyAllocated (ID super)) where
- super na@(NewlyAllocated x) = NewSuper x (castObject superClass)
- where superClass = staticClassForObject (asSuper na)
- asSuper :: SuperClass sub super => NewlyAllocated sub ->
super
- asSuper _ = error "staticClassForObject must not touch its
parameter"
+ super (NewlyAllocated x) = NewSuper x (castObject (classObject ::
Class super))
Modified: branches/objc2/hoc/HOC/HOC/Super.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/Super.hs (original)
+++ branches/objc2/hoc/HOC/HOC/Super.hs Wed Dec 10 06:53:54 2008
@@ -2,8 +2,7 @@
UndecidableInstances, FlexibleInstances,
FlexibleContexts #-}
module HOC.Super(
- SuperClass, SuperTarget, Super(super), withExportedSuper,
- staticSuperclassForObject, castSuper
+ SuperClass, SuperTarget, Super(super), withExportedSuper, castSuper
) where
import HOC.Base
@@ -58,14 +57,14 @@
staticSuperclassForObject ::
( SuperClass (ID sub) (ID super)
- , StaticClassAndObject (Class super) (ID super)
+ , ClassObject (Class super)
) => ID sub -> Class super
-staticSuperclassForObject = staticClassForObject . castSuper
+staticSuperclassForObject obj = classObject
instance (Object (ID sub), Object (ID super), SuperClass (ID sub) (ID
super),
- StaticClassAndObject (Class super) (ID super))
+ ClassObject (Class super))
=> Super (ID sub) (SuperTarget (ID super)) where
- super obj = SuperTarget (fromID $ toID obj) (castObject
(staticSuperclassForObject obj))
+ super obj = SuperTarget (castSuper obj) (castObject
(staticSuperclassForObject obj))
instance MessageTarget a => MessageTarget (SuperTarget a) where
isNil (SuperTarget x cls) = isNil x || isNil cls
|
|
From: <cod...@go...> - 2008-12-10 14:56:22
|
Author: jam...@us...
Date: Wed Dec 10 06:52:25 2008
New Revision: 372
Modified:
trunk/hoc/HOC/HOC.hs
trunk/hoc/HOC/HOC/Class.hs
trunk/hoc/HOC/HOC/DeclareClass.hs
trunk/hoc/HOC/HOC/NewlyAllocated.hs
trunk/hoc/HOC/HOC/Super.hs
Log:
Simplified previous patch for Issue 9 by replacing
newly-introduced "StaticClassAndObject" typeclass with a
simpler "ClassObject" typeclass.
This patch touches the template-haskell code, so bindings will have to be
rebuilt. Sorry for any inconvenience this may cause.
Modified: trunk/hoc/HOC/HOC.hs
==============================================================================
--- trunk/hoc/HOC/HOC.hs (original)
+++ trunk/hoc/HOC/HOC.hs Wed Dec 10 06:52:25 2008
@@ -5,9 +5,8 @@
Object(..),
Class,
ClassAndObject,
- StaticClassAndObject,
- staticClassForObject,
- staticSuperclassForObject,
+ ClassObject,
+ classObject,
( # ), ( #. ),
withExportedArray,
castObject,
Modified: trunk/hoc/HOC/HOC/Class.hs
==============================================================================
--- trunk/hoc/HOC/HOC/Class.hs (original)
+++ trunk/hoc/HOC/HOC/Class.hs Wed Dec 10 06:52:25 2008
@@ -36,13 +36,6 @@
instance ClassAndObject (Class a) (ID a)
-class ClassAndObject a b => StaticClassAndObject a b
- where
- -- _staticClassForObject must not touch its parameter:
- -- its value should only depend on the type of the parameter.
- _staticClassForObject :: b -> a
-
--- make an export-safe version; don't want people making new
--- implementations, but they should be allowed to use the info.
-staticClassForObject :: StaticClassAndObject a b => b -> a
-staticClassForObject = _staticClassForObject
\ No newline at end of file
+class Object cls => ClassObject cls
+ where
+ classObject :: cls
Modified: trunk/hoc/HOC/HOC/DeclareClass.hs
==============================================================================
--- trunk/hoc/HOC/HOC/DeclareClass.hs (original)
+++ trunk/hoc/HOC/HOC/DeclareClass.hs Wed Dec 10 06:52:25 2008
@@ -47,10 +47,10 @@
-- instance SuperClass (name ()) (super ())
instanceD (cxt []) (conT ''SuperClass `appT` clsType `appT`
superType) [],
- -- instance StaticClassAndObject (name ())
- -- where staticClassForObject _ = classObject
- instanceD (cxt []) (conT ''StaticClassAndObject `appT` metaClsType
`appT` clsType)
- [funD '_staticClassForObject [clause [wildP] (normalB $ varE
(mkName classObjectName)) []]]
+ -- instance ClassObject (metaClsName ())
+ -- where classObject = classObject
+ instanceD (cxt []) (conT ''ClassObject `appT` metaClsType)
+ [funD 'classObject [clause [] (normalB $ varE (mkName
classObjectName)) []]]
]
where
phantomName = name ++ "_"
Modified: trunk/hoc/HOC/HOC/NewlyAllocated.hs
==============================================================================
--- trunk/hoc/HOC/HOC/NewlyAllocated.hs (original)
+++ trunk/hoc/HOC/HOC/NewlyAllocated.hs Wed Dec 10 06:52:25 2008
@@ -1,4 +1,5 @@
-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
UndecidableInstances #-}
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
UndecidableInstances,
+ ScopedTypeVariables #-}
module HOC.NewlyAllocated where
{-
@@ -55,9 +56,6 @@
sendMessageWithoutRetval (NewlyAllocated _) =
objSendMessageWithoutRetval
sendMessageWithoutRetval (NewSuper _ _) = superSendMessageWithoutRetval
-instance (SuperClass sub (ID super), StaticClassAndObject (Class super)
(ID super))
+instance (SuperClass sub (ID super), ClassObject (Class super))
=> Super (NewlyAllocated sub) (NewlyAllocated (ID super)) where
- super na@(NewlyAllocated x) = NewSuper x (castObject superClass)
- where superClass = staticClassForObject (asSuper na)
- asSuper :: SuperClass sub super => NewlyAllocated sub ->
super
- asSuper _ = error "staticClassForObject must not touch its
parameter"
+ super (NewlyAllocated x) = NewSuper x (castObject (classObject ::
Class super))
Modified: trunk/hoc/HOC/HOC/Super.hs
==============================================================================
--- trunk/hoc/HOC/HOC/Super.hs (original)
+++ trunk/hoc/HOC/HOC/Super.hs Wed Dec 10 06:52:25 2008
@@ -2,8 +2,7 @@
UndecidableInstances, FlexibleInstances,
FlexibleContexts #-}
module HOC.Super(
- SuperClass, SuperTarget, Super(super), withExportedSuper,
- staticSuperclassForObject, castSuper
+ SuperClass, SuperTarget, Super(super), withExportedSuper, castSuper
) where
import HOC.Base
@@ -58,14 +57,14 @@
staticSuperclassForObject ::
( SuperClass (ID sub) (ID super)
- , StaticClassAndObject (Class super) (ID super)
+ , ClassObject (Class super)
) => ID sub -> Class super
-staticSuperclassForObject = staticClassForObject . castSuper
+staticSuperclassForObject obj = classObject
instance (Object (ID sub), Object (ID super), SuperClass (ID sub) (ID
super),
- StaticClassAndObject (Class super) (ID super))
+ ClassObject (Class super))
=> Super (ID sub) (SuperTarget (ID super)) where
- super obj = SuperTarget (fromID $ toID obj) (castObject
(staticSuperclassForObject obj))
+ super obj = SuperTarget (castSuper obj) (castObject
(staticSuperclassForObject obj))
instance MessageTarget a => MessageTarget (SuperTarget a) where
isNil (SuperTarget x cls) = isNil x || isNil cls
|
|
From: <cod...@go...> - 2008-12-09 22:45:37
|
Author: jam...@us...
Date: Tue Dec 9 12:37:44 2008
New Revision: 369
Modified:
branches/objc2/hoc/HOC/HOC.hs
branches/objc2/hoc/HOC/HOC/Class.hs
branches/objc2/hoc/HOC/HOC/DeclareClass.hs
branches/objc2/hoc/HOC/HOC/NewlyAllocated.hs
branches/objc2/hoc/HOC/HOC/Super.hs
branches/objc2/hoc/Tests/TestFoundation.hs
Log:
Pushing same changes in r368 (super call chaining fix) to objc2 branch.
Modified: branches/objc2/hoc/HOC/HOC.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC.hs (original)
+++ branches/objc2/hoc/HOC/HOC.hs Tue Dec 9 12:37:44 2008
@@ -5,6 +5,9 @@
Object(..),
Class,
ClassAndObject,
+ StaticClassAndObject,
+ staticClassForObject,
+ staticSuperclassForObject,
( # ), ( #. ),
withExportedArray,
castObject,
@@ -36,6 +39,7 @@
SuperClass,
SuperTarget,
super,
+ castSuper,
CEnum(..),
declareCEnum,
Modified: branches/objc2/hoc/HOC/HOC/Class.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/Class.hs (original)
+++ branches/objc2/hoc/HOC/HOC/Class.hs Tue Dec 9 12:37:44 2008
@@ -35,3 +35,14 @@
class (Object a, Object b) => ClassAndObject a b | a -> b, b -> a
instance ClassAndObject (Class a) (ID a)
+
+class ClassAndObject a b => StaticClassAndObject a b
+ where
+ -- _staticClassForObject must not touch its parameter:
+ -- its value should only depend on the type of the parameter.
+ _staticClassForObject :: b -> a
+
+-- make an export-safe version; don't want people making new
+-- implementations, but they should be allowed to use the info.
+staticClassForObject :: StaticClassAndObject a b => b -> a
+staticClassForObject = _staticClassForObject
\ No newline at end of file
Modified: branches/objc2/hoc/HOC/HOC/DeclareClass.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/DeclareClass.hs (original)
+++ branches/objc2/hoc/HOC/HOC/DeclareClass.hs Tue Dec 9 12:37:44 2008
@@ -45,7 +45,12 @@
valD (return $ VarP (mkName superName)) (normalB $ stringE super)
[],
-- instance SuperClass (name ()) (super ())
- instanceD (cxt []) (conT ''SuperClass `appT` clsType `appT`
superType) []
+ instanceD (cxt []) (conT ''SuperClass `appT` clsType `appT`
superType) [],
+
+ -- instance StaticClassAndObject (name ())
+ -- where staticClassForObject _ = classObject
+ instanceD (cxt []) (conT ''StaticClassAndObject `appT` metaClsType
`appT` clsType)
+ [funD '_staticClassForObject [clause [wildP] (normalB $ varE
(mkName classObjectName)) []]]
]
where
phantomName = name ++ "_"
@@ -56,5 +61,6 @@
classObjectName = "_" ++ name
superName = "super_" ++ name
+ metaClsType = conT (mkName metaClassName) `appT` [t| () |]
clsType = conT (mkName name) `appT` [t| () |]
superType = conT (mkName super) `appT` [t| () |]
Modified: branches/objc2/hoc/HOC/HOC/NewlyAllocated.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/NewlyAllocated.hs (original)
+++ branches/objc2/hoc/HOC/HOC/NewlyAllocated.hs Tue Dec 9 12:37:44 2008
@@ -14,6 +14,8 @@
import HOC.Base ( ObjCObject )
import HOC.Arguments ( ObjCArgument(..) )
+import HOC.Class
+import HOC.ID
import HOC.MessageTarget( Object(..), MessageTarget(..) )
import HOC.MsgSend
import HOC.Super
@@ -24,15 +26,16 @@
data NewlyAllocated a
= NewlyAllocated (Ptr ObjCObject)
- | NewSuper (Ptr ObjCObject)
+ | NewSuper (Ptr ObjCObject) (Class ())
instance ObjCArgument (NewlyAllocated a) (Ptr ObjCObject) where
withExportedArgument (NewlyAllocated p) action = action p
- withExportedArgument (NewSuper p) action =
- withExportedSuper p action
+ withExportedArgument (NewSuper p cls) action =
+ withExportedArgument cls $ \cls ->
+ withExportedSuper p cls action
exportArgument (NewlyAllocated p) = return p
- exportArgument (NewSuper p) = fail "HOC.NewlyAllocated.NewSuper:
exportArgument"
+ exportArgument (NewSuper p cls) = fail "HOC.NewlyAllocated.NewSuper:
exportArgument"
importArgument p = return (NewlyAllocated p)
@@ -45,13 +48,16 @@
instance MessageTarget (NewlyAllocated a) where
isNil (NewlyAllocated p) = p == nullPtr
- isNil (NewSuper p) = p == nullPtr
+ isNil (NewSuper p cls) = (p == nullPtr) || isNil cls
sendMessageWithRetval (NewlyAllocated _) = objSendMessageWithRetval
- sendMessageWithRetval (NewSuper _) = superSendMessageWithRetval
+ sendMessageWithRetval (NewSuper _ _) = superSendMessageWithRetval
sendMessageWithoutRetval (NewlyAllocated _) =
objSendMessageWithoutRetval
- sendMessageWithoutRetval (NewSuper _) = superSendMessageWithoutRetval
+ sendMessageWithoutRetval (NewSuper _ _) = superSendMessageWithoutRetval
-instance SuperClass sub super
- => Super (NewlyAllocated sub) (NewlyAllocated super) where
- super (NewlyAllocated x) = NewSuper x
+instance (SuperClass sub (ID super), StaticClassAndObject (Class super)
(ID super))
+ => Super (NewlyAllocated sub) (NewlyAllocated (ID super)) where
+ super na@(NewlyAllocated x) = NewSuper x (castObject superClass)
+ where superClass = staticClassForObject (asSuper na)
+ asSuper :: SuperClass sub super => NewlyAllocated sub ->
super
+ asSuper _ = error "staticClassForObject must not touch its
parameter"
Modified: branches/objc2/hoc/HOC/HOC/Super.hs
==============================================================================
--- branches/objc2/hoc/HOC/HOC/Super.hs (original)
+++ branches/objc2/hoc/HOC/HOC/Super.hs Tue Dec 9 12:37:44 2008
@@ -1,12 +1,14 @@
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
UndecidableInstances, FlexibleInstances,
- ForeignFunctionInterface #-}
+ FlexibleContexts #-}
module HOC.Super(
- SuperClass, SuperTarget, Super(super), withExportedSuper
+ SuperClass, SuperTarget, Super(super), withExportedSuper,
+ staticSuperclassForObject, castSuper
) where
import HOC.Base
import HOC.Arguments
+import HOC.Class
import HOC.ID
import HOC.MsgSend
import HOC.MessageTarget
@@ -24,7 +26,7 @@
-- super, which is sufficient to define a class hierarchy.
class SuperClass sub super | sub -> super
-data SuperTarget a = SuperTarget a
+data SuperTarget a = SuperTarget a (Class ())
class Super sub super | sub -> super where
super :: sub -> super
@@ -34,32 +36,39 @@
pokeSuper objcSuper obj cls
= pokeByteOff objcSuper 0 obj >> pokeByteOff objcSuper (sizeOf obj) cls
-withExportedSuper p action =
- getSuperClassForObject p >>= \cls ->
+withExportedSuper p cls action =
allocaBytes (sizeOf p + sizeOf cls) $ \sptr ->
pokeSuper sptr p cls >> action sptr
instance MessageTarget a
=> ObjCArgument (SuperTarget a) (Ptr ObjCObject) where
- withExportedArgument (SuperTarget obj) action =
+ withExportedArgument (SuperTarget obj cls) action =
+ withExportedArgument cls $ \cls ->
withExportedArgument obj $ \p ->
- withExportedSuper p action
+ withExportedSuper p cls action
exportArgument _ = fail "HOC.Super: exportArgument"
importArgument _ = fail "HOC.Super: importArgument"
objCTypeString _ = "@" -- well, close enough.
-instance (Object (ID sub), Object super, SuperClass (ID sub) super)
- => Super (ID sub) (SuperTarget super) where
- super obj = SuperTarget (fromID $ toID obj)
+castSuper :: SuperClass (ID sub) (ID super) => ID sub -> ID super
+castSuper = castObject
-foreign import ccall "Class.h getSuperClassForObject"
- getSuperClassForObject :: Ptr ObjCObject -> IO (Ptr ())
+staticSuperclassForObject ::
+ ( SuperClass (ID sub) (ID super)
+ , StaticClassAndObject (Class super) (ID super)
+ ) => ID sub -> Class super
+staticSuperclassForObject = staticClassForObject . castSuper
+
+instance (Object (ID sub), Object (ID super), SuperClass (ID sub) (ID
super),
+ StaticClassAndObject (Class super) (ID super))
+ => Super (ID sub) (SuperTarget (ID super)) where
+ super obj = SuperTarget (fromID $ toID obj) (castObject
(staticSuperclassForObject obj))
instance MessageTarget a => MessageTarget (SuperTarget a) where
- isNil (SuperTarget x) = isNil x
+ isNil (SuperTarget x cls) = isNil x || isNil cls
sendMessageWithRetval _ = superSendMessageWithRetval
sendMessageWithoutRetval _ = superSendMessageWithoutRetval
Modified: branches/objc2/hoc/Tests/TestFoundation.hs
==============================================================================
--- branches/objc2/hoc/Tests/TestFoundation.hs (original)
+++ branches/objc2/hoc/Tests/TestFoundation.hs Tue Dec 9 12:37:44 2008
@@ -90,6 +90,30 @@
nil
>>= raise
+$(declareSelector "countInvocations:upto:" [t| Int -> Int -> IO Int |])
+
+$(declareClass "HaskellObjectCountingInvocations" "NSObject")
+$(exportClass "HaskellObjectCountingInvocations" "hoci_1_" [
+ InstanceMethod 'countInvocationsUpto
+ ])
+
+instance Has_countInvocationsUpto (HaskellObjectCountingInvocations a)
+
+hoci_1_countInvocationsUpto start limit self = return (start + 1)
+
+$(declareClass "HaskellObjectUsingSuper" "HaskellObjectCountingInvocations")
+$(exportClass "HaskellObjectUsingSuper" "hoci_2_" [
+ InstanceMethod 'countInvocationsUpto
+ ])
+
+hoci_2_countInvocationsUpto start limit self
+ | start >= limit = return start
+ | otherwise = super self # countInvocationsUpto (start + 1)
limit
+
+$(declareClass "HaskellSubclassOfObjectUsingSuper" "HaskellObjectUsingSuper")
+
+$(exportClass "HaskellSubclassOfObjectUsingSuper" "noMembers_" [])
+
tests = test [
"NSNumber" ~: test [
"alloc-initWithInt-intValue" ~: (assertNoLeaks $ do
@@ -172,7 +196,10 @@
initializeClass_HaskellObjectWithOutlet
initializeClass_HaskellObjectWithDescription
initializeClass_HaskellObjectWithIVar
- initializeClass_ExceptionThrower,
+ initializeClass_ExceptionThrower
+ initializeClass_HaskellObjectCountingInvocations
+ initializeClass_HaskellObjectUsingSuper
+ initializeClass_HaskellSubclassOfObjectUsingSuper,
"HaskellObjectWithOutlet" ~: test [
"alloc-init" ~: (assertNoLeaks $ do
@@ -235,11 +262,30 @@
result @?= expected
)
],
- "Super" ~: (assertNoLeaks $ do
- hobj <- _HaskellObjectWithDescription # alloc >>= init
- str <- hobj # description
- fromNSString str @?= "<HaskellObjectWithDescription: TEST>"
- ),
+ "Super" ~: test [
+ "description" ~: (assertNoLeaks $ do
+ hobj <- _HaskellObjectWithDescription # alloc >>= init
+ str <- hobj # description
+ fromNSString str @?= "<HaskellObjectWithDescription: TEST>"
+ ),
+ "chaining" ~: test [
+ "base" ~: (assertNoLeaks $ do
+ hobj <- _HaskellObjectCountingInvocations # alloc >>=
init
+ count <- hobj # countInvocationsUpto 0 100
+ count @?= 1
+ ),
+ "subclass" ~: (assertNoLeaks $ do
+ hobj <- _HaskellObjectUsingSuper # alloc >>= init
+ count <- hobj # countInvocationsUpto 0 100
+ count @?= 2
+ ),
+ "subsubclass" ~: (assertNoLeaks $ do
+ hobj <- _HaskellSubclassOfObjectUsingSuper # alloc >>=
init
+ count <- hobj # countInvocationsUpto 0 100
+ count @?= 2
+ )
+ ]
+ ],
"structs" ~: test [
"pointArg" ~: (do
let point = NSPoint 6.42 7.42
|
|
From: <cod...@go...> - 2008-12-09 21:52:44
|
Author: jam...@us...
Date: Tue Dec 9 13:10:33 2008
New Revision: 370
Modified:
branches/objc2/hoc/HOC_cbits/Exceptions.m
Log:
(objc2 branch) fixed a backward-compatibility issue I previously noted but
forgot to fix
Modified: branches/objc2/hoc/HOC_cbits/Exceptions.m
==============================================================================
--- branches/objc2/hoc/HOC_cbits/Exceptions.m (original)
+++ branches/objc2/hoc/HOC_cbits/Exceptions.m Tue Dec 9 13:10:33 2008
@@ -64,8 +64,11 @@
clsHOCHaskellException = getClassByName("HOCHaskellException");
stablePtrIvar = class_getInstanceVariable(clsHOCHaskellException,
hsExceptionIvarName);
- #warning TODO - ivar_getOffset needs backport or workaround for
fact that offsets are no longer in the list
+#ifdef __OBJC2__
stablePtrOffset = ivar_getOffset(stablePtrIvar);
+#else
+ stablePtrOffset = stablePtrIvar->ivar_offset;
+#endif
selExceptionWithNameReasonUserInfo =
getSelectorForName("exceptionWithName:reason:userInfo:");
|
|
From: <cod...@go...> - 2008-12-09 21:28:53
|
Author: jam...@us...
Date: Tue Dec 9 13:12:04 2008
New Revision: 371
Modified:
branches/objc2/hoc/HOC_cbits/Ivars.m
branches/objc2/hoc/HOC_cbits/NewClass.h
Log:
(objc2 branch) Removed last 2 sources of build warnings in cbits. (yes, I
did proofread before removing the TODO ;-))
Modified: branches/objc2/hoc/HOC_cbits/Ivars.m
==============================================================================
--- branches/objc2/hoc/HOC_cbits/Ivars.m (original)
+++ branches/objc2/hoc/HOC_cbits/Ivars.m Tue Dec 9 13:12:04 2008
@@ -59,7 +59,6 @@
list->ivar_list[i].ivar_offset = offset;
}
-#warning TODO - proofread buildIndexedIvarList
struct objc_ivar_list * buildIndexedIvarList(
struct hoc_ivar_list *list,
int start_offset,
Modified: branches/objc2/hoc/HOC_cbits/NewClass.h
==============================================================================
--- branches/objc2/hoc/HOC_cbits/NewClass.h (original)
+++ branches/objc2/hoc/HOC_cbits/NewClass.h Tue Dec 9 13:12:04 2008
@@ -7,7 +7,7 @@
struct hoc_ivar_list;
struct hoc_method_list;
-void newClass(struct objc_class * super_class,
+void newClass(Class super_class,
const char * name, /* never
deallocate this */
struct hoc_ivar_list *ivars,
struct hoc_method_list *methods,
|
|
From: <cod...@go...> - 2008-12-09 21:24:52
|
Author: jam...@us...
Date: Tue Dec 9 12:29:11 2008
New Revision: 368
Modified:
trunk/hoc/HOC/HOC.hs
trunk/hoc/HOC/HOC/Class.hs
trunk/hoc/HOC/HOC/DeclareClass.hs
trunk/hoc/HOC/HOC/NewlyAllocated.hs
trunk/hoc/HOC/HOC/Super.hs
trunk/hoc/Tests/TestFoundation.hs
Log:
Fixed super calls to chain properly (Issue 9) and added tests for the fix.
The short story:
- Added a typeclass "StaticClassAndObject" with a
method "staticClassForObject", and added an instance declaration to the
output of declareClass.
- Added a field to the SuperTarget and NewSuper constructors to carry the
targeted superclass, and changed the objc_super marshalling stuff in
Super.hs to make use of those fields.
Modified: trunk/hoc/HOC/HOC.hs
==============================================================================
--- trunk/hoc/HOC/HOC.hs (original)
+++ trunk/hoc/HOC/HOC.hs Tue Dec 9 12:29:11 2008
@@ -5,6 +5,9 @@
Object(..),
Class,
ClassAndObject,
+ StaticClassAndObject,
+ staticClassForObject,
+ staticSuperclassForObject,
( # ), ( #. ),
withExportedArray,
castObject,
@@ -36,6 +39,7 @@
SuperClass,
SuperTarget,
super,
+ castSuper,
CEnum(..),
declareCEnum,
Modified: trunk/hoc/HOC/HOC/Class.hs
==============================================================================
--- trunk/hoc/HOC/HOC/Class.hs (original)
+++ trunk/hoc/HOC/HOC/Class.hs Tue Dec 9 12:29:11 2008
@@ -35,3 +35,14 @@
class (Object a, Object b) => ClassAndObject a b | a -> b, b -> a
instance ClassAndObject (Class a) (ID a)
+
+class ClassAndObject a b => StaticClassAndObject a b
+ where
+ -- _staticClassForObject must not touch its parameter:
+ -- its value should only depend on the type of the parameter.
+ _staticClassForObject :: b -> a
+
+-- make an export-safe version; don't want people making new
+-- implementations, but they should be allowed to use the info.
+staticClassForObject :: StaticClassAndObject a b => b -> a
+staticClassForObject = _staticClassForObject
\ No newline at end of file
Modified: trunk/hoc/HOC/HOC/DeclareClass.hs
==============================================================================
--- trunk/hoc/HOC/HOC/DeclareClass.hs (original)
+++ trunk/hoc/HOC/HOC/DeclareClass.hs Tue Dec 9 12:29:11 2008
@@ -45,7 +45,12 @@
valD (return $ VarP (mkName superName)) (normalB $ stringE super)
[],
-- instance SuperClass (name ()) (super ())
- instanceD (cxt []) (conT ''SuperClass `appT` clsType `appT`
superType) []
+ instanceD (cxt []) (conT ''SuperClass `appT` clsType `appT`
superType) [],
+
+ -- instance StaticClassAndObject (name ())
+ -- where staticClassForObject _ = classObject
+ instanceD (cxt []) (conT ''StaticClassAndObject `appT` metaClsType
`appT` clsType)
+ [funD '_staticClassForObject [clause [wildP] (normalB $ varE
(mkName classObjectName)) []]]
]
where
phantomName = name ++ "_"
@@ -56,5 +61,6 @@
classObjectName = "_" ++ name
superName = "super_" ++ name
+ metaClsType = conT (mkName metaClassName) `appT` [t| () |]
clsType = conT (mkName name) `appT` [t| () |]
superType = conT (mkName super) `appT` [t| () |]
Modified: trunk/hoc/HOC/HOC/NewlyAllocated.hs
==============================================================================
--- trunk/hoc/HOC/HOC/NewlyAllocated.hs (original)
+++ trunk/hoc/HOC/HOC/NewlyAllocated.hs Tue Dec 9 12:29:11 2008
@@ -14,6 +14,8 @@
import HOC.Base ( ObjCObject )
import HOC.Arguments ( ObjCArgument(..) )
+import HOC.Class
+import HOC.ID
import HOC.MessageTarget( Object(..), MessageTarget(..) )
import HOC.MsgSend
import HOC.Super
@@ -24,15 +26,16 @@
data NewlyAllocated a
= NewlyAllocated (Ptr ObjCObject)
- | NewSuper (Ptr ObjCObject)
+ | NewSuper (Ptr ObjCObject) (Class ())
instance ObjCArgument (NewlyAllocated a) (Ptr ObjCObject) where
withExportedArgument (NewlyAllocated p) action = action p
- withExportedArgument (NewSuper p) action =
- withExportedSuper p action
+ withExportedArgument (NewSuper p cls) action =
+ withExportedArgument cls $ \cls ->
+ withExportedSuper p cls action
exportArgument (NewlyAllocated p) = return p
- exportArgument (NewSuper p) = fail "HOC.NewlyAllocated.NewSuper:
exportArgument"
+ exportArgument (NewSuper p cls) = fail "HOC.NewlyAllocated.NewSuper:
exportArgument"
importArgument p = return (NewlyAllocated p)
@@ -45,13 +48,16 @@
instance MessageTarget (NewlyAllocated a) where
isNil (NewlyAllocated p) = p == nullPtr
- isNil (NewSuper p) = p == nullPtr
+ isNil (NewSuper p cls) = (p == nullPtr) || isNil cls
sendMessageWithRetval (NewlyAllocated _) = objSendMessageWithRetval
- sendMessageWithRetval (NewSuper _) = superSendMessageWithRetval
+ sendMessageWithRetval (NewSuper _ _) = superSendMessageWithRetval
sendMessageWithoutRetval (NewlyAllocated _) =
objSendMessageWithoutRetval
- sendMessageWithoutRetval (NewSuper _) = superSendMessageWithoutRetval
+ sendMessageWithoutRetval (NewSuper _ _) = superSendMessageWithoutRetval
-instance SuperClass sub super
- => Super (NewlyAllocated sub) (NewlyAllocated super) where
- super (NewlyAllocated x) = NewSuper x
+instance (SuperClass sub (ID super), StaticClassAndObject (Class super)
(ID super))
+ => Super (NewlyAllocated sub) (NewlyAllocated (ID super)) where
+ super na@(NewlyAllocated x) = NewSuper x (castObject superClass)
+ where superClass = staticClassForObject (asSuper na)
+ asSuper :: SuperClass sub super => NewlyAllocated sub ->
super
+ asSuper _ = error "staticClassForObject must not touch its
parameter"
Modified: trunk/hoc/HOC/HOC/Super.hs
==============================================================================
--- trunk/hoc/HOC/HOC/Super.hs (original)
+++ trunk/hoc/HOC/HOC/Super.hs Tue Dec 9 12:29:11 2008
@@ -1,11 +1,14 @@
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
- UndecidableInstances, FlexibleInstances #-}
+ UndecidableInstances, FlexibleInstances,
+ FlexibleContexts #-}
module HOC.Super(
- SuperClass, SuperTarget, Super(super), withExportedSuper
+ SuperClass, SuperTarget, Super(super), withExportedSuper,
+ staticSuperclassForObject, castSuper
) where
import HOC.Base
import HOC.Arguments
+import HOC.Class
import HOC.ID
import HOC.MsgSend
import HOC.MessageTarget
@@ -23,7 +26,7 @@
-- super, which is sufficient to define a class hierarchy.
class SuperClass sub super | sub -> super
-data SuperTarget a = SuperTarget a
+data SuperTarget a = SuperTarget a (Class ())
class Super sub super | sub -> super where
super :: sub -> super
@@ -33,32 +36,39 @@
pokeSuper objcSuper obj cls
= pokeByteOff objcSuper 0 obj >> pokeByteOff objcSuper (sizeOf obj) cls
-withExportedSuper p action =
- getSuperClassForObject p >>= \cls ->
+withExportedSuper p cls action =
allocaBytes (sizeOf p + sizeOf cls) $ \sptr ->
pokeSuper sptr p cls >> action sptr
instance MessageTarget a
=> ObjCArgument (SuperTarget a) (Ptr ObjCObject) where
- withExportedArgument (SuperTarget obj) action =
+ withExportedArgument (SuperTarget obj cls) action =
+ withExportedArgument cls $ \cls ->
withExportedArgument obj $ \p ->
- withExportedSuper p action
+ withExportedSuper p cls action
exportArgument _ = fail "HOC.Super: exportArgument"
importArgument _ = fail "HOC.Super: importArgument"
objCTypeString _ = "@" -- well, close enough.
-instance (Object (ID sub), Object super, SuperClass (ID sub) super)
- => Super (ID sub) (SuperTarget super) where
- super obj = SuperTarget (fromID $ toID obj)
+castSuper :: SuperClass (ID sub) (ID super) => ID sub -> ID super
+castSuper = castObject
-getSuperClassForObject obj = do cls <- peekByteOff obj 0 :: IO (Ptr (Ptr
()))
- peekElemOff cls 1
+staticSuperclassForObject ::
+ ( SuperClass (ID sub) (ID super)
+ , StaticClassAndObject (Class super) (ID super)
+ ) => ID sub -> Class super
+staticSuperclassForObject = staticClassForObject . castSuper
+
+instance (Object (ID sub), Object (ID super), SuperClass (ID sub) (ID
super),
+ StaticClassAndObject (Class super) (ID super))
+ => Super (ID sub) (SuperTarget (ID super)) where
+ super obj = SuperTarget (fromID $ toID obj) (castObject
(staticSuperclassForObject obj))
instance MessageTarget a => MessageTarget (SuperTarget a) where
- isNil (SuperTarget x) = isNil x
+ isNil (SuperTarget x cls) = isNil x || isNil cls
sendMessageWithRetval _ = superSendMessageWithRetval
sendMessageWithoutRetval _ = superSendMessageWithoutRetval
Modified: trunk/hoc/Tests/TestFoundation.hs
==============================================================================
--- trunk/hoc/Tests/TestFoundation.hs (original)
+++ trunk/hoc/Tests/TestFoundation.hs Tue Dec 9 12:29:11 2008
@@ -90,6 +90,30 @@
nil
>>= raise
+$(declareSelector "countInvocations:upto:" [t| Int -> Int -> IO Int |])
+
+$(declareClass "HaskellObjectCountingInvocations" "NSObject")
+$(exportClass "HaskellObjectCountingInvocations" "hoci_1_" [
+ InstanceMethod 'countInvocationsUpto
+ ])
+
+instance Has_countInvocationsUpto (HaskellObjectCountingInvocations a)
+
+hoci_1_countInvocationsUpto start limit self = return (start + 1)
+
+$(declareClass "HaskellObjectUsingSuper" "HaskellObjectCountingInvocations")
+$(exportClass "HaskellObjectUsingSuper" "hoci_2_" [
+ InstanceMethod 'countInvocationsUpto
+ ])
+
+hoci_2_countInvocationsUpto start limit self
+ | start >= limit = return start
+ | otherwise = super self # countInvocationsUpto (start + 1)
limit
+
+$(declareClass "HaskellSubclassOfObjectUsingSuper" "HaskellObjectUsingSuper")
+
+$(exportClass "HaskellSubclassOfObjectUsingSuper" "noMembers_" [])
+
tests = test [
"NSNumber" ~: test [
"alloc-initWithInt-intValue" ~: (assertNoLeaks $ do
@@ -172,7 +196,10 @@
initializeClass_HaskellObjectWithOutlet
initializeClass_HaskellObjectWithDescription
initializeClass_HaskellObjectWithIVar
- initializeClass_ExceptionThrower,
+ initializeClass_ExceptionThrower
+ initializeClass_HaskellObjectCountingInvocations
+ initializeClass_HaskellObjectUsingSuper
+ initializeClass_HaskellSubclassOfObjectUsingSuper,
"HaskellObjectWithOutlet" ~: test [
"alloc-init" ~: (assertNoLeaks $ do
@@ -235,11 +262,30 @@
result @?= expected
)
],
- "Super" ~: (assertNoLeaks $ do
- hobj <- _HaskellObjectWithDescription # alloc >>= init
- str <- hobj # description
- fromNSString str @?= "<HaskellObjectWithDescription: TEST>"
- ),
+ "Super" ~: test [
+ "description" ~: (assertNoLeaks $ do
+ hobj <- _HaskellObjectWithDescription # alloc >>= init
+ str <- hobj # description
+ fromNSString str @?= "<HaskellObjectWithDescription: TEST>"
+ ),
+ "chaining" ~: test [
+ "base" ~: (assertNoLeaks $ do
+ hobj <- _HaskellObjectCountingInvocations # alloc >>=
init
+ count <- hobj # countInvocationsUpto 0 100
+ count @?= 1
+ ),
+ "subclass" ~: (assertNoLeaks $ do
+ hobj <- _HaskellObjectUsingSuper # alloc >>= init
+ count <- hobj # countInvocationsUpto 0 100
+ count @?= 2
+ ),
+ "subsubclass" ~: (assertNoLeaks $ do
+ hobj <- _HaskellSubclassOfObjectUsingSuper # alloc >>=
init
+ count <- hobj # countInvocationsUpto 0 100
+ count @?= 2
+ )
+ ]
+ ],
"structs" ~: test [
"pointArg" ~: (do
let point = NSPoint 6.42 7.42
|
|
From: <cod...@go...> - 2008-12-08 21:04:50
|
Author: jam...@us...
Date: Mon Dec 8 13:03:47 2008
New Revision: 367
Modified:
branches/objc2/hoc/HOC_cbits/Class.h
branches/objc2/hoc/HOC_cbits/Class.m
branches/objc2/hoc/HOC_cbits/NewClass.m
Log:
Cleaned up recent objective C 2.0-related changes to newClass.
Modified: branches/objc2/hoc/HOC_cbits/Class.h
==============================================================================
--- branches/objc2/hoc/HOC_cbits/Class.h (original)
+++ branches/objc2/hoc/HOC_cbits/Class.h Mon Dec 8 13:03:47 2008
@@ -1,4 +1,9 @@
#include <objc/objc.h>
id getClassByName(const char* name);
+
+Class getSuperclassForClass(Class class);
+Class getRootClassForClass(Class super_class);
+
+Class getClassForObject(id self);
Class getSuperClassForObject(id self);
Modified: branches/objc2/hoc/HOC_cbits/Class.m
==============================================================================
--- branches/objc2/hoc/HOC_cbits/Class.m (original)
+++ branches/objc2/hoc/HOC_cbits/Class.m Mon Dec 8 13:03:47 2008
@@ -14,6 +14,42 @@
#endif
}
+Class getSuperclassForClass(Class class)
+{
+#ifdef GNUSTEP
+ if(CLS_ISRESOLV(class))
+ return class->super_class;
+ else
+ return getClassByName((const char*) class->super_class);
+
+#elif defined(__OBJC2__)
+ return class_getSuperclass(class);
+#else
+ return class->super_class;
+#endif
+}
+
+Class getRootClassForClass(Class super_class)
+{
+ Class root_class;
+
+ for(root_class = super_class;
+ getSuperclassForClass(root_class) != nil;
+ root_class = getSuperclassForClass(root_class))
+ ;
+
+ return root_class;
+}
+
+Class getClassForObject(id object)
+{
+#ifdef __OBJC2__
+ return object_getClass(object);
+#else
+ return object->isa;
+#endif
+}
+
Class getSuperClassForObject(id self)
{
#ifdef GNUSTEP
Modified: branches/objc2/hoc/HOC_cbits/NewClass.m
==============================================================================
--- branches/objc2/hoc/HOC_cbits/NewClass.m (original)
+++ branches/objc2/hoc/HOC_cbits/NewClass.m Mon Dec 8 13:03:47 2008
@@ -12,137 +12,132 @@
#define CLS_META _CLS_META
#endif
-static struct objc_class * getSuper(struct objc_class *class)
+static Class allocateClassPair(Class super_class, const char * name) {
+#ifdef __OBJC2__
+ return objc_allocateClassPair(super_class, name, 0);
+#else
+ Class new_class = calloc( 2, sizeof(struct objc_class) );
+ Class meta_class = &new_class[1];
+ Class root_class = getRootClassForClass(super_class);
+
+ new_class->isa = meta_class;
+ new_class->info = CLS_CLASS;
+ meta_class->info = CLS_META;
+
+ new_class->name = name;
+ meta_class->name = name;
+
+# ifdef GNUSTEP
+ new_class->super_class = (void*)(super_class->name);
+ meta_class->super_class = (void*)(super_class->isa->name);
+# else
+ new_class->super_class = super_class;
+ meta_class->super_class = super_class->isa;
+ meta_class->isa = (void *)root_class->isa;
+# endif
+
+ return new_class;
+#endif
+}
+
+static void registerClassPair(Class new_class) {
+#ifdef GNUSTEP
+ Module_t module = calloc(1, sizeof(Module));
+ Symtab_t symtab = calloc(1, sizeof(Symtab) + sizeof(void*) /* two defs
pointers */);
+ extern void __objc_exec_class (Module_t module);
+ extern void __objc_resolve_class_links ();
+
+ module->version = 8;
+ module->size = sizeof(Module);
+ module->name = strdup(name);
+ module->symtab = symtab;
+ symtab->cls_def_cnt = 1;
+ symtab->defs[0] = new_class;
+ symtab->defs[1] = NULL;
+
+ __objc_exec_class (module);
+ __objc_resolve_class_links();
+#elif defined(__OBJC2__)
+ objc_registerClassPair(new_class);
+#else
+ objc_addClass( new_class );
+#endif
+}
+
+static void addIvarsToClass(Class new_class, struct hoc_ivar_list *ivars)
+{
+#ifdef __OBJC2__
+ int i;
+
+ for (i = 0; i < ivars->ivar_count; i++)
+ {
+ struct hoc_ivar *ivar = &ivars->ivar_list[i];
+ class_addIvar(new_class, ivar->ivar_name,
+ ivar->ivar_size, ivar->ivar_alignment, ivar->ivar_types);
+ }
+#else
+ Class super_class = getSuperclassForClass(new_class);
+
+ int instance_size;
+ new_class->ivars = buildIndexedIvarList(
+ ivars,
+ super_class->instance_size,
+ &instance_size);
+
+ new_class->instance_size = super_class->instance_size + instance_size;
+#endif
+}
+
+static void addMethodsToClass(Class new_class, struct hoc_method_list
*methods)
{
#ifdef GNUSTEP
- if(CLS_ISRESOLV(class))
- return class->super_class;
- else
- return getClassByName((const char*) class->super_class);
-
+ class_add_method_list(new_class, convertMethodList(methods));
#elif defined(__OBJC2__)
- return class_getSuperclass(class);
+ int i;
+ for (i = 0; i < methods->method_count; i++)
+ {
+ struct hoc_method * m = &methods->method_list[i];
+ class_addMethod(new_class, m->method_name, m->method_imp,
m->method_types);
+ }
#else
- return class->super_class;
+ new_class->methodLists = calloc( 1, sizeof(struct objc_method_list *)
);
+ new_class->methodLists[0] = (struct objc_method_list*) -1;
+
+ class_addMethods(new_class, convertMethodList(methods));
#endif
}
-void newClass(struct objc_class * super_class,
+void newClass(Class super_class,
const char * name,
struct hoc_ivar_list *ivars,
struct hoc_method_list *methods,
struct hoc_method_list *class_methods)
{
- struct objc_class * meta_class;
- struct objc_class * new_class;
+ Class meta_class;
+ Class new_class;
assert(objc_lookUpClass(name) == nil);
/* Allocate the class and metaclass */
-#ifdef __OBJC2__
- new_class = objc_allocateClassPair(super_class, name, 0);
- meta_class = object_getClass(new_class);
-#else
- new_class = calloc( 2, sizeof(struct objc_class) );
- meta_class = &new_class[1];
-
- new_class->isa = meta_class;
- new_class->info = CLS_CLASS;
- meta_class->info = CLS_META;
-
- new_class->name = name;
- meta_class->name = name;
-#endif
+ new_class = allocateClassPair(super_class, name);
+ meta_class = getClassForObject(new_class);
/* Add instance variables to the class */
-#ifdef __OBJC2__
- {
- int i;
-
- for (i = 0; i < ivars->ivar_count; i++)
- {
- struct hoc_ivar *ivar = &ivars->ivar_list[i];
- class_addIvar(new_class, ivar->ivar_name,
- ivar->ivar_size, ivar->ivar_alignment, ivar->ivar_types);
- }
-
- }
-#else
- {
- int instance_size;
- new_class->ivars = buildIndexedIvarList(
- ivars,
- super_class->instance_size,
- &instance_size);
-
- new_class->instance_size = super_class->instance_size +
instance_size;
- }
-#endif
+ addIvarsToClass(new_class, ivars);
/* Add methods and class methods */
-#ifdef GNUSTEP
- new_class->super_class = (void*)(super_class->name);
- meta_class->super_class = (void*)(super_class->isa->name);
-
- {
- Module_t module = calloc(1, sizeof(Module));
- Symtab_t symtab = calloc(1, sizeof(Symtab) + sizeof(void*) /* two
defs pointers */);
- extern void __objc_exec_class (Module_t module);
- extern void __objc_resolve_class_links ();
-
- module->version = 8;
- module->size = sizeof(Module);
- module->name = strdup(name);
- module->symtab = symtab;
- symtab->cls_def_cnt = 1;
- symtab->defs[0] = new_class;
- symtab->defs[1] = NULL;
-
- __objc_exec_class (module);
- __objc_resolve_class_links();
- }
+ /* I don't know whether order actually matters here in the non-objc2
cases,
+ so I'm leaving it as it was. */
+#ifdef __OBJC2__
+ addMethodsToClass(new_class, methods);
+ addMethodsToClass(meta_class, class_methods);
- class_add_method_list(new_class, convertMethodList(methods));
- class_add_method_list(meta_class, convertMethodList(class_methods));
-#elif defined(__OBJC2__)
- {
- int i;
- for (i = 0; i < methods->method_count; i++)
- {
- struct hoc_method * m = &methods->method_list[i];
- class_addMethod(new_class, m->method_name, m->method_imp,
m->method_types);
- }
-
- for (i = 0; i < class_methods->method_count; i++)
- {
- struct hoc_method * m = &class_methods->method_list[i];
- class_addMethod(meta_class, m->method_name, m->method_imp,
m->method_types);
- }
-
- objc_registerClassPair(new_class);
- }
+ registerClassPair(new_class);
#else
- {
- struct objc_class * root_class;
- for(root_class = super_class;
- root_class->super_class != nil;
- root_class = getSuper(root_class))
- ;
-
- new_class->methodLists = calloc( 1, sizeof(struct objc_method_list *)
);
- meta_class->methodLists = calloc( 1, sizeof(struct objc_method_list
*) );
- new_class->methodLists[0] = (struct objc_method_list*) -1;
- meta_class->methodLists[0] = (struct objc_method_list*) -1;
-
- new_class->super_class = super_class;
- meta_class->super_class = super_class->isa;
- meta_class->isa = (void *)root_class->isa;
-
- objc_addClass( new_class );
-
- class_addMethods(new_class, convertMethodList(methods));
- class_addMethods(meta_class, convertMethodList(class_methods));
- }
+ registerClassPair(new_class);
+
+ addMethodsToClass(new_class, methods);
+ addMethodsToClass(meta_class, class_methods);
#endif
}
|